Objectively 1.0.0
Ultra-lightweight object oriented framework for GNU C.
Macros | Functions
MutableDictionary.c File Reference
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include "Hash.h"
#include "MutableArray.h"
#include "MutableDictionary.h"
#include "String.h"

Go to the source code of this file.

Macros

#define _Class   _MutableDictionary
 
#define MUTABLEDICTIONARY_DEFAULT_CAPACITY   64
 
#define MUTABLEDICTIONARY_GROW_FACTOR   2.0
 
#define MUTABLEDICTIONARY_MAX_LOAD   0.75f
 

Functions

Class_MutableDictionary (void)
 
static void addEntriesFromDictionary (MutableDictionary *self, const Dictionary *dictionary)
 
static void addEntriesFromDictionary_enumerator (const Dictionary *dict, ident obj, ident key, ident data)
 DictionaryEnumerator for addEntriesFromDictionary. More...
 
static Objectcopy (const Object *self)
 
static MutableDictionarydictionary (void)
 
static MutableDictionarydictionaryWithCapacity (size_t capacity)
 
static MutableDictionaryinit (MutableDictionary *self)
 
static void initialize (Class *clazz)
 
static MutableDictionaryinitWithCapacity (MutableDictionary *self, size_t capacity)
 
static void removeAllObjects (MutableDictionary *self)
 
static void removeAllObjectsWithEnumerator (MutableDictionary *self, DictionaryEnumerator enumerator, ident data)
 
static void removeObjectForKey (MutableDictionary *self, const ident key)
 
static void removeObjectForKeyPath (MutableDictionary *self, const char *path)
 
static void setObjectForKey (MutableDictionary *self, const ident obj, const ident key)
 
static void setObjectForKey_resize (Dictionary *dict)
 A helper for resizing Dictionaries as pairs are added to them. More...
 
static void setObjectForKeyPath (MutableDictionary *self, const ident obj, const char *path)
 
static void setObjectsForKeyPaths (MutableDictionary *self,...)
 
static void setObjectsForKeys (MutableDictionary *self,...)
 

Macro Definition Documentation

◆ _Class

#define _Class   _MutableDictionary

Definition at line 33 of file MutableDictionary.c.

◆ MUTABLEDICTIONARY_DEFAULT_CAPACITY

#define MUTABLEDICTIONARY_DEFAULT_CAPACITY   64

Definition at line 35 of file MutableDictionary.c.

◆ MUTABLEDICTIONARY_GROW_FACTOR

#define MUTABLEDICTIONARY_GROW_FACTOR   2.0

Definition at line 36 of file MutableDictionary.c.

◆ MUTABLEDICTIONARY_MAX_LOAD

#define MUTABLEDICTIONARY_MAX_LOAD   0.75f

Definition at line 37 of file MutableDictionary.c.

Function Documentation

◆ _MutableDictionary()

Class * _MutableDictionary ( void  )

Definition at line 371 of file MutableDictionary.c.

371 {
372 static Class *clazz;
373 static Once once;
374
375 do_once(&once, {
376 clazz = _initialize(&(const ClassDef) {
377 .name = "MutableDictionary",
378 .superclass = _Dictionary(),
379 .instanceSize = sizeof(MutableDictionary),
380 .interfaceOffset = offsetof(MutableDictionary, interface),
381 .interfaceSize = sizeof(MutableDictionaryInterface),
383 });
384 });
385
386 return clazz;
387}
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition: Class.c:91
static void initialize(Class *clazz)
long Once
The Once type.
Definition: Once.h:37
#define do_once(once, block)
Executes the given block at most one time.
Definition: Once.h:43
ClassDefs are passed to _initialize via an archetype to initialize a Class.
Definition: Class.h:41
The runtime representation of a Class.
Definition: Class.h:95
Class * _Dictionary(void)
The Dictionary archetype.
Definition: Dictionary.c:451
Mutable key-value stores.

◆ addEntriesFromDictionary()

static void addEntriesFromDictionary ( MutableDictionary self,
const Dictionary dictionary 
)
static

Definition at line 68 of file MutableDictionary.c.

68 {
69
70 assert(dictionary);
71
73}
static void addEntriesFromDictionary_enumerator(const Dictionary *dict, ident obj, ident key, ident data)
DictionaryEnumerator for addEntriesFromDictionary.
void enumerateObjectsAndKeys(const Dictionary *self, DictionaryEnumerator enumerator, ident data)
Enumerate the pairs of this Dictionary with the given function.
Definition: Dictionary.c:253
MutableDictionary * dictionary(void)
Returns a new MutableDictionary.

◆ addEntriesFromDictionary_enumerator()

static void addEntriesFromDictionary_enumerator ( const Dictionary dict,
ident  obj,
ident  key,
ident  data 
)
static

DictionaryEnumerator for addEntriesFromDictionary.

Definition at line 60 of file MutableDictionary.c.

60 {
62}
#define obj
MutableData * data(void)
Returns a new MutableData.
Definition: MutableData.c:75
void setObjectForKey(MutableDictionary *self, const ident obj, const ident key)
Sets a pair in this MutableDictionary.

◆ copy()

static Object * copy ( const Object self)
static
See also
Object::copy(const Object *)

Definition at line 44 of file MutableDictionary.c.

44 {
45
46 const Dictionary *this = (const Dictionary *) self;
47
49
51
52 return (Object *) copy;
53}
#define alloc(type)
Allocate and initialize and instance of type.
Definition: Class.h:159
Immutable key-value stores.
Definition: Dictionary.h:60
MutableArray * initWithCapacity(MutableArray *self, size_t capacity)
Initializes this MutableArray with the specified capacity.
Definition: MutableArray.c:195
void addEntriesFromDictionary(MutableDictionary *self, const Dictionary *dictionary)
Adds the key-value entries from dictionary to this MutableDictionary.
Object is the root Class of The Objectively Class hierarchy.
Definition: Object.h:46
Object * copy(const Object *self)
Creates a shallow copy of this Object.
Definition: Array.c:40

◆ dictionary()

static MutableDictionary * dictionary ( void  )
static

Definition at line 79 of file MutableDictionary.c.

79 {
80
81 return $(alloc(MutableDictionary), init);
82}
Condition * init(Condition *self)
Initializes this Condition.
Definition: Condition.c:67

◆ dictionaryWithCapacity()

static MutableDictionary * dictionaryWithCapacity ( size_t  capacity)
static

Definition at line 88 of file MutableDictionary.c.

88 {
89
90 return $(alloc(MutableDictionary), initWithCapacity, capacity);
91}

◆ init()

static MutableDictionary * init ( MutableDictionary self)
static

Definition at line 97 of file MutableDictionary.c.

97 {
98
100}
#define MUTABLEDICTIONARY_DEFAULT_CAPACITY

◆ initialize()

static void initialize ( Class clazz)
static
See also
Class::initialize(Class *)

Definition at line 348 of file MutableDictionary.c.

348 {
349
350 ((ObjectInterface *) clazz->interface)->copy = copy;
351
352 ((MutableDictionaryInterface *) clazz->interface)->addEntriesFromDictionary = addEntriesFromDictionary;
353 ((MutableDictionaryInterface *) clazz->interface)->dictionary = dictionary;
354 ((MutableDictionaryInterface *) clazz->interface)->dictionaryWithCapacity = dictionaryWithCapacity;
355 ((MutableDictionaryInterface *) clazz->interface)->init = init;
356 ((MutableDictionaryInterface *) clazz->interface)->initWithCapacity = initWithCapacity;
357 ((MutableDictionaryInterface *) clazz->interface)->removeAllObjects = removeAllObjects;
358 ((MutableDictionaryInterface *) clazz->interface)->removeAllObjectsWithEnumerator = removeAllObjectsWithEnumerator;
359 ((MutableDictionaryInterface *) clazz->interface)->removeObjectForKey = removeObjectForKey;
360 ((MutableDictionaryInterface *) clazz->interface)->removeObjectForKeyPath = removeObjectForKeyPath;
361 ((MutableDictionaryInterface *) clazz->interface)->setObjectForKey = setObjectForKey;
362 ((MutableDictionaryInterface *) clazz->interface)->setObjectForKeyPath = setObjectForKeyPath;
363 ((MutableDictionaryInterface *) clazz->interface)->setObjectsForKeyPaths = setObjectsForKeyPaths;
364 ((MutableDictionaryInterface *) clazz->interface)->setObjectsForKeys = setObjectsForKeys;
365}
ident interface
The interface of the Class.
Definition: Class.h:105
void removeAllObjectsWithEnumerator(MutableArray *self, ArrayEnumerator enumerator, ident data)
Removes all Objects from this MutableArray, invoking enumerator for each Object.
Definition: MutableArray.c:243
void removeAllObjects(MutableArray *self)
Removes all Objects from this MutableArray.
Definition: MutableArray.c:232
MutableDictionary * dictionaryWithCapacity(size_t capacity)
Returns a new MutableDictionary with the given capacity.
void removeObjectForKeyPath(MutableDictionary *self, const char *path)
Removes the Object with the specified key path from this MutableDictionary.
void setObjectForKeyPath(MutableDictionary *self, const ident obj, const char *path)
Sets a pair in this MutableDictionary.
void setObjectsForKeys(MutableDictionary *self,...)
Sets pairs in this MutableDictionary from the NULL-terminated list.
void removeObjectForKey(MutableDictionary *self, const ident key)
Removes the Object with the specified key from this MutableDictionary.
MutableDictionary * init(MutableDictionary *self)
Initializes this MutableDictionary.
void setObjectsForKeyPaths(MutableDictionary *self,...)
Sets pairs in this MutableDictionary from the NULL-terminated list.

◆ initWithCapacity()

static MutableDictionary * initWithCapacity ( MutableDictionary self,
size_t  capacity 
)
static

Definition at line 106 of file MutableDictionary.c.

106 {
107
108 self = (MutableDictionary *) super(Object, self, init);
109 if (self) {
110
111 self->dictionary.capacity = capacity;
112 if (self->dictionary.capacity) {
113
114 self->dictionary.elements = calloc(self->dictionary.capacity, sizeof(ident));
115 assert(self->dictionary.elements);
116 }
117 }
118
119 return self;
120}
#define super(type, obj, method,...)
void * ident
The identity type, similar to Objective-C id.
Definition: Types.h:49
Dictionary dictionary
The superclass.

◆ removeAllObjects()

static void removeAllObjects ( MutableDictionary self)
static

Definition at line 126 of file MutableDictionary.c.

126 {
127
128 for (size_t i = 0; i < self->dictionary.capacity; i++) {
129
130 Array *array = self->dictionary.elements[i];
131 if (array) {
132 self->dictionary.elements[i] = release(array);
133 }
134 }
135
136 self->dictionary.count = 0;
137}
ident release(ident obj)
Atomically decrement the given Object's reference count. If the resulting reference count is 0,...
Definition: Class.c:196
Immutable arrays.
Definition: Array.h:56
size_t count
The count of elements.
Definition: Dictionary.h:82
MutableArray * array(void)
Returns a new MutableArray.
Definition: MutableArray.c:153

◆ removeAllObjectsWithEnumerator()

static void removeAllObjectsWithEnumerator ( MutableDictionary self,
DictionaryEnumerator  enumerator,
ident  data 
)
static

Definition at line 143 of file MutableDictionary.c.

143 {
144
145 assert(enumerator);
146
147 for (size_t i = 0; i < self->dictionary.capacity; i++) {
148
149 Array *array = self->dictionary.elements[i];
150 if (array) {
151 for (size_t j = array->count; j > 0; j -= 2) {
152
153 ident obj = array->elements[j - 1];
154 ident key = array->elements[j - 2];
155
156 enumerator((Dictionary *) self, obj, key, data);
157
160 }
161
162 self->dictionary.elements[i] = release(array);
163 }
164 }
165
166 self->dictionary.count = 0;
167}
size_t count
The count of elements.
Definition: Array.h:72
Mutable arrays.
Definition: MutableArray.h:40
void removeObjectAtIndex(MutableArray *self, size_t index)
Removes the Object at the specified index.
Definition: MutableArray.c:282

◆ removeObjectForKey()

static void removeObjectForKey ( MutableDictionary self,
const ident  key 
)
static

Definition at line 173 of file MutableDictionary.c.

173 {
174
175 if (self->dictionary.capacity == 0) {
176 return;
177 }
178
179 const size_t bin = HashForObject(HASH_SEED, key) % self->dictionary.capacity;
180
181 MutableArray *array = self->dictionary.elements[bin];
182 if (array) {
183
184 const ssize_t index = $((Array *) array, indexOfObject, key);
185 if (index > -1) {
186
187 $(array, removeObjectAtIndex, index);
188 $(array, removeObjectAtIndex, index);
189
190 if (((Array *) array)->count == 0) {
191 self->dictionary.elements[bin] = release(array);
192 }
193
194 self->dictionary.count--;
195 }
196 }
197}
int HashForObject(int hash, const ident obj)
Accumulates the hash value of object into hash.
Definition: Hash.c:66
#define HASH_SEED
The hash seed value.
Definition: Hash.h:37
ssize_t indexOfObject(const Array *self, const ident obj)
Definition: Array.c:271

◆ removeObjectForKeyPath()

static void removeObjectForKeyPath ( MutableDictionary self,
const char *  path 
)
static

Definition at line 203 of file MutableDictionary.c.

203 {
204
205 String *key = $$(String, stringWithCharacters, path);
206
207 $(self, removeObjectForKey, key);
208
209 release(key);
210}
Immutable UTF-8 strings.
Definition: String.h:69
String * stringWithCharacters(const char *chars)
Returns a new String by copying chars.
Definition: String.c:487

◆ setObjectForKey()

static void setObjectForKey ( MutableDictionary self,
const ident  obj,
const ident  key 
)
static

Definition at line 260 of file MutableDictionary.c.

260 {
261
262 Dictionary *dict = (Dictionary *) self;
263
265
266 const size_t bin = HashForObject(HASH_SEED, key) % dict->capacity;
267
268 MutableArray *array = dict->elements[bin];
269 if (array == NULL) {
270 array = dict->elements[bin] = $$(MutableArray, arrayWithCapacity, (dict->capacity >> 2) + 1);
271 }
272
273 const ssize_t index = $((Array *) array, indexOfObject, key);
274 if (index > -1) {
275 $(array, setObjectAtIndex, obj, index + 1);
276 } else {
277 $(array, addObject, key);
278 $(array, addObject, obj);
279
280 dict->count++;
281 }
282}
static void setObjectForKey_resize(Dictionary *dict)
A helper for resizing Dictionaries as pairs are added to them.
void setObjectAtIndex(MutableArray *self, const ident obj, size_t index)
Replaces the Object at the specified index.
Definition: MutableArray.c:299
MutableArray * arrayWithCapacity(size_t capacity)
Returns a new MutableArray with the given capacity.
Definition: MutableArray.c:162
void addObject(MutableArray *self, const ident obj)
Adds the specified Object to this MutableArray.
Definition: MutableArray.c:99

◆ setObjectForKey_resize()

static void setObjectForKey_resize ( Dictionary dict)
static

A helper for resizing Dictionaries as pairs are added to them.

Remarks
Static method invocations are used for all operations.

Definition at line 216 of file MutableDictionary.c.

216 {
217
218 if (dict->capacity) {
219
220 const float load = dict->count / (float) dict->capacity;
221 if (load >= MUTABLEDICTIONARY_MAX_LOAD) {
222
223 size_t capacity = dict->capacity;
224 ident *elements = dict->elements;
225
226 dict->capacity = dict->capacity * MUTABLEDICTIONARY_GROW_FACTOR;
227 dict->count = 0;
228
229 dict->elements = calloc(dict->capacity, sizeof(ident));
230 assert(dict->elements);
231
232 for (size_t i = 0; i < capacity; i++) {
233
234 Array *array = elements[i];
235 if (array) {
236
237 for (size_t j = 0; j < array->count; j += 2) {
238
239 ident key = $(array, objectAtIndex, j);
240 ident obj = $(array, objectAtIndex, j + 1);
241
243 }
244
245 release(array);
246 }
247 }
248
249 free(elements);
250 }
251 } else {
253 }
254}
#define MUTABLEDICTIONARY_MAX_LOAD
#define MUTABLEDICTIONARY_GROW_FACTOR
ident objectAtIndex(const Array *self, int index)

◆ setObjectForKeyPath()

static void setObjectForKeyPath ( MutableDictionary self,
const ident  obj,
const char *  path 
)
static

Definition at line 288 of file MutableDictionary.c.

288 {
289
290 String *key = $$(String, stringWithCharacters, path);
291
292 $(self, setObjectForKey, obj, key);
293
294 release(key);
295}

◆ setObjectsForKeyPaths()

static void setObjectsForKeyPaths ( MutableDictionary self,
  ... 
)
static

Definition at line 301 of file MutableDictionary.c.

301 {
302
303 va_list args;
304 va_start(args, self);
305
306 while (true) {
307
308 ident obj = va_arg(args, ident);
309 if (obj) {
310 const char *path = va_arg(args, const char *);
311 $(self, setObjectForKeyPath, obj, path);
312 } else {
313 break;
314 }
315 }
316
317 va_end(args);
318}

◆ setObjectsForKeys()

static void setObjectsForKeys ( MutableDictionary self,
  ... 
)
static

Definition at line 324 of file MutableDictionary.c.

324 {
325
326 va_list args;
327 va_start(args, self);
328
329 while (true) {
330
331 ident obj = va_arg(args, ident);
332 if (obj) {
333 ident key = va_arg(args, ident);
334 $(self, setObjectForKey, obj, key);
335 } else {
336 break;
337 }
338 }
339
340 va_end(args);
341}