/*!
@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