19 using System.Collections.Generic;
24 namespace Lucene.Net.Index
50 private sealed
class FileEntry
53 internal System.String file;
56 internal long directoryOffset;
59 internal long dataOffset;
64 private readonly String fileName;
65 private readonly HashSet<string> ids;
66 private readonly LinkedList<FileEntry> entries;
67 private bool merged =
false;
81 throw new ArgumentNullException(
"dir");
83 throw new ArgumentNullException(
"name");
84 this.checkAbort = checkAbort;
87 ids =
new HashSet<string>();
88 entries =
new LinkedList<FileEntry>();
94 get {
return directory; }
100 get {
return fileName; }
112 public void AddFile(String file)
115 throw new InvalidOperationException(
"Can't add extensions after merge has been called");
118 throw new ArgumentNullException(
"file");
126 throw new ArgumentException(
"File " + file +
" already added");
129 var entry =
new FileEntry {file = file};
130 entries.AddLast(entry);
133 [Obsolete(
"Use Dispose() instead")]
147 public void Dispose()
153 throw new SystemException(
"Merge already performed");
155 if ((entries.Count == 0))
156 throw new SystemException(
"No entries to merge have been defined");
164 os = directory.CreateOutput(fileName);
167 os.WriteVInt(entries.Count);
173 foreach (FileEntry fe
in entries)
175 fe.directoryOffset = os.FilePointer;
177 os.WriteString(fe.file);
178 totalSize += directory.FileLength(fe.file);
187 long finalLength = totalSize + os.FilePointer;
188 os.SetLength(finalLength);
192 var buffer =
new byte[16384];
193 foreach (FileEntry fe
in entries)
195 fe.dataOffset = os.FilePointer;
196 CopyFile(fe, os, buffer);
200 foreach (FileEntry fe
in entries)
202 os.Seek(fe.directoryOffset);
203 os.WriteLong(fe.dataOffset);
206 System.Diagnostics.Debug.Assert(finalLength == os.Length);
223 catch (System.IO.IOException)
234 private void CopyFile(FileEntry source,
IndexOutput os, byte[] buffer)
239 long startPtr = os.FilePointer;
241 isRenamed = directory.OpenInput(source.file);
242 long length = isRenamed.Length();
243 long remainder = length;
244 int chunk = buffer.Length;
246 while (remainder > 0)
248 var len = (int) Math.Min(chunk, remainder);
249 isRenamed.ReadBytes(buffer, 0, len,
false);
250 os.WriteBytes(buffer, len);
252 if (checkAbort != null)
260 throw new System.IO.IOException(
"Non-zero remainder length after copying: " + remainder +
" (id: " + source.file +
", length: " + length +
", buffer size: " + chunk +
")");
263 long endPtr = os.FilePointer;
264 long diff = endPtr - startPtr;
266 throw new System.IO.IOException(
"Difference in the output file offsets " + diff +
" does not match the original file length " + length);
270 if (isRenamed != null)