C-HashMap實現

typedef struct _Entry {
    String key;
    void* value;
    struct _Entry* next;
} *Entry;

typedef struct _Map {
    Entry* table;
    int cap;
    int sz;
    int slotSz;
} *Map;

Map newMap(int cap);
void putElem(Map map, String key, void* value);
void* getElem(Map map, String key);
int containsKey(Map map, String key);
void* deleteElem(Map map, String key);
void releaseMap(Map map);

unsigned long hashcode(String key) {
    unsigned long h = 0;
    unsigned long g;
    for (int i = 0; i < key->len; i++) {
        h = (h << 4) + key->val[i];
        g = h & 0xF0000000L;
        if(g) h ^= g >> 24;
        h &= ~g;
    }
    return h ^ (h >> 16);
}

Entry newEntry(String key, void *value) {
    Entry e = (Entry)malloc(sizeof(struct _Entry));
    e->key = cloneString(key);
    e->value = value;
    e->next = NULL;
    return e;
}

Map newMap(int cap) {
    Map map = (Map) malloc(sizeof(struct _Map));
    map->table = (Entry*)malloc(cap * sizeof(Entry));
    memset(map->table, 0, cap * sizeof(Entry));
    map->cap = cap;
    map->sz = 0;
    map->slotSz = 0;
    return map;
}

void putElem(Map map, String key, void* value) {
    int idx = hashcode(key) % map->cap;
    Entry entry = map->table[idx], cur;
    if (entry == NULL) {
        entry = newEntry(key, value);
        map->table[idx] = entry;
        map->slotSz++;
    } else {
        do {
            if (equalString(entry->key, key)) {
                entry->value = value;
                return;
            }
            cur = entry;
        } while ((entry = entry->next) != NULL);
        cur->next = newEntry(key, value);
        cur->value = value;
    }
    map->sz++;
}

void* getElem(Map map, String key) {
    int idx = hashcode(key) % map->cap;
    Entry entry = map->table[idx];
    while (entry != NULL && !equalString(entry->key, key)) {
        entry = entry->next;
    }
    return entry == NULL ? NULL : entry->value;
}

int containsKey(Map map, String key) {
    int idx = hashcode(key) % map->cap;
    return map->table[idx] != NULL;
}

void* deleteElem(Map map, String key) {
    int idx = hashcode(key) % map->cap;
    Entry entry = map->table[idx], cur = NULL;
    while (entry != NULL && !equalString(entry->key, key)) {
        cur = entry;
        entry = entry->next;
    }
    if (entry != NULL) {
        void* ret = entry->value;
        if (cur != NULL) {
            cur->next = NULL;
        } else {
            map->table[idx] = NULL;
            map->slotSz--;
        }
        free(entry);
        map->sz--;
        return ret;
    } else {
        return NULL;
    }
}

void releaseMap(Map map) {
    Entry entry, next;
    for (int i = 0; i < map->cap; i++) {
        entry = map->table[i];
        while (entry != NULL) {
            next = entry->next;
            releaseString(entry->key);
            entry->next = NULL;
            entry->value = NULL;
            free(entry);
            entry = next;
        }
        map->table[i] = NULL;
    }
    free(map->table);
    map->table = NULL;
    free(map);
}
發佈了36 篇原創文章 · 獲贊 13 · 訪問量 6504
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章