/*! @header FTOrderedReferenceSetImpl @abstract Module of FT @availability OS X, GNUstep @copyright 2004, 2005, 2006 Free Software Foundation, Inc. This library 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.1 of the License, or (at your option) any later version. This library 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 this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  -------------------------------------------------------------------------
  Modification history

  11.09.05 ola     initial version
  23.08.06 ola     license changed
  -------------------------------------------------------------------------
  
*/ #include #include #include @implementation FTOrderedReferenceSetImpl - initForBaseNode: (id ) aNode { self = [super init]; self->baseNodeId = [[aNode nodeId] retain]; self->references = [[NSMutableArray alloc] init]; self->nodeIdToIndexArray = [[NSMutableDictionary alloc] init]; self->edgeIdToIndex = [[NSMutableDictionary alloc] init]; return self; } - (id) initWithCoder:(NSCoder *) decoder { self->baseNodeId = [[decoder decodeObject] retain]; self->references = [[decoder decodeObject] retain]; self->nodeIdToIndexArray = nil; self->edgeIdToIndex = nil; [self createIndexes]; return self; } - (void) dealloc { [self->baseNodeId release]; [self->references release]; [self->nodeIdToIndexArray release]; [self->edgeIdToIndex release]; [super dealloc]; } - (id ) allReferences { return [[ECArrayIterator alloc] initWithArray: self->references]; } - (unsigned) countReferences { return [self->references count]; } - createAndAppendReferenceToNode: (id ) aNodeId withEdgeId: (id ) anEdgeId { NSNumber *indexOfNewEntry = [[NSNumber alloc] initWithUnsignedInt: [self->references count]]; FTReferenceImpl *reference = [[FTReferenceImpl alloc] initWithNodeId: aNodeId edgeId: anEdgeId]; [self->references addObject: reference ]; [self updateIndexes: indexOfNewEntry forReference: reference]; [reference release]; [indexOfNewEntry release]; return self; } - createIndexes { unsigned i; if( nil != self->nodeIdToIndexArray ) { [self->nodeIdToIndexArray release]; } self->nodeIdToIndexArray = [[NSMutableDictionary alloc] init]; if( nil != self->edgeIdToIndex ) { [self->edgeIdToIndex release]; } self->edgeIdToIndex = [[NSMutableDictionary alloc] init]; for(i = 0; i < [self->references count]; i++) { FTReferenceImpl *current = (FTReferenceImpl *) [self->references objectAtIndex: i]; NSNumber *index = [[NSNumber alloc] initWithUnsignedInt: i]; [self updateIndexes: index forReference: current]; [index release]; } return self; } - (void) encodeWithCoder:(NSCoder *) encoder { [encoder encodeObject: self->baseNodeId]; [encoder encodeObject: self->references]; } - (unsigned) hash { return [self->baseNodeId hash] + 17; } - (BOOL) isEqual: (id) anObject { if( nil != anObject ) { if( [anObject isKindOfClass: [self class]] ) { FTOrderedReferenceSetImpl *set = (FTOrderedReferenceSetImpl *) anObject; if( [self->baseNodeId isEqual: set->baseNodeId] ) { return [self->references isEqual: set->references]; } else { return NO; } } else { return NO; } } else { return NO; } } - (id ) referencesByNodeId: (id ) aNodeId { NSArray *indexArray = [self->nodeIdToIndexArray objectForKey: aNodeId]; NSMutableArray *foundReferences = [[NSMutableArray alloc] init]; ECArrayIterator *result; if( nil != indexArray ) { int i; for(i = 0; i < [indexArray count]; i++) { NSNumber *currentIndex = [indexArray objectAtIndex: i]; [foundReferences addObject: [self->references objectAtIndex: [currentIndex unsignedIntValue]]]; } } result = [[ECArrayIterator alloc] initWithArray: foundReferences]; [foundReferences release]; return result; } - (id ) referenceByEdgeId: (id ) anEdgeId { NSNumber *index = (NSNumber *) [self->edgeIdToIndex objectForKey: anEdgeId]; FTReferenceImpl *toReturn = nil; if( nil != index ) { toReturn = (FTReferenceImpl *) [self->references objectAtIndex: [index unsignedIntValue]]; } return toReturn; } - removeReference: (id ) toRemove { NSNumber *index = (NSNumber *) [self->edgeIdToIndex objectForKey: [toRemove edgeId]]; if( nil != index ) { [self->references removeObjectAtIndex: [index unsignedIntValue]]; [self createIndexes]; } return self; } - updateIndexes: (NSNumber *) indexOfNewEntry forReference: (FTReferenceImpl *) aReference { NSMutableArray *indexArray = [self->nodeIdToIndexArray objectForKey: [aReference nodeId]]; if( nil == indexArray ) { indexArray = [[NSMutableArray alloc] init]; [self->nodeIdToIndexArray setObject: indexArray forKey: [aReference nodeId]]; } if( [self->edgeIdToIndex objectForKey: [aReference edgeId]] ) { // an entry already exists for the given reference! [indexArray release]; [[[ECIllegalArgumentException alloc] initWithArgumentInfo: @"FTOrderedReferenceSetImpl::updateIndexes: "\ "Edge id already exists in set!" ] raise]; } [self->edgeIdToIndex setObject: indexOfNewEntry forKey: [aReference edgeId]]; [indexArray addObject: indexOfNewEntry]; [indexArray release]; return self; } @end