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 try (ObjectInputStream objectInputStream = new ObjectInputStream(
052 inputStream)) {
053
054 IndexCommitMetaInfo indexCommitMetaInfo = null;
055
056 try {
057 indexCommitMetaInfo =
058 (IndexCommitMetaInfo)objectInputStream.readObject();
059 }
060 catch (ClassNotFoundException cnfe) {
061 throw new IOException(cnfe);
062 }
063
064 if (_log.isDebugEnabled()) {
065 _log.debug("Deserializing " + indexCommitMetaInfo);
066 }
067
068 if (indexCommitMetaInfo.isEmpty()) {
069 return;
070 }
071
072 List<Segment> segments = indexCommitMetaInfo.getSegments();
073
074 for (Segment segment : segments) {
075 if (_log.isDebugEnabled()) {
076 _log.debug("Deserializing segment " + segment);
077 }
078
079 _deserializeSegment(
080 objectInputStream, segment.getFileSize(),
081 directory.createOutput(segment.getFileName()));
082 }
083
084 _writeSegmentsGen(directory, indexCommitMetaInfo.getGeneration());
085 }
086 }
087
088 public static void serializeIndex(
089 IndexCommit indexCommit, OutputStream outputStream)
090 throws IOException {
091
092 if (PropsValues.INDEX_DUMP_COMPRESSION_ENABLED) {
093 outputStream = new GZIPOutputStream(outputStream);
094 }
095
096 ObjectOutputStream objectOputStream = new ObjectOutputStream(
097 outputStream);
098
099 IndexCommitMetaInfo indexCommitMetaInfo = new IndexCommitMetaInfo(
100 indexCommit);
101
102 if (_log.isDebugEnabled()) {
103 _log.debug("Serializing " + indexCommitMetaInfo);
104 }
105
106 objectOputStream.writeObject(indexCommitMetaInfo);
107
108 List<Segment> segments = indexCommitMetaInfo.getSegments();
109
110 Directory directory = indexCommit.getDirectory();
111
112 for (Segment segment : segments) {
113 if (_log.isDebugEnabled()) {
114 _log.debug("Serializing segment " + segment);
115 }
116
117 _serializeSegment(
118 directory.openInput(segment.getFileName()),
119 segment.getFileSize(), objectOputStream);
120 }
121
122 objectOputStream.flush();
123
124 if (PropsValues.INDEX_DUMP_COMPRESSION_ENABLED) {
125 GZIPOutputStream gZipOutputStream = (GZIPOutputStream)outputStream;
126
127 gZipOutputStream.finish();
128 }
129 }
130
131 private static void _deserializeSegment(
132 InputStream inputStream, long length, IndexOutput indexOutput)
133 throws IOException {
134
135 try {
136 indexOutput.setLength(length);
137
138 byte[] buffer = new byte[_BUFFER_SIZE];
139
140 long received = 0;
141
142 while (received < length) {
143 int bufferSize = _BUFFER_SIZE;
144
145 if ((received + _BUFFER_SIZE) > length) {
146 bufferSize = (int)(length - received);
147 }
148
149 int actualSize = inputStream.read(buffer, 0, bufferSize);
150
151 indexOutput.writeBytes(buffer, actualSize);
152
153 received += actualSize;
154 }
155 }
156 finally {
157 indexOutput.close();
158 }
159 }
160
161 private static void _serializeSegment(
162 IndexInput indexInput, long length, OutputStream outputStream)
163 throws IOException {
164
165 byte[] buffer = new byte[_BUFFER_SIZE];
166
167 int count = (int)(length / _BUFFER_SIZE);
168 int tail = (int)(length - count * _BUFFER_SIZE);
169
170 try {
171 for (int i = 0; i < count; i++) {
172 indexInput.readBytes(buffer, 0, _BUFFER_SIZE);
173 outputStream.write(buffer);
174 }
175
176 indexInput.readBytes(buffer, 0, tail);
177 outputStream.write(buffer, 0, tail);
178 }
179 finally {
180 indexInput.close();
181 }
182 }
183
184 private static void _writeSegmentsGen(Directory directory, long generation)
185 throws IOException {
186
187 if (_log.isDebugEnabled()) {
188 _log.debug(
189 "Writing " + _SEGMENTS_GEN_FILE_NAME + " with generation " +
190 generation);
191 }
192
193 try (IndexOutput indexOutput = directory.createOutput(
194 _SEGMENTS_GEN_FILE_NAME)) {
195
196 indexOutput.writeInt(SegmentInfos.FORMAT_LOCKLESS);
197 indexOutput.writeLong(generation);
198 indexOutput.writeLong(generation);
199 }
200 }
201
202 private static final int _BUFFER_SIZE = 8192;
203
204 private static final String _SEGMENTS_GEN_FILE_NAME = "segments.gen";
205
206 private static Log _log = LogFactoryUtil.getLog(
207 IndexCommitSerializationUtil.class);
208
209 }