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