17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
-
-
+
+
-
+
+
-
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
+
-
-
-
-
-
+
+
+
+
-
+
-
+
+
-
+
-
-
+
+
-
+
-
-
-
+
+
+
+
-
+
+
+
+
-
-
+
+
+
|
#import "OFExceptions.h"
#import "OFMacros.h"
@implementation OFMutableDictionary
- setObject: (OFObject*)obj
forKey: (OFObject <OFCopying>*)key
{
uint32_t hash;
of_list_object_t *iter, *key_obj;
uint32_t fullhash, hash;
of_dictionary_list_object_t *iter;
if (key == nil || obj == nil)
@throw [OFInvalidArgumentException newWithClass: isa
andSelector: _cmd];
hash = [key hash] & (size - 1);
fullhash = [key hash];
hash = fullhash & (size - 1);
if (data[hash] == nil)
data[hash] = [[OFList alloc] init];
data[hash] = [[OFList alloc] initWithListObjectSize:
sizeof(of_dictionary_list_object_t)];
for (iter = (of_dictionary_list_object_t*)[data[hash] first];
for (iter = [data[hash] first]; iter != NULL; iter = iter->next->next) {
if ([iter->object isEqual: key]) {
[iter->next->object release];
[obj retain];
iter != NULL; iter = iter->next) {
if ([iter->key isEqual: key]) {
[iter->object release];
iter->object = [obj retain];
iter->next->object = obj;
return self;
}
}
key = [key copy];
@try {
key_obj = [data[hash] append: key];
} @finally {
of_dictionary_list_object_t *o;
[key release];
}
@try {
[data[hash] append: obj];
o = (of_dictionary_list_object_t*)[data[hash] append: obj];
o->key = key;
o->hash = fullhash;
} @catch (OFException *e) {
[data[hash] remove: key_obj];
[key release];
@throw e;
}
return self;
}
- removeObjectForKey: (OFObject*)key
{
uint32_t hash;
of_list_object_t *iter;
of_dictionary_list_object_t *iter;
if (key == nil)
@throw [OFInvalidArgumentException newWithClass: isa
andSelector: _cmd];
hash = [key hash] & (size - 1);
if (data[hash] == nil)
return self;
for (iter = (of_dictionary_list_object_t*)[data[hash] first];
for (iter = [data[hash] first]; iter != NULL; iter = iter->next->next) {
iter != NULL; iter = iter->next) {
if ([iter->object isEqual: key]) {
[data[hash] remove: iter->next];
[data[hash] remove: iter];
[iter->key release];
[data[hash] remove: (of_list_object_t*)iter];
if ([data[hash] first] == NULL) {
[data[hash] release];
data[hash] = nil;
}
return self;
}
}
return self;
}
- changeHashSize: (int)hashsize
{
OFList **newdata;
size_t newsize, i;
of_list_object_t *iter;
of_dictionary_list_object_t *iter;
if (hashsize < 8 || hashsize >= 28)
@throw [OFInvalidArgumentException newWithClass: isa
andSelector: _cmd];
newsize = (size_t)1 << hashsize;
newdata = [self allocMemoryForNItems: newsize
withSize: sizeof(OFList*)];
memset(newdata, 0, newsize * sizeof(OFList*));
for (i = 0; i < size; i++) {
if (OF_LIKELY(data[i] == nil))
continue;
for (iter = [data[i] first]; iter != NULL;
iter = iter->next->next) {
uint32_t hash = [iter->object hash] & (newsize - 1);
for (iter = (of_dictionary_list_object_t*)[data[i] first];
iter != NULL; iter = iter->next) {
uint32_t hash = iter->hash & (newsize - 1);
of_dictionary_list_object_t *o;
if (newdata[hash] == nil)
newdata[hash] = [[OFList alloc] init];
newdata[hash] = [[OFList alloc]
initWithListObjectSize:
sizeof(of_dictionary_list_object_t)];
o = (of_dictionary_list_object_t*)
[newdata[hash] append: iter->object];
[newdata[hash] append: iter->next->object];
[newdata[hash] append: iter->object];
o->key = iter->key;
o->hash = iter->hash;
}
[data[i] release];
}
[self freeMemory: data];
data = newdata;
|