#include "LCMultipleTermPositions.h" #include "LCPriorityQueue.h" /** * Describe class MultipleTermPositions here. * * @author Anders Nielsen * @version 1.0 */ @interface LCTermPositionsQueue: LCPriorityQueue - (id) initWithTermPositions: (NSArray *) termPositions; - (id ) peek; @end @implementation LCTermPositionsQueue - (id) initWithTermPositions: (NSArray *) termPositions { self = [super initWithSize: [termPositions count]]; NSEnumerator *e = [termPositions objectEnumerator]; id tp; while((tp = [e nextObject])) { if ([tp hasNextDocument]) [self put:tp]; } return self; } - (id ) peek { return (id )[self top]; } @end @interface LCIntQueue: NSObject { int _arraySize; int _index; int _lastIndex; NSMutableArray *_array; } - (void) add: (int) i; - (int) next; - (void) sort; - (void) clear; - (int) size; - (void) growArray; @end @implementation LCIntQueue - (id) init { self = [super init]; _arraySize = 16; _index = 0; _lastIndex = 0; _array = [[NSMutableArray alloc] init]; return self; } - (void) add: (int) i { if (_lastIndex == _arraySize) [self growArray]; [_array addObject: [NSNumber numberWithInt: i]]; _lastIndex++; } - (int) next { return [[_array objectAtIndex: _index++] intValue]; } - (void) sort { [_array sortUsingSelector: @selector(compare:)]; } - (void) clear { _index = 0; _lastIndex = 0; [_array removeAllObjects]; } - (int) size { return (_lastIndex - _index); } - (void) growArray { _arraySize *= 2; } @end @implementation LCMultipleTermPositions /** * Creates a new MultipleTermPositions instance. * * @param indexReader an IndexReader value * @param terms a Term[] value * @exception IOException if an error occurs */ - (id) initWithIndexReader: (LCIndexReader *) indexReader terms: (NSArray *) terms { self = [super init]; NSMutableArray *termPositions = [[NSMutableArray alloc] init]; int i; for (i = 0; i < [terms count]; i++) [termPositions addObject: [indexReader termPositionsWithTerm: [terms objectAtIndex: i] ]]; _termPositionsQueue = [[LCTermPositionsQueue alloc] initWithTermPositions: termPositions]; _posList = [[LCIntQueue alloc] init]; return self; } - (BOOL) hasNextDocument { if ([_termPositionsQueue size] == 0) return NO; [_posList clear]; _doc = [[_termPositionsQueue peek] document]; id tp; do { tp = [_termPositionsQueue peek]; int i; for (i=0; i< [tp frequency]; i++) [_posList add: [tp nextPosition]]; if ([tp hasNextDocument]) [_termPositionsQueue adjustTop]; else { [_termPositionsQueue pop]; [tp close]; } } while ([_termPositionsQueue size] > 0 && [[_termPositionsQueue peek] document] == _doc); [_posList sort]; _freq = [_posList size]; return YES; } - (int) nextPosition { return [_posList next]; } - (BOOL) skipTo: (int) target { #if 1 while (target > [[_termPositionsQueue peek] document]) #else /* FIXME: below is new code */ while (_termPositionsQueue.peek() != null && target > _termPositionsQueue.peek().doc()) #endif { id tp = (id )[_termPositionsQueue pop]; if ([tp skipTo: target]) [_termPositionsQueue put: tp]; else [tp close]; } return [self hasNextDocument]; } - (long) document { return _doc; } - (long) frequency { return _freq; } - (void) close { while ([_termPositionsQueue size] > 0) [(id )[_termPositionsQueue pop] close]; } /** Not implemented. * @throws UnsupportedOperationException */ - (void) seekTerm: (LCTerm *) arg0 { NSLog(@"UnsupportedOperation"); } /** Not implemented. * @throws UnsupportedOperationException */ - (void) seekTermEnumerator: (LCTermEnumerator *) termEnum { NSLog(@"UnsupportedOperation"); } /** Not implemented. * @throws UnsupportedOperationException */ - (int) readDocuments: (NSMutableArray *) docs frequency: (NSMutableArray *) freq size: (int) size { NSLog(@"UnsupportedOperation"); return 0; } - (NSComparisonResult) compare: (id) o { LCMultipleTermPositions *other = (LCMultipleTermPositions *) o; if ([self document] < [other document]) return NSOrderedAscending; else if ([self document] == [other document]) return NSOrderedSame; else return NSOrderedDescending; } @end