Make dictionary functions static and include the .c file

This commit is contained in:
Pieter Noordhuis 2011-01-14 12:07:24 +01:00
parent 7adfef1680
commit c6b8bd77c0
5 changed files with 45 additions and 99 deletions

View File

@ -2,7 +2,7 @@
# Copyright (C) 2010 Salvatore Sanfilippo <antirez at gmail dot com> # Copyright (C) 2010 Salvatore Sanfilippo <antirez at gmail dot com>
# This file is released under the BSD license, see the COPYING file # This file is released under the BSD license, see the COPYING file
OBJ = net.o hiredis.o sds.o async.o dict.o OBJ = net.o hiredis.o sds.o async.o
BINS = hiredis-example hiredis-test BINS = hiredis-example hiredis-test
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
@ -45,11 +45,10 @@ all: ${DYLIBNAME} ${BINS}
# Deps (use make dep to generate this) # Deps (use make dep to generate this)
net.o: net.c fmacros.h net.h net.o: net.c fmacros.h net.h
async.o: async.c async.h hiredis.h sds.h util.h async.o: async.c async.h hiredis.h sds.h util.h dict.c dict.h
example.o: example.c hiredis.h example.o: example.c hiredis.h
hiredis.o: hiredis.c hiredis.h net.h sds.h util.h hiredis.o: hiredis.c hiredis.h net.h sds.h util.h
sds.o: sds.c sds.h sds.o: sds.c sds.h
dict.o: dict.c dict.h
test.o: test.c hiredis.h test.o: test.c hiredis.h
${DYLIBNAME}: ${OBJ} ${DYLIBNAME}: ${OBJ}

View File

@ -34,6 +34,7 @@
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include "async.h" #include "async.h"
#include "dict.c"
#include "sds.h" #include "sds.h"
#include "util.h" #include "util.h"

View File

@ -32,13 +32,13 @@
#ifndef __HIREDIS_ASYNC_H #ifndef __HIREDIS_ASYNC_H
#define __HIREDIS_ASYNC_H #define __HIREDIS_ASYNC_H
#include "hiredis.h" #include "hiredis.h"
#include "dict.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ struct redisAsyncContext; /* need forward declaration of redisAsyncContext */
struct dict; /* dictionary header is included in async.c */
/* Reply callback prototype and container */ /* Reply callback prototype and container */
typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*);
@ -95,8 +95,8 @@ typedef struct redisAsyncContext {
/* Subscription callbacks */ /* Subscription callbacks */
struct { struct {
redisCallbackList invalid; redisCallbackList invalid;
dict *channels; struct dict *channels;
dict *patterns; struct dict *patterns;
} sub; } sub;
} redisAsyncContext; } redisAsyncContext;

104
dict.c
View File

@ -50,7 +50,7 @@ static int _dictInit(dict *ht, dictType *type, void *privDataPtr);
/* Generic hash function (a popular one from Bernstein). /* Generic hash function (a popular one from Bernstein).
* I tested a few and this was the best. */ * I tested a few and this was the best. */
unsigned int dictGenHashFunction(const unsigned char *buf, int len) { static unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
unsigned int hash = 5381; unsigned int hash = 5381;
while (len--) while (len--)
@ -70,31 +70,22 @@ static void _dictReset(dict *ht) {
} }
/* Create a new hash table */ /* Create a new hash table */
dict *dictCreate(dictType *type, void *privDataPtr) { static dict *dictCreate(dictType *type, void *privDataPtr) {
dict *ht = malloc(sizeof(*ht)); dict *ht = malloc(sizeof(*ht));
_dictInit(ht,type,privDataPtr); _dictInit(ht,type,privDataPtr);
return ht; return ht;
} }
/* Initialize the hash table */ /* Initialize the hash table */
int _dictInit(dict *ht, dictType *type, void *privDataPtr) { static int _dictInit(dict *ht, dictType *type, void *privDataPtr) {
_dictReset(ht); _dictReset(ht);
ht->type = type; ht->type = type;
ht->privdata = privDataPtr; ht->privdata = privDataPtr;
return DICT_OK; return DICT_OK;
} }
/* Resize the table to the minimal size that contains all the elements,
* but with the invariant of a USER/BUCKETS ration near to <= 1 */
int dictResize(dict *ht) {
int minimal = ht->used;
if (minimal < DICT_HT_INITIAL_SIZE)
minimal = DICT_HT_INITIAL_SIZE;
return dictExpand(ht, minimal);
}
/* Expand or create the hashtable */ /* Expand or create the hashtable */
int dictExpand(dict *ht, unsigned long size) { static int dictExpand(dict *ht, unsigned long size) {
dict n; /* the new hashtable */ dict n; /* the new hashtable */
unsigned long realsize = _dictNextPower(size), i; unsigned long realsize = _dictNextPower(size), i;
@ -141,7 +132,7 @@ int dictExpand(dict *ht, unsigned long size) {
} }
/* Add an element to the target hash table */ /* Add an element to the target hash table */
int dictAdd(dict *ht, void *key, void *val) { static int dictAdd(dict *ht, void *key, void *val) {
int index; int index;
dictEntry *entry; dictEntry *entry;
@ -166,7 +157,7 @@ int dictAdd(dict *ht, void *key, void *val) {
* Return 1 if the key was added from scratch, 0 if there was already an * Return 1 if the key was added from scratch, 0 if there was already an
* element with such key and dictReplace() just performed a value update * element with such key and dictReplace() just performed a value update
* operation. */ * operation. */
int dictReplace(dict *ht, void *key, void *val) { static int dictReplace(dict *ht, void *key, void *val) {
dictEntry *entry, auxentry; dictEntry *entry, auxentry;
/* Try to add the element. If the key /* Try to add the element. If the key
@ -188,47 +179,38 @@ int dictReplace(dict *ht, void *key, void *val) {
} }
/* Search and remove an element */ /* Search and remove an element */
static int dictGenericDelete(dict *ht, const void *key, int nofree) { static int dictDelete(dict *ht, const void *key) {
unsigned int h; unsigned int h;
dictEntry *he, *prevHe; dictEntry *de, *prevde;
if (ht->size == 0) if (ht->size == 0)
return DICT_ERR; return DICT_ERR;
h = dictHashKey(ht, key) & ht->sizemask; h = dictHashKey(ht, key) & ht->sizemask;
he = ht->table[h]; de = ht->table[h];
prevHe = NULL; prevde = NULL;
while(he) { while(de) {
if (dictCompareHashKeys(ht, key, he->key)) { if (dictCompareHashKeys(ht,key,de->key)) {
/* Unlink the element from the list */ /* Unlink the element from the list */
if (prevHe) if (prevde)
prevHe->next = he->next; prevde->next = de->next;
else else
ht->table[h] = he->next; ht->table[h] = de->next;
if (!nofree) {
dictFreeEntryKey(ht, he); dictFreeEntryKey(ht,de);
dictFreeEntryVal(ht, he); dictFreeEntryVal(ht,de);
} free(de);
free(he);
ht->used--; ht->used--;
return DICT_OK; return DICT_OK;
} }
prevHe = he; prevde = de;
he = he->next; de = de->next;
} }
return DICT_ERR; /* not found */ return DICT_ERR; /* not found */
} }
int dictDelete(dict *ht, const void *key) {
return dictGenericDelete(ht,key,0);
}
int dictDeleteNoFree(dict *ht, const void *key) {
return dictGenericDelete(ht,key,1);
}
/* Destroy an entire hash table */ /* Destroy an entire hash table */
int _dictClear(dict *ht) { static int _dictClear(dict *ht) {
unsigned long i; unsigned long i;
/* Free all the elements */ /* Free all the elements */
@ -253,12 +235,12 @@ int _dictClear(dict *ht) {
} }
/* Clear & Release the hash table */ /* Clear & Release the hash table */
void dictRelease(dict *ht) { static void dictRelease(dict *ht) {
_dictClear(ht); _dictClear(ht);
free(ht); free(ht);
} }
dictEntry *dictFind(dict *ht, const void *key) { static dictEntry *dictFind(dict *ht, const void *key) {
dictEntry *he; dictEntry *he;
unsigned int h; unsigned int h;
@ -273,7 +255,7 @@ dictEntry *dictFind(dict *ht, const void *key) {
return NULL; return NULL;
} }
dictIterator *dictGetIterator(dict *ht) { static dictIterator *dictGetIterator(dict *ht) {
dictIterator *iter = malloc(sizeof(*iter)); dictIterator *iter = malloc(sizeof(*iter));
iter->ht = ht; iter->ht = ht;
@ -283,7 +265,7 @@ dictIterator *dictGetIterator(dict *ht) {
return iter; return iter;
} }
dictEntry *dictNext(dictIterator *iter) { static dictEntry *dictNext(dictIterator *iter) {
while (1) { while (1) {
if (iter->entry == NULL) { if (iter->entry == NULL) {
iter->index++; iter->index++;
@ -303,38 +285,10 @@ dictEntry *dictNext(dictIterator *iter) {
return NULL; return NULL;
} }
void dictReleaseIterator(dictIterator *iter) { static void dictReleaseIterator(dictIterator *iter) {
free(iter); free(iter);
} }
/* Return a random entry from the hash table. Useful to
* implement randomized algorithms */
dictEntry *dictGetRandomKey(dict *ht) {
dictEntry *he;
unsigned int h;
int listlen, listele;
if (ht->used == 0) return NULL;
do {
h = random() & ht->sizemask;
he = ht->table[h];
} while(he == NULL);
/* Now we found a non empty bucket, but it is a linked
* list and we need to get a random element from the list.
* The only sane way to do so is to count the element and
* select a random index. */
listlen = 0;
while(he) {
he = he->next;
listlen++;
}
listele = random() % listlen;
he = ht->table[h];
while(listele--) he = he->next;
return he;
}
/* ------------------------- private functions ------------------------------ */ /* ------------------------- private functions ------------------------------ */
/* Expand the hash table if needed */ /* Expand the hash table if needed */
@ -382,7 +336,3 @@ static int _dictKeyIndex(dict *ht, const void *key) {
return h; return h;
} }
void dictEmpty(dict *ht) {
_dictClear(ht);
}

28
dict.h
View File

@ -1,4 +1,4 @@
/* Hash Tables Implementation. /* Hash table implementation.
* *
* This file implements in memory hash tables with insert/del/replace/find/ * This file implements in memory hash tables with insert/del/replace/find/
* get-random-element operations. Hash tables will auto resize if needed * get-random-element operations. Hash tables will auto resize if needed
@ -111,20 +111,16 @@ typedef struct dictIterator {
#define dictSize(ht) ((ht)->used) #define dictSize(ht) ((ht)->used)
/* API */ /* API */
dict *dictCreate(dictType *type, void *privDataPtr); static unsigned int dictGenHashFunction(const unsigned char *buf, int len);
int dictExpand(dict *ht, unsigned long size); static dict *dictCreate(dictType *type, void *privDataPtr);
int dictAdd(dict *ht, void *key, void *val); static int dictExpand(dict *ht, unsigned long size);
int dictReplace(dict *ht, void *key, void *val); static int dictAdd(dict *ht, void *key, void *val);
int dictDelete(dict *ht, const void *key); static int dictReplace(dict *ht, void *key, void *val);
int dictDeleteNoFree(dict *ht, const void *key); static int dictDelete(dict *ht, const void *key);
void dictRelease(dict *ht); static void dictRelease(dict *ht);
dictEntry * dictFind(dict *ht, const void *key); static dictEntry * dictFind(dict *ht, const void *key);
int dictResize(dict *ht); static dictIterator *dictGetIterator(dict *ht);
dictIterator *dictGetIterator(dict *ht); static dictEntry *dictNext(dictIterator *iter);
dictEntry *dictNext(dictIterator *iter); static void dictReleaseIterator(dictIterator *iter);
void dictReleaseIterator(dictIterator *iter);
dictEntry *dictGetRandomKey(dict *ht);
unsigned int dictGenHashFunction(const unsigned char *buf, int len);
void dictEmpty(dict *ht);
#endif /* __DICT_H */ #endif /* __DICT_H */