4 Copyright (C) 1996 Free Software Foundation, Inc.
6 Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
9 This file is part of the GNUstep Database Library.
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public
13 License as published by the Free Software Foundation; either
14 version 2 of the License, or (at your option) any later version.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Library General Public License for more details.
21 You should have received a copy of the GNU Library General Public
22 License along with this library; see the file COPYING.LIB.
23 If not, write to the Free Software Foundation,
24 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 // $Id: EORecordDictionary.m 1 2004-08-20 10:38:46Z znek $
31 #import <Foundation/NSObject.h>
32 #import <Foundation/NSDictionary.h>
33 #import <Foundation/NSArray.h>
34 #import <Foundation/NSString.h>
35 #import <Foundation/NSException.h>
37 #if LIB_FOUNDATION_LIBRARY
38 # include <Foundation/exceptions/GeneralExceptions.h>
39 # include <extensions/objc-runtime.h>
41 # include <NGExtensions/NGObjectMacros.h>
44 #include "EORecordDictionary.h"
46 @implementation EORecordDictionary
48 static NSDictionary *emptyDict = nil;
52 if (emptyDict == nil) emptyDict = [[NSDictionary alloc] init];
53 return [emptyDict retain];
56 - (id)initWithObjects:(id *)_objects forKeys:(id *)_keys
57 count:(unsigned int)_count
61 if (emptyDict == nil) emptyDict = [[NSDictionary alloc] init];
62 return [emptyDict retain];
67 return [[NSDictionary alloc]
68 initWithObjects:_objects forKeys:_keys
74 if ((_keys[_count] == nil) || (_objects[_count] == nil)) {
75 [NSException raise:NSInvalidArgumentException
76 format:@"Nil object to be added in dictionary"];
78 self->entries[_count].key = RETAIN(_keys[_count]);
79 self->entries[_count].hash = [_keys[_count] hash];
80 self->entries[_count].value = RETAIN(_objects[_count]);
85 - (id)initWithDictionary:(NSDictionary *)dictionary {
86 // TODO: who calls this method?
90 keys = [dictionary keyEnumerator];
91 self->count = [dictionary count];
93 for (i = 0; i < self->count; i++) {
94 id key = [keys nextObject];
96 self->entries[i].key = RETAIN(key);
97 self->entries[i].hash = [key hash];
98 self->entries[i].value = RETAIN([dictionary objectForKey:key]);
104 /* keys are always NSString keys?! */
106 static Class LastKeyClass = Nil;
107 static IMP keyRelease = 0;
108 static unsigned misses = 0, hits = 0;
110 register unsigned char i;
112 for (i = 0; i < self->count; i++) {
113 register NSString *key = self->entries[i].key;
115 if (*(id *)key != LastKeyClass) {
116 LastKeyClass = *(id *)key;
118 method_get_imp(class_get_instance_method(LastKeyClass,
119 @selector(release)));
125 keyRelease(key, NULL /* dangerous? */);
127 #if PROF_METHOD_CACHE
128 if (hits % 1000 == 0 && hits != 0)
129 NSLog(@"%s: DB HITS: %d MISSES: %d", __PRETTY_FUNCTION__,hits, misses);
135 RELEASE(self->entries[i].value);
142 - (id)objectForKey:(id)aKey {
143 register EORecordDictionaryEntry *e = self->entries;
144 register signed char i;
145 register unsigned hash;
147 static Class LastKeyClass = Nil;
148 static unsigned (*keyHash)(id,SEL) = 0;
149 static BOOL (*keyEq)(id,SEL,id) = 0;
150 #if PROF_METHOD_CACHE
151 static unsigned misses = 0, hits = 0;
159 if (*(id *)aKey != LastKeyClass) {
160 LastKeyClass = *(id *)aKey;
162 method_get_imp(class_get_instance_method(LastKeyClass,
165 method_get_imp(class_get_instance_method(LastKeyClass,
166 @selector(isEqual:)));
169 hash = keyHash(aKey, NULL /* dangerous? */);
174 for (i = (self->count - 1); i >= 0; i--, e++) {
181 if (keyEq(e->key, NULL /* dangerous? */, aKey))
184 if ([e->key isEqual:aKey])
191 - (unsigned int)count {
194 - (NSEnumerator *)keyEnumerator {
195 return AUTORELEASE([[_EORecordDictionaryKeyEnumerator alloc]
196 initWithDictionary:self
197 firstEntry:self->entries count:self->count]);
200 @end /* NSConcreteSmallDictionary */
202 @implementation _EORecordDictionaryKeyEnumerator
204 - (id)initWithDictionary:(EORecordDictionary *)_dict
205 firstEntry:(EORecordDictionaryEntry *)_firstEntry
206 count:(unsigned char)_count
208 self->dict = RETAIN(_dict);
209 self->currentEntry = _firstEntry;
210 self->count = _count;
220 if (self->count > 0) {
222 obj = self->currentEntry->key;
223 self->currentEntry++;
231 @end /* _NSConcreteSmallDictionaryKeyEnumerator */