ObjFW  Check-in [b110e218cb]

Overview
Comment:Implement Fast Enumeration for OFDictionary.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: b110e218cb0d5508ca6ff7a965f30cd67aa5cde1864206c3cecb05dbfba21f70
User & Date: js on 2010-01-03 21:08:13
Other Links: manifest | tags
Context
2010-01-04
00:18
Fix forgotten static for enumeration_mutation_handler. check-in: c46f609578 user: js tags: trunk
2010-01-03
21:08
Implement Fast Enumeration for OFDictionary. check-in: b110e218cb user: js tags: trunk
21:03
OFMutableDictionary: Add mutations counter. check-in: 4f18e380bf user: js tags: trunk
Changes

Modified src/OFDictionary.h from [9f7e890222] to [dfa50c8022].

9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
 * the packaging of this file.
 */

#include <stdarg.h>

#import "OFObject.h"
#import "OFArray.h"


struct of_dictionary_bucket
{
	OFObject <OFCopying> *key;
	OFObject	     *object;
	uint32_t	     hash;
};

/**
 * The OFDictionary class is a class for using hash tables.
 */
@interface OFDictionary: OFObject <OFCopying, OFMutableCopying>

{
	struct of_dictionary_bucket *data;
	size_t			    size;
	size_t			    count;
}

/**







>











|
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 * the packaging of this file.
 */

#include <stdarg.h>

#import "OFObject.h"
#import "OFArray.h"
#import "OFFastEnumeration.h"

struct of_dictionary_bucket
{
	OFObject <OFCopying> *key;
	OFObject	     *object;
	uint32_t	     hash;
};

/**
 * The OFDictionary class is a class for using hash tables.
 */
@interface OFDictionary: OFObject <OFCopying, OFMutableCopying,
    OFFastEnumeration>
{
	struct of_dictionary_bucket *data;
	size_t			    size;
	size_t			    count;
}

/**

Modified src/OFDictionary.m from [c0653a92e6] to [df376703da].

503
504
505
506
507
508
509























510
511
512
513
514
515
516
	for (i = 0; i < size; i++)
		if (data[i].key != nil &&
		    ![[dict objectForKey: data[i].key] isEqual: data[i].object])
			return NO;

	return YES;
}
























- (void)dealloc
{
	size_t i;

	for (i = 0; i < size; i++) {
		if (data[i].key != nil) {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
	for (i = 0; i < size; i++)
		if (data[i].key != nil &&
		    ![[dict objectForKey: data[i].key] isEqual: data[i].object])
			return NO;

	return YES;
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
			     count: (int)count_
{
	size_t i;

	for (i = 0; i < count_; i++) {
		for (; state->state < size && data[state->state].key == nil;
		    state->state++);

		if (state->state < size) {
			objects[i] = data[state->state].key;
			state->state++;
		} else
			break;
	}

	state->itemsPtr = objects;
	state->mutationsPtr = (unsigned long*)self;

	return i;
}

- (void)dealloc
{
	size_t i;

	for (i = 0; i < size; i++) {
		if (data[i].key != nil) {

Modified src/OFMutableDictionary.m from [301606f51d] to [6f1a880dde].

160
161
162
163
164
165
166























167
	return self;
}

- (id)copy
{
	return [[OFDictionary alloc] initWithDictionary: self];
}























@end







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
	return self;
}

- (id)copy
{
	return [[OFDictionary alloc] initWithDictionary: self];
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
			   objects: (id*)objects
			     count: (int)count_
{
	size_t i;

	for (i = 0; i < count_; i++) {
		for (; state->state < size && data[state->state].key == nil;
		    state->state++);

		if (state->state < size) {
			objects[i] = data[state->state].key;
			state->state++;
		} else
			break;
	}

	state->itemsPtr = objects;
	state->mutationsPtr = &mutations;

	return i;
}
@end

Modified tests/OFDictionary.m from [4e3b8525e6] to [42a6228937].

54
55
56
57
58
59
60





























61
62
63
64
65
66
67
	pair[2] = [enumerator nextKeyObjectPair];
	TEST(@"OFEnumerator's -[nextKeyObjectPair]",
	    [pair[0].key isEqual: keys[0]] &&
	    [pair[0].object isEqual: values[0]] &&
	    [pair[1].key isEqual: keys[1]] &&
	    [pair[1].object isEqual: values[1]] &&
	    pair[2].key == nil && pair[2].object == nil)






























	TEST(@"-[count]", [dict count] == 2)

	TEST(@"+[dictionaryWithKeysAndObjects:]",
	    (dict = [OFDictionary dictionaryWithKeysAndObjects: @"foo", @"bar",
								@"baz", @"qux",
								nil]) &&







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	pair[2] = [enumerator nextKeyObjectPair];
	TEST(@"OFEnumerator's -[nextKeyObjectPair]",
	    [pair[0].key isEqual: keys[0]] &&
	    [pair[0].object isEqual: values[0]] &&
	    [pair[1].key isEqual: keys[1]] &&
	    [pair[1].object isEqual: values[1]] &&
	    pair[2].key == nil && pair[2].object == nil)

#ifdef OF_HAVE_FAST_ENUMERATION
	size_t i = 0;
	BOOL ok = YES;

	for (OFString *key in dict) {
		if (![key isEqual: keys[i]])
			ok = NO;
		[dict setObject: [dict objectForKey: key]
			 forKey: key];
		i++;
	}

	TEST(@"Fast Enumeration", ok)

	ok = NO;
	@try {
		for (OFString *key in dict)
			[dict setObject: @""
				 forKey: @""];
	} @catch (OFEnumerationMutationException *e) {
		ok = YES;
		[e dealloc];
	}

	TEST(@"Detection of mutation during Fast Enumeration", ok)

	[dict removeObjectForKey: @""];
#endif

	TEST(@"-[count]", [dict count] == 2)

	TEST(@"+[dictionaryWithKeysAndObjects:]",
	    (dict = [OFDictionary dictionaryWithKeysAndObjects: @"foo", @"bar",
								@"baz", @"qux",
								nil]) &&