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.
30 #import <Foundation/NSObject.h>
31 #import <Foundation/NSDictionary.h>
32 #import <Foundation/NSArray.h>
33 #import <Foundation/NSString.h>
34 #import <Foundation/NSException.h>
36 #if LIB_FOUNDATION_LIBRARY
37 # include <extensions/objc-runtime.h>
39 # include <NGExtensions/NGObjectMacros.h>
42 #include "EORecordDictionary.h"
44 @implementation EORecordDictionary
46 static NSDictionary *emptyDict = nil;
50 if (emptyDict == nil) emptyDict = [[NSDictionary alloc] init];
51 return [emptyDict retain];
54 - (id)initWithObjects:(id *)_objects forKeys:(id *)_keys
55 count:(unsigned int)_count
59 if (emptyDict == nil) emptyDict = [[NSDictionary alloc] init];
60 return [emptyDict retain];
65 return [[NSDictionary alloc]
66 initWithObjects:_objects forKeys:_keys
72 if ((_keys[_count] == nil) || (_objects[_count] == nil)) {
73 [NSException raise:NSInvalidArgumentException
74 format:@"Nil object to be added in dictionary"];
76 self->entries[_count].key = RETAIN(_keys[_count]);
77 self->entries[_count].hash = [_keys[_count] hash];
78 self->entries[_count].value = RETAIN(_objects[_count]);
83 - (id)initWithDictionary:(NSDictionary *)dictionary {
84 // TODO: who calls this method?
88 keys = [dictionary keyEnumerator];
89 self->count = [dictionary count];
91 for (i = 0; i < self->count; i++) {
92 id key = [keys nextObject];
94 self->entries[i].key = RETAIN(key);
95 self->entries[i].hash = [key hash];
96 self->entries[i].value = RETAIN([dictionary objectForKey:key]);
102 /* keys are always NSString keys?! */
104 static Class LastKeyClass = Nil;
105 static IMP keyRelease = 0;
106 static unsigned misses = 0, hits = 0;
108 register unsigned char i;
110 for (i = 0; i < self->count; i++) {
111 register NSString *key = self->entries[i].key;
113 if (*(id *)key != LastKeyClass) {
114 LastKeyClass = *(id *)key;
116 method_get_imp(class_get_instance_method(LastKeyClass,
117 @selector(release)));
123 keyRelease(key, NULL /* dangerous? */);
125 #if PROF_METHOD_CACHE
126 if (hits % 1000 == 0 && hits != 0)
127 NSLog(@"%s: DB HITS: %d MISSES: %d", __PRETTY_FUNCTION__,hits, misses);
133 RELEASE(self->entries[i].value);
140 - (id)objectForKey:(id)aKey {
141 register EORecordDictionaryEntry *e = self->entries;
142 register signed char i;
143 register unsigned hash;
145 static Class LastKeyClass = Nil;
146 static unsigned (*keyHash)(id,SEL) = 0;
147 static BOOL (*keyEq)(id,SEL,id) = 0;
148 #if PROF_METHOD_CACHE
149 static unsigned misses = 0, hits = 0;
157 if (*(id *)aKey != LastKeyClass) {
158 LastKeyClass = *(id *)aKey;
160 method_get_imp(class_get_instance_method(LastKeyClass,
163 method_get_imp(class_get_instance_method(LastKeyClass,
164 @selector(isEqual:)));
167 hash = keyHash(aKey, NULL /* dangerous? */);
172 for (i = (self->count - 1); i >= 0; i--, e++) {
179 if (keyEq(e->key, NULL /* dangerous? */, aKey))
182 if ([e->key isEqual:aKey])
189 - (unsigned int)count {
192 - (NSEnumerator *)keyEnumerator {
193 return AUTORELEASE([[_EORecordDictionaryKeyEnumerator alloc]
194 initWithDictionary:self
195 firstEntry:self->entries count:self->count]);
198 @end /* NSConcreteSmallDictionary */
200 @implementation _EORecordDictionaryKeyEnumerator
202 - (id)initWithDictionary:(EORecordDictionary *)_dict
203 firstEntry:(EORecordDictionaryEntry *)_firstEntry
204 count:(unsigned char)_count
206 self->dict = RETAIN(_dict);
207 self->currentEntry = _firstEntry;
208 self->count = _count;
218 if (self->count > 0) {
220 obj = self->currentEntry->key;
221 self->currentEntry++;
229 @end /* _NSConcreteSmallDictionaryKeyEnumerator */