c_cpp C中的哈希表环境类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp C中的哈希表环境类相关的知识,希望对你有一定的参考价值。
#ifndef XEN_ENV_H
#define XEN_ENV_H
#ifdef __cplusplus
extern "C" {
#endif
//container structure for variable environment
struct XenEnvBox
{
char* key;
XenObject* obj;
struct XenEnvBox* link;
};
typedef struct XenEnvBox XenEnvBox;
#define XenEnvBox_SET_NULL_OL(xeb) do {\
xeb->obj = NULL; \
xeb->key = NULL; \
xeb->link = NULL;}while(0)
#define XenEnvBox_SET_NULL_O(xeb) xeb->obj = NULL
#define XenEnvBox_SET_NULL_L(xeb) xeb->link = NULL
#define XenEnvBox_IS_NULL_O(xeb) xeb->obj == NULL
#define XenEnvBox_IS_NULL_L(xeb) xeb->link == NULL
#define XenEnvBox_FIND_EMPTY(xeb) while(xeb->link != NULL) xeb = xeb->link
#define XenEnvBox_KEY_CMP(key, hskey) hskey != NULL && (strcmp(key, hskey) == 0)
XenEnvBox* XenEnvBox_new(char* key, XenObject* xo);
void XenEnvBox_set_null(XenEnvBox* xeb);
void XenEnvBox_add_obj(XenEnvBox* xeb, char* key, XenObject* xo);
void XenEnvBox_del(XenEnvBox* xeb);
#define XenEnv_SIZE 5000
#define XenEnv_LOAD_FACTOR(xenv) xenv->ocount / 5000
typedef struct
{
XenEnvBox* table;
int size; //current size
int icount; //total items
int ocount; //buckets occupied
} XenEnv;
XenEnv* XenEnv_new();
//primary hash function for env
unsigned long XenEnv_hash(char *str);
XenObject* XenEnv_insert(XenEnv* xe, char* key, XenObject* xo);
XenObject* XenEnv_find(XenEnv* xe, char* key);
void XenEnv_del(XenEnv* xe, char* key);
void XenEnv_expand(XenEnv* xe);
#ifdef __cplusplus
}
#endif
#include "Xenon.h"
XenEnvBox* XenEnvBox_new(char* key, XenObject* xo)
{
XenEnvBox* xeb = malloc(sizeof(XenEnvBox));
xeb->key = malloc(strlen(key));
strcpy(xeb->key, key);
xeb->obj = xo;
xeb->link = NULL;
return xeb;
}
//once a hash slot is found, either chains or inserts the pair into this box
void XenEnvBox_add_obj(XenEnvBox* xeb, char* key, XenObject* xo)
{
if(xeb->key == NULL)
{
xeb->obj = xo;
xeb->key = malloc(strlen(key));
strcpy(xeb->key, key);
}
else
{
if(XenEnvBox_KEY_CMP(key, xeb->key))
{
xeb->obj = xo;
return;
}
while(xeb->link != NULL)
{
xeb = xeb->link;
//checks if name is reassigned, and changes XenObject pointer
if(XenEnvBox_KEY_CMP(key, xeb->key))
{
xeb->obj = xo;
return;
}
}
//creates new chain link if space occupied
xeb->link = XenEnvBox_new(key, xo);
}
}
//deletes entire xenenvbox
void XenEnvBox_del(XenEnvBox* xeb)
{
if(xeb->key != NULL) free(xeb->key);
if(xeb->obj != NULL) XenGc_del(xeb->obj);
if(xeb->link != NULL) XenEnvBox_del(xeb->link);
free(xeb);
}
XenEnv* XenEnv_new()
{
XenEnv* env = malloc(sizeof(XenEnv));
env->ocount = 0;
env->icount = 0;
env->size = XenEnv_SIZE;
env->table = malloc(sizeof(XenEnvBox) * XenEnv_SIZE);
return env;
}
unsigned long
XenEnv_hash(char *str)
{
unsigned long hash = 5381;
int c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
XenObject* XenEnv_insert(XenEnv* xe, char* key, XenObject* xo)
{
if(xe->icount > (xe->size - 100)) XenEnv_expand(xe);
XenEnvBox* hashslot = (xe->table) + (XenEnv_hash(key) % xe->size);
if(XenEnvBox_IS_NULL_O(hashslot)) xe->ocount++;
XenEnvBox_add_obj(hashslot, key, xo);
xe->icount++;
return xo;
}
//finds a variable in the table
XenObject* XenEnv_find(XenEnv* xe, char* key)
{
XenEnvBox* hashslot = (xe->table) + (XenEnv_hash(key) % xe->size);
while(hashslot != NULL)
{
if(XenEnvBox_KEY_CMP(key, hashslot->key))
{
return hashslot->obj;
}
else
{
hashslot = hashslot->link;
}
}
//todo: decide if error handling
return (XenObject*)XenNone_new();
}
//deletes a hashslots data and key
void XenEnv_del(XenEnv* xe, char* key)
{
XenEnvBox* hashslot = (xe->table) + (XenEnv_hash(key) % xe->size);
if(XenEnvBox_KEY_CMP(key, hashslot->key))
{
free(hashslot->key);
hashslot->key = NULL;
XenGc_del(hashslot->obj);
hashslot->obj = NULL;
xe->ocount--;
xe->icount--;
}
//works off the link incase of downstream chain items
else while(hashslot->link != NULL)
{
if(XenEnvBox_KEY_CMP(key, hashslot->link->key))
{
if(hashslot->link->key != NULL) free(hashslot->link->key);
if(hashslot->link->obj != NULL) XenGc_del(hashslot->link->obj);
free(hashslot->link);
xe->icount--;
hashslot->link = hashslot->link->link;
}
hashslot = hashslot->link;
}
}
//expands the variable table size
void XenEnv_expand(XenEnv* xe)
{
xe->size += xe->size;
xe->table = realloc(xe->table, sizeof(XenEnvBox) * xe->size);
}
#endif
以上是关于c_cpp C中的哈希表环境类的主要内容,如果未能解决你的问题,请参考以下文章