001
014
015 package com.liferay.portal.search.lucene.dump;
016
017 import com.liferay.portal.kernel.io.ProtectedObjectInputStream;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.search.lucene.dump.IndexCommitMetaInfo.Segment;
021 import com.liferay.portal.util.PropsValues;
022
023 import java.io.IOException;
024 import java.io.InputStream;
025 import java.io.ObjectInputStream;
026 import java.io.ObjectOutputStream;
027 import java.io.OutputStream;
028
029 import java.util.List;
030 import java.util.zip.GZIPInputStream;
031 import java.util.zip.GZIPOutputStream;
032
033 import org.apache.lucene.index.IndexCommit;
034 import org.apache.lucene.index.SegmentInfos;
035 import org.apache.lucene.store.Directory;
036 import org.apache.lucene.store.IndexInput;
037 import org.apache.lucene.store.IndexOutput;
038
039
042 public class IndexCommitSerializationUtil {
043
044 public static void deserializeIndex(
045 InputStream inputStream, Directory directory)
046 throws IOException {
047
048 if (PropsValues.INDEX_DUMP_COMPRESSION_ENABLED) {
049 inputStream = new GZIPInputStream(inputStream);
050 }
051
052 ObjectInputStream objectInputStream = null;
053
054 try {
055 objectInputStream = new ProtectedObjectInputStream(inputStream);
056
057 IndexCommitMetaInfo indexCommitMetaInfo = null;
058
059 try {
060 indexCommitMetaInfo =
061 (IndexCommitMetaInfo)objectInputStream.readObject();
062 }
063 catch (ClassNotFoundException cnfe) {
064 throw new IOException(cnfe.getMessage());
065 }
066
067 if (_log.isDebugEnabled()) {
068 _log.debug("Deserializing " + indexCommitMetaInfo);
069 }
070
071 if (indexCommitMetaInfo.isEmpty()) {
072 return;
073 }
074
075 List<Segment> segments = indexCommitMetaInfo.getSegments();
076
077 for (Segment segment : segments) {
078 if (_log.isDebugEnabled()) {
079 _log.debug("Deserializing segment " + segment);
080 }
081
082 _deserializeSegment(
083 objectInputStream, segment.getFileSize(),
084 directory.createOutput(segment.getFileName()));
085 }
086
087 _writeSegmentsGen(directory, indexCommitMetaInfo.getGeneration());
088 }
089 finally {
090 if (objectInputStream != null) {
091 objectInputStream.close();
092 }
093 }
094 }
095
096 public static void serializeIndex(
097 IndexCommit indexCommit, OutputStream outputStream)
098 throws IOException {
099
100 if (PropsValues.INDEX_DUMP_COMPRESSION_ENABLED) {
101 outputStream = new GZIPOutputStream(outputStream);
102 }
103
104 ObjectOutputStream objectOputStream = new ObjectOutputStream(
105 outputStream);
106
107 IndexCommitMetaInfo indexCommitMetaInfo = new IndexCommitMetaInfo(
108 indexCommit);
109
110 if (_log.isDebugEnabled()) {
111 _log.debug("Serializing " + indexCommitMetaInfo);
112 }
113
114 objectOputStream.writeObject(indexCommitMetaInfo);
115
116 List<Segment> segments = indexCommitMetaInfo.getSegments();
117
118 Directory directory = indexCommit.getDirectory();
119
120 for (Segment segment : segments) {
121 if (_log.isDebugEnabled()) {
122 _log.debug("Serializing segment " + segment);
123 }
124
125 _serializeSegment(
126 directory.openInput(segment.getFileName()),
127 segment.getFileSize(), objectOputStream);
128 }
129
130 objectOputStream.flush();
131
132 if (PropsValues.INDEX_DUMP_COMPRESSION_ENABLED) {
133 GZIPOutputStream gZipOutputStream = (GZIPOutputStream)outputStream;
134
135 gZipOutputStream.finish();
136 }
137 }
138
139 private static void _deserializeSegment(
140 InputStream inputStream, long length, IndexOutput indexOutput)
141 throws IOException {
142
143 try {
144 indexOutput.setLength(length);
145
146 byte[] buffer = new byte[_BUFFER_SIZE];
147
148 long received = 0;
149
150 while (received < length) {
151 int bufferSize = _BUFFER_SIZE;
152
153 if ((received + _BUFFER_SIZE) > length) {
154 bufferSize = (int)(length - received);
155 }
156
157 int actualSize = inputStream.read(buffer, 0, bufferSize);
158
159 indexOutput.writeBytes(buffer, actualSize);
160
161 received += actualSize;
162 }
163 }
164 finally {
165 indexOutput.close();
166 }
167 }
168
169 private static void _serializeSegment(
170 IndexInput indexInput, long length, OutputStream outputStream)
171 throws IOException {
172
173 byte[] buffer = new byte[_BUFFER_SIZE];
174
175 int count = (int)(length / _BUFFER_SIZE);
176 int tail = (int)(length - count * _BUFFER_SIZE);
177
178 try {
179 for (int i = 0; i < count; i++) {
180 indexInput.readBytes(buffer, 0, _BUFFER_SIZE);
181 outputStream.write(buffer);
182 }
183
184 indexInput.readBytes(buffer, 0, tail);
185 outputStream.write(buffer, 0, tail);
186 }
187 finally {
188 indexInput.close();
189 }
190 }
191
192 private static void _writeSegmentsGen(Directory directory, long generation)
193 throws IOException {
194
195 if (_log.isDebugEnabled()) {
196 _log.debug(
197 "Writing " + _SEGMENTS_GEN_FILE_NAME + " with generation " +
198 generation);
199 }
200
201 IndexOutput indexOutput = directory.createOutput(
202 _SEGMENTS_GEN_FILE_NAME);
203
204 try {
205 indexOutput.writeInt(SegmentInfos.FORMAT_LOCKLESS);
206 indexOutput.writeLong(generation);
207 indexOutput.writeLong(generation);
208 }
209 finally {
210 indexOutput.close();
211 }
212 }
213
214 private static final int _BUFFER_SIZE = 8192;
215
216 private static final String _SEGMENTS_GEN_FILE_NAME = "segments.gen";
217
218 private static Log _log = LogFactoryUtil.getLog(
219 IndexCommitSerializationUtil.class);
220
221 }