20 using Lucene.Net.Support;
21 using Lucene.Net.Util;
23 using Lucene.Net.Documents;
29 namespace Lucene.Net.Index
42 private readonly
IndexInput cloneableFieldsStream;
48 private readonly
IndexInput cloneableIndexStream;
50 private readonly
int numTotalDocs;
51 private readonly
int size;
53 private readonly
int format;
54 private readonly
int formatSize;
58 private readonly
int docStoreOffset;
61 private readonly
bool isOriginal =
false;
69 public System.Object Clone()
72 return new FieldsReader(fieldInfos, numTotalDocs, size, format, formatSize, docStoreOffset, cloneableFieldsStream, cloneableIndexStream);
78 this.fieldInfos = fieldInfos;
79 this.numTotalDocs = numTotalDocs;
82 this.formatSize = formatSize;
83 this.docStoreOffset = docStoreOffset;
84 this.cloneableFieldsStream = cloneableFieldsStream;
85 this.cloneableIndexStream = cloneableIndexStream;
87 indexStream = (
IndexInput) cloneableIndexStream.Clone();
98 internal FieldsReader(
Directory d, System.String segment, FieldInfos fn,
int readBufferSize,
int docStoreOffset,
int size)
100 bool success =
false;
106 cloneableFieldsStream = d.OpenInput(segment +
"." + IndexFileNames.FIELDS_EXTENSION, readBufferSize);
107 cloneableIndexStream = d.OpenInput(segment +
"." + IndexFileNames.FIELDS_INDEX_EXTENSION, readBufferSize);
112 int firstInt = cloneableIndexStream.ReadInt();
113 format = firstInt == 0 ? 0 : firstInt;
115 if (format > FieldsWriter.FORMAT_CURRENT)
116 throw new CorruptIndexException(
"Incompatible format version: " + format +
" expected " + FieldsWriter.FORMAT_CURRENT +
" or lower");
118 formatSize = format > FieldsWriter.FORMAT ? 4 : 0;
120 if (format < FieldsWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES)
121 cloneableFieldsStream.SetModifiedUTF8StringsMode();
123 fieldsStream = (
IndexInput) cloneableFieldsStream.Clone();
125 long indexSize = cloneableIndexStream.Length() - formatSize;
127 if (docStoreOffset != - 1)
130 this.docStoreOffset = docStoreOffset;
135 System.Diagnostics.Debug.Assert(((
int)(indexSize / 8)) >= size + this.docStoreOffset,
"indexSize=" + indexSize +
" size=" + size +
" docStoreOffset=" + docStoreOffset);
139 this.docStoreOffset = 0;
140 this.size = (int) (indexSize >> 3);
143 indexStream = (
IndexInput) cloneableIndexStream.Clone();
144 numTotalDocs = (int) (indexSize >> 3);
162 internal void EnsureOpen()
175 public void Dispose()
180 if (fieldsStream != null)
182 fieldsStream.Close();
186 if (cloneableFieldsStream != null)
188 cloneableFieldsStream.Close();
190 if (cloneableIndexStream != null)
192 cloneableIndexStream.Close();
195 if (indexStream != null)
199 fieldsStreamTL.Close();
209 private void SeekIndex(
int docID)
211 indexStream.Seek(formatSize + (docID + docStoreOffset) * 8L);
214 internal bool CanReadRawDocs()
220 return format >= FieldsWriter.FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS;
226 long position = indexStream.ReadLong();
227 fieldsStream.Seek(position);
230 int numFields = fieldsStream.ReadVInt();
231 for (
int i = 0; i < numFields; i++)
233 int fieldNumber = fieldsStream.ReadVInt();
234 FieldInfo fi = fieldInfos.FieldInfo(fieldNumber);
237 byte bits = fieldsStream.ReadByte();
240 bool compressed = (bits &
FieldsWriter.FIELD_IS_COMPRESSED) != 0;
241 System.Diagnostics.Debug.Assert(
242 (!compressed || (format <
FieldsWriter.FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS)),
243 "compressed fields are only allowed in indexes of version <= 2.9");
244 bool tokenize = (bits &
FieldsWriter.FIELD_IS_TOKENIZED) != 0;
245 bool binary = (bits &
FieldsWriter.FIELD_IS_BINARY) != 0;
250 AddField(doc, fi, binary, compressed, tokenize);
254 AddField(doc, fi, binary, compressed, tokenize);
259 AddFieldLazy(doc, fi, binary, compressed, tokenize);
263 SkipField(binary, compressed, AddFieldSize(doc, fi, binary, compressed));
267 AddFieldSize(doc, fi, binary, compressed);
272 SkipField(binary, compressed);
284 internal IndexInput RawDocs(
int[] lengths,
int startDocID,
int numDocs)
286 SeekIndex(startDocID);
287 long startOffset = indexStream.ReadLong();
288 long lastOffset = startOffset;
290 while (count < numDocs)
293 int docID = docStoreOffset + startDocID + count + 1;
294 System.Diagnostics.Debug.Assert(docID <= numTotalDocs);
295 if (docID < numTotalDocs)
296 offset = indexStream.ReadLong();
298 offset = fieldsStream.Length();
299 lengths[count++] = (int) (offset - lastOffset);
303 fieldsStream.Seek(startOffset);
311 private void SkipField(
bool binary,
bool compressed)
313 SkipField(binary, compressed, fieldsStream.ReadVInt());
316 private void SkipField(
bool binary,
bool compressed,
int toRead)
318 if (format >= FieldsWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES || binary || compressed)
320 fieldsStream.Seek(fieldsStream.FilePointer + toRead);
325 fieldsStream.SkipChars(toRead);
329 private void AddFieldLazy(
Document doc, FieldInfo fi,
bool binary,
bool compressed,
bool tokenize)
333 int toRead = fieldsStream.ReadVInt();
334 long pointer = fieldsStream.FilePointer;
336 doc.
Add(
new LazyField(
this, fi.name,
Field.
Store.YES, toRead, pointer, binary, compressed));
339 fieldsStream.Seek(pointer + toRead);
344 Field.
Index index = FieldExtensions.ToIndex(fi.isIndexed, tokenize);
345 Field.
TermVector termVector = FieldExtensions.ToTermVector(fi.storeTermVector, fi.storeOffsetWithTermVector, fi.storePositionWithTermVector);
350 int toRead = fieldsStream.ReadVInt();
351 long pointer = fieldsStream.FilePointer;
352 f =
new LazyField(
this, fi.name, store, toRead, pointer, binary, compressed);
354 fieldsStream.Seek(pointer + toRead);
360 int length = fieldsStream.ReadVInt();
361 long pointer = fieldsStream.FilePointer;
363 if (format >= FieldsWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES)
365 fieldsStream.Seek(pointer + length);
369 fieldsStream.SkipChars(length);
371 f =
new LazyField(
this, fi.name, store, index, termVector, length, pointer, binary, compressed)
372 {OmitNorms = fi.omitNorms, OmitTermFreqAndPositions = fi.omitTermFreqAndPositions};
379 private void AddField(
Document doc, FieldInfo fi,
bool binary,
bool compressed,
bool tokenize)
384 int toRead = fieldsStream.ReadVInt();
385 var b =
new byte[toRead];
386 fieldsStream.ReadBytes(b, 0, b.Length);
392 Field.
Index index = FieldExtensions.ToIndex(fi.isIndexed, tokenize);
393 Field.
TermVector termVector = FieldExtensions.ToTermVector(fi.storeTermVector, fi.storeOffsetWithTermVector, fi.storePositionWithTermVector);
398 int toRead = fieldsStream.ReadVInt();
400 var b =
new byte[toRead];
401 fieldsStream.ReadBytes(b, 0, b.Length);
402 f =
new Field(fi.name,
false, System.Text.Encoding.GetEncoding(
"UTF-8").GetString(Uncompress(b)), store, index,
403 termVector) {OmitTermFreqAndPositions = fi.omitTermFreqAndPositions, OmitNorms = fi.omitNorms};
407 f =
new Field(fi.name,
false, fieldsStream.ReadString(), store, index, termVector)
408 {OmitTermFreqAndPositions = fi.omitTermFreqAndPositions, OmitNorms = fi.omitNorms};
418 private int AddFieldSize(
Document doc, FieldInfo fi,
bool binary,
bool compressed)
420 int size = fieldsStream.ReadVInt(), bytesize = binary || compressed?size:2 * size;
421 var sizebytes =
new byte[4];
425 sizebytes[3] = (byte) bytesize;
436 private void InitBlock(FieldsReader enclosingInstance)
438 this.Enclosing_Instance = enclosingInstance;
441 private FieldsReader Enclosing_Instance {
get;
set; }
444 private long pointer;
445 [Obsolete(
"Only kept for backward-compatbility with <3.0 indexes. Will be removed in 4.0.")]
446 private readonly Boolean isCompressed;
448 public LazyField(FieldsReader enclosingInstance, System.String name,
Field.
Store store,
int toRead,
long pointer,
bool isBinary,
bool isCompressed):base(name, store,
Field.Index.NO,
Field.TermVector.NO)
450 InitBlock(enclosingInstance);
451 this.toRead = toRead;
452 this.pointer = pointer;
453 this.internalIsBinary = isBinary;
455 internalBinaryLength = toRead;
457 this.isCompressed = isCompressed;
460 public LazyField(FieldsReader enclosingInstance, System.String name,
Field.
Store store,
Field.
Index index,
Field.
TermVector termVector,
int toRead,
long pointer,
bool isBinary,
bool isCompressed):base(name, store, index, termVector)
462 InitBlock(enclosingInstance);
463 this.toRead = toRead;
464 this.pointer = pointer;
465 this.internalIsBinary = isBinary;
467 internalBinaryLength = toRead;
469 this.isCompressed = isCompressed;
474 IndexInput localFieldsStream = Enclosing_Instance.fieldsStreamTL.Get();
475 if (localFieldsStream == null)
477 localFieldsStream = (
IndexInput) Enclosing_Instance.cloneableFieldsStream.Clone();
478 Enclosing_Instance.fieldsStreamTL.Set(localFieldsStream);
480 return localFieldsStream;
487 public override TextReader ReaderValue
491 Enclosing_Instance.EnsureOpen();
504 Enclosing_Instance.EnsureOpen();
513 public override string StringValue
517 Enclosing_Instance.EnsureOpen();
518 if (internalIsBinary)
521 if (fieldsData == null)
523 IndexInput localFieldsStream = GetFieldStream();
526 localFieldsStream.Seek(pointer);
529 var b =
new byte[toRead];
530 localFieldsStream.ReadBytes(b, 0, b.Length);
532 System.Text.Encoding.GetEncoding(
"UTF-8").GetString(Enclosing_Instance.Uncompress(b));
536 if (Enclosing_Instance.format >= FieldsWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES)
538 var bytes =
new byte[toRead];
539 localFieldsStream.ReadBytes(bytes, 0, toRead);
540 fieldsData = System.Text.Encoding.GetEncoding(
"UTF-8").GetString(bytes);
545 var chars =
new char[toRead];
546 localFieldsStream.ReadChars(chars, 0, toRead);
547 fieldsData =
new System.String(chars);
551 catch (System.IO.IOException e)
553 throw new FieldReaderException(e);
556 return (System.String) fieldsData;
564 Enclosing_Instance.EnsureOpen();
569 Enclosing_Instance.EnsureOpen();
570 this.pointer = value;
578 Enclosing_Instance.EnsureOpen();
583 Enclosing_Instance.EnsureOpen();
588 public override byte[] GetBinaryValue(byte[] result)
590 Enclosing_Instance.EnsureOpen();
592 if (internalIsBinary)
594 if (fieldsData == null)
598 if (result == null || result.Length < toRead)
599 b =
new byte[toRead];
603 IndexInput localFieldsStream = GetFieldStream();
609 localFieldsStream.Seek(pointer);
610 localFieldsStream.ReadBytes(b, 0, toRead);
611 fieldsData = isCompressed ? Enclosing_Instance.Uncompress(b) : b;
613 catch (IOException e)
615 throw new FieldReaderException(e);
618 internalbinaryOffset = 0;
619 internalBinaryLength = toRead;
622 return (byte[]) fieldsData;
628 private byte[] Uncompress(byte[] b)