#include "LCSegmentTermEnum.h" #include "LCTermInfosWriter.h" #include "GNUstep.h" @implementation LCSegmentTermEnumerator - (id) init { self = [super init]; position = -1; [self setTermBuffer: AUTORELEASE([[LCTermBuffer alloc] init])]; [self setPrevBuffer: AUTORELEASE([[LCTermBuffer alloc] init])]; ASSIGN(termInfo, AUTORELEASE([[LCTermInfo alloc] init])); indexPointer = 0; return self; } - (id) initWithIndexInput: (LCIndexInput *) i fieldInfos: (LCFieldInfos *) fis isIndex: (BOOL) isi; { self = [self init]; [self setIndexInput: i]; [self setFieldInfos: fis]; isIndex = isi; int firstInt = [input readInt]; if (firstInt >= 0) { // original-format file, without explicit format version number format = 0; size = firstInt; // back-compatible settings indexInterval = 128; skipInterval = INT_MAX; //Integer.MAX_VALUE; // switch off skipTo optimization } else { // we have a format version number format = firstInt; // check that it is a format we can understand if (format < LCTermInfos_FORMAT) { NSLog(@"Unknown format version: %d", format); return nil; } size = [input readLong]; // read the size if(format == -1){ if (!isIndex) { indexInterval = [input readInt]; formatM1SkipInterval = [input readInt]; } // switch off skipTo optimization for file format prior to 1.4rc2 in order to avoid a bug in // skipTo implementation of these versions skipInterval = INT_MAX; // Integer.MAX_VALUE; } else{ indexInterval = [input readInt]; skipInterval = [input readInt]; } } return self; } - (void) dealloc { DESTROY(termInfo); DESTROY(input); DESTROY(fieldInfos); DESTROY(termBuffer); DESTROY(prevBuffer); DESTROY(scratch); [super dealloc]; } - (void) seek: (long) pointer position: (int) p term: (LCTerm *) t termInfo: (LCTermInfo *) ti { [input seekToFileOffset: pointer]; position = p; [termBuffer setTerm: t]; [termInfo setTermInfo: ti]; } /** Increments the enumeration to the next element. True if one exists.*/ - (BOOL) hasNextTerm { if (position++ >= size-1) { return NO; } [prevBuffer setTerm: termBuffer]; [termBuffer read: input fieldInfos: fieldInfos]; long intValue = [input readVInt]; [termInfo setDocumentFrequency: intValue]; // read doc freq long long longValue = [input readVLong]; [termInfo setFreqPointer: longValue + [termInfo freqPointer]]; // read freq pointer [termInfo setProxPointer: [input readVLong] + [termInfo proxPointer]]; // read prox pointer if(format == -1){ // just read skipOffset in order to increment file pointer; // value is never used since skipTo is switched off if (!isIndex) { if ([termInfo documentFrequency] > formatM1SkipInterval) { [termInfo setSkipOffset: [input readVInt]]; } } } else{ if ([termInfo documentFrequency] >= skipInterval) [termInfo setSkipOffset: [input readVInt]]; } if (isIndex) { long long longValue = [input readVLong]; indexPointer += longValue; // indexPointer += [input readVLong]; // read index pointer } return YES; } /** Optimized scan, without allocating new terms. */ - (void) scanTo: (LCTerm *) term { if (scratch == nil) ASSIGN(scratch, AUTORELEASE([[LCTermBuffer alloc] init])); [scratch setTerm: term]; while (([scratch compare: termBuffer] == NSOrderedDescending) && [self hasNextTerm]) {} } /** Returns the current Term in the enumeration. Initially invalid, valid after next() called for the first time.*/ - (LCTerm *) term { return AUTORELEASE([termBuffer copy]); } /** Returns the previous Term enumerated. Initially null.*/ - (LCTerm *) prev { return AUTORELEASE([prevBuffer copy]); } /** Returns the current TermInfo in the enumeration. Initially invalid, valid after next() called for the first time.*/ - (LCTermInfo *) termInfo { return AUTORELEASE([[LCTermInfo alloc] initWithTermInfo: termInfo]); } /** Sets the argument to the current TermInfo in the enumeration. Initially invalid, valid after next() called for the first time.*/ - (void) setTermInfo: (LCTermInfo *) ti { [termInfo setTermInfo: ti]; } /** Returns the docFreq from the current TermInfo in the enumeration. Initially invalid, valid after next() called for the first time.*/ - (long) documentFrequency { return [termInfo documentFrequency]; } /* Returns the freqPointer from the current TermInfo in the enumeration. Initially invalid, valid after next() called for the first time.*/ - (long long) freqPointer { return [termInfo freqPointer]; } /* Returns the proxPointer from the current TermInfo in the enumeration. Initially invalid, valid after next() called for the first time.*/ - (long long) proxPointer { return [termInfo proxPointer]; } /** Closes the enumeration to further activity, freeing resources. */ - (void) close { [input close]; } - (void) setIndexInput: (LCIndexInput *) i { ASSIGN(input, i); } - (void) setTermBuffer: (LCTermBuffer *) tb { ASSIGN(termBuffer, tb); } - (void) setPrevBuffer: (LCTermBuffer *) pb { ASSIGN(prevBuffer, pb); } - (void) setScratch: (LCTermBuffer *) s { ASSIGN(scratch, s); } - (void) setSize: (long long) s { size = s; } - (void) setPosition: (long long ) p { position = p; } - (void) setFormat: (int) f { format = f; } - (void) setIndexed: (BOOL) index { isIndex = index; } - (void) setIndexPointer: (long) p { indexPointer = p; } - (void) setIndexInterval: (int) i { indexInterval = i; } - (void) setSkipInterval: (unsigned int) skip { skipInterval = skip; } - (void) setFormatM1SkipInterval: (int) formatM1 { formatM1SkipInterval = formatM1; } - (void) setFieldInfos: (LCFieldInfos *) fi { ASSIGN(fieldInfos, fi); } - (LCFieldInfos *) fieldInfos { return fieldInfos; } - (long long) size { return size; } - (long) indexPointer { return indexPointer; } - (int) indexInterval { return indexInterval; } - (unsigned int) skipInterval { return skipInterval; } - (long long) position { return position; } - (id) copyWithZone: (NSZone *) zone { LCSegmentTermEnumerator *clone = [[LCSegmentTermEnumerator allocWithZone: zone] init]; [clone setIndexInput: AUTORELEASE([input copy])]; [clone setFieldInfos: fieldInfos]; [clone setSize: size]; [clone setPosition: position]; [clone setTermInfo: AUTORELEASE([termInfo copy])]; [clone setTermBuffer: AUTORELEASE([termBuffer copy])]; [clone setPrevBuffer: AUTORELEASE([prevBuffer copy])]; [clone setScratch: nil]; [clone setFormat: format]; [clone setIndexed: isIndex]; [clone setIndexPointer: indexPointer]; [clone setIndexInterval: indexInterval]; [clone setSkipInterval: skipInterval]; [clone setFormatM1SkipInterval: formatM1SkipInterval]; return clone; } @end