/* Copyright (c) 1998--2005 Benhur Stein This file is part of Pajé. Pajé is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Pajé is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Pajé; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "ChunkArray.h" #include "MultiEnumerator.h" #include "Macros.h" #include "PajeEntity.h" @implementation ChunkArray - (id)init { self = [super init]; if (self != nil) { chunks = [[PSortedArray alloc] initWithSelector:@selector(endTime)]; } return self; } - (void)dealloc { Assign(chunks, nil); [super dealloc]; } - (NSEnumerator *)enumeratorOfEntitiesFromTime:(NSDate *)startTime toTime:(NSDate *)endTime { unsigned startIndex; unsigned endIndex; int index; MultiEnumerator *multiEnum; EntityChunk *chunk; int chunkCount; chunkCount = [chunks count]; if (chunkCount == 0) { return nil; } startIndex = [chunks indexOfFirstObjectNotBeforeValue:startTime]; endIndex = [chunks indexOfFirstObjectNotBeforeValue:endTime]; if (endIndex >= chunkCount) { endIndex = chunkCount - 1; } if (startIndex > endIndex) { return nil; } if (startIndex == endIndex) { chunk = [chunks objectAtIndex:startIndex]; return [chunk enumeratorOfEntitiesFromTime:startTime toTime:endTime]; } // there are multiple chunks involved -- get complete and incomplete // entities from last chunk, all complete from intermediary chunks and some // complete entities from first chunk. multiEnum = [MultiEnumerator enumerator]; chunk = [chunks objectAtIndex:endIndex]; [multiEnum addEnumerator:[chunk enumeratorOfEntitiesBeforeTime:endTime]]; for (index = endIndex - 1; index > startIndex; index--) { chunk = [chunks objectAtIndex:index]; [multiEnum addEnumerator:[chunk enumeratorOfAllCompleteEntities]]; } chunk = [chunks objectAtIndex:startIndex]; [multiEnum addEnumerator: [chunk enumeratorOfCompleteEntitiesAfterTime:startTime]]; return multiEnum; } - (void)addChunk:(EntityChunk *)chunk { [chunks addObject:chunk]; } - (void)removeChunksBeforeTime:(NSDate *)time { int index; index = [chunks indexOfLastObjectNotAfterValue:time]; if (index != NSNotFound) { [chunks removeObjectsInRange:NSMakeRange(0, index+1)]; } } - (void)removeChunksAfterTime:(NSDate *)time { int index; int count; index = [chunks indexOfLastObjectNotAfterValue:time]; if (index == NSNotFound) { // all chunks are after time --- remove them all [chunks removeAllObjects]; } else { // index is the last not after time; the next index is after time index++; count = [chunks count]; if (index < count) { [chunks removeObjectsInRange:NSMakeRange(index, count - index)]; } } } @end