001
014
015 package com.liferay.portal.search.lucene.dump;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.search.lucene.dump.IndexCommitMetaInfo.Segment;
020 import com.liferay.portal.util.PropsValues;
021
022 import java.io.IOException;
023 import java.io.InputStream;
024 import java.io.ObjectInputStream;
025 import java.io.ObjectOutputStream;
026 import java.io.OutputStream;
027
028 import java.util.List;
029 import java.util.zip.GZIPInputStream;
030 import java.util.zip.GZIPOutputStream;
031
032 import org.apache.lucene.index.IndexCommit;
033 import org.apache.lucene.index.SegmentInfos;
034 import org.apache.lucene.store.Directory;
035 import org.apache.lucene.store.IndexInput;
036 import org.apache.lucene.store.IndexOutput;
037
038
041 public class IndexCommitSerializationUtil {
042
043 public static void deserializeIndex(
044 InputStream inputStream, Directory directory)
045 throws IOException {
046
047 if (PropsValues.INDEX_DUMP_COMPRESSION_ENABLED) {
048 inputStream = new GZIPInputStream(inputStream);
049 }
050
051 ObjectInputStream objectInputStream = null;
052
053 try {
054 objectInputStream = new ObjectInputStream(inputStream);
055
056 IndexCommitMetaInfo indexCommitMetaInfo = null;
057
058 try {
059 indexCommitMetaInfo =
060 (IndexCommitMetaInfo)objectInputStream.readObject();
061 }
062 catch (ClassNotFoundException cnfe) {
063 throw new IOException(cnfe.getMessage());
064 }
065
066 if (_log.isDebugEnabled()) {
067 _log.debug("Deserializing " + indexCommitMetaInfo);
068 }
069
070 if (indexCommitMetaInfo.isEmpty()) {
071 return;
072 }
073
074 List<Segment> segments = indexCommitMetaInfo.getSegments();
075
076 for (Segment segment : segments) {
077 if (_log.isDebugEnabled()) {
078 _log.debug("Deserializing segment " + segment);
079 }
080
081 deserializeSegment(
082 objectInputStream, segment.getFileSize(),
083 directory.createOutput(segment.getFileName()));
084 }
085
086 writeSegmentsGen(
087 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(
193 Directory directory, long generation)
194 throws IOException {
195
196 if (_log.isDebugEnabled()) {
197 _log.debug(
198 "Writing " + _SEGMENTS_GEN_FILE_NAME + " with generation " +
199 generation);
200 }
201
202 IndexOutput indexOutput = directory.createOutput(
203 _SEGMENTS_GEN_FILE_NAME);
204
205 try {
206 indexOutput.writeInt(SegmentInfos.FORMAT_LOCKLESS);
207 indexOutput.writeLong(generation);
208 indexOutput.writeLong(generation);
209 }
210 finally {
211 indexOutput.close();
212 }
213 }
214
215 private static final int _BUFFER_SIZE = 8192;
216
217 private static final String _SEGMENTS_GEN_FILE_NAME = "segments.gen";
218
219 private static Log _log = LogFactoryUtil.getLog(
220 IndexCommitSerializationUtil.class);
221
222 }