| 25 |
#include <sys/shm.h> |
#include <sys/shm.h> |
| 26 |
#include <sys/ipc.h> |
#include <sys/ipc.h> |
| 27 |
|
|
|
#define TRIE_NODE_PER_POOL 10000 |
|
|
|
|
| 28 |
struct trie_node_pool_t |
struct trie_node_pool_t |
| 29 |
{ |
{ |
| 30 |
int shmid; |
int shmid; |
| 31 |
TRIE_NODE trie_nodes[TRIE_NODE_PER_POOL]; |
int node_count_limit; |
|
TRIE_NODE *p_node_free_list; |
|
| 32 |
int node_count; |
int node_count; |
| 33 |
|
TRIE_NODE *p_node_free_list; |
| 34 |
}; |
}; |
| 35 |
typedef struct trie_node_pool_t TRIE_NODE_POOL; |
typedef struct trie_node_pool_t TRIE_NODE_POOL; |
| 36 |
|
|
| 37 |
static TRIE_NODE_POOL *p_trie_node_pool; |
static TRIE_NODE_POOL *p_trie_node_pool; |
| 38 |
|
|
| 39 |
int trie_dict_init(const char *filename) |
int trie_dict_init(const char *filename, int node_count_limit) |
| 40 |
{ |
{ |
| 41 |
int shmid; |
int shmid; |
| 42 |
int proj_id; |
int proj_id; |
| 43 |
key_t key; |
key_t key; |
| 44 |
size_t size; |
size_t size; |
| 45 |
void *p_shm; |
void *p_shm; |
| 46 |
|
TRIE_NODE *p_trie_nodes; |
| 47 |
int i; |
int i; |
| 48 |
|
|
| 49 |
if (p_trie_node_pool != NULL) |
if (p_trie_node_pool != NULL) |
| 52 |
return -1; |
return -1; |
| 53 |
} |
} |
| 54 |
|
|
| 55 |
|
if (node_count_limit <= 0 || node_count_limit > TRIE_NODE_PER_POOL) |
| 56 |
|
{ |
| 57 |
|
log_error("trie_dict_init(%d) error: invalid node_count_limit\n", node_count_limit); |
| 58 |
|
return -1; |
| 59 |
|
} |
| 60 |
|
|
| 61 |
// Allocate shared memory |
// Allocate shared memory |
| 62 |
proj_id = (int)(time(NULL) % getpid()); |
proj_id = (int)(time(NULL) % getpid()); |
| 63 |
key = ftok(filename, proj_id); |
key = ftok(filename, proj_id); |
| 67 |
return -2; |
return -2; |
| 68 |
} |
} |
| 69 |
|
|
| 70 |
size = sizeof(TRIE_NODE_POOL); |
size = sizeof(TRIE_NODE_POOL) + sizeof(TRIE_NODE) * (size_t)node_count_limit; |
| 71 |
shmid = shmget(key, size, IPC_CREAT | IPC_EXCL | 0600); |
shmid = shmget(key, size, IPC_CREAT | IPC_EXCL | 0600); |
| 72 |
if (shmid == -1) |
if (shmid == -1) |
| 73 |
{ |
{ |
| 83 |
|
|
| 84 |
p_trie_node_pool = p_shm; |
p_trie_node_pool = p_shm; |
| 85 |
p_trie_node_pool->shmid = shmid; |
p_trie_node_pool->shmid = shmid; |
| 86 |
|
p_trie_node_pool->node_count_limit = node_count_limit; |
| 87 |
p_trie_node_pool->node_count = 0; |
p_trie_node_pool->node_count = 0; |
| 88 |
|
|
| 89 |
p_trie_node_pool->p_node_free_list = &(p_trie_node_pool->trie_nodes[0]); |
p_trie_nodes = p_shm + sizeof(TRIE_NODE_POOL); |
| 90 |
for (i = 0; i < TRIE_NODE_PER_POOL - 1; i++) |
p_trie_node_pool->p_node_free_list = &(p_trie_nodes[0]); |
| 91 |
|
for (i = 0; i < node_count_limit - 1; i++) |
| 92 |
{ |
{ |
| 93 |
p_trie_node_pool->trie_nodes[i].p_nodes[0] = &(p_trie_node_pool->trie_nodes[i + 1]); |
p_trie_nodes[i].p_nodes[0] = &(p_trie_nodes[i + 1]); |
| 94 |
} |
} |
| 95 |
p_trie_node_pool->trie_nodes[TRIE_NODE_PER_POOL - 1].p_nodes[0] = NULL; |
p_trie_nodes[node_count_limit - 1].p_nodes[0] = NULL; |
| 96 |
|
|
| 97 |
return 0; |
return 0; |
| 98 |
} |
} |
| 114 |
{ |
{ |
| 115 |
log_error("shmctl(shmid = %d, IPC_RMID) error (%d)\n", shmid, errno); |
log_error("shmctl(shmid = %d, IPC_RMID) error (%d)\n", shmid, errno); |
| 116 |
} |
} |
|
|
|
|
p_trie_node_pool = NULL; |
|
| 117 |
} |
} |
| 118 |
|
|
| 119 |
int set_trie_dict_shm_readonly(void) |
int set_trie_dict_shm_readonly(void) |
| 149 |
log_error("shmdt() error (%d)\n", errno); |
log_error("shmdt() error (%d)\n", errno); |
| 150 |
return -1; |
return -1; |
| 151 |
} |
} |
| 152 |
|
|
| 153 |
p_trie_node_pool = NULL; |
p_trie_node_pool = NULL; |
| 154 |
|
|
| 155 |
return 0; |
return 0; |
| 165 |
p_trie_node_pool->p_node_free_list = p_dict->p_nodes[0]; |
p_trie_node_pool->p_node_free_list = p_dict->p_nodes[0]; |
| 166 |
|
|
| 167 |
bzero(p_dict, sizeof(*p_dict)); |
bzero(p_dict, sizeof(*p_dict)); |
| 168 |
|
|
| 169 |
|
p_trie_node_pool->node_count++; |
| 170 |
|
} |
| 171 |
|
else if (p_trie_node_pool != NULL) |
| 172 |
|
{ |
| 173 |
|
log_error("trie_dict_create() error: node depleted %d >= %d\n", p_trie_node_pool->node_count, p_trie_node_pool->node_count_limit); |
| 174 |
} |
} |
| 175 |
|
|
| 176 |
return p_dict; |
return p_dict; |
| 195 |
|
|
| 196 |
p_dict->p_nodes[0] = p_trie_node_pool->p_node_free_list; |
p_dict->p_nodes[0] = p_trie_node_pool->p_node_free_list; |
| 197 |
p_trie_node_pool->p_node_free_list = p_dict; |
p_trie_node_pool->p_node_free_list = p_dict; |
| 198 |
|
|
| 199 |
|
p_trie_node_pool->node_count--; |
| 200 |
} |
} |
| 201 |
|
|
| 202 |
int trie_dict_set(TRIE_NODE *p_dict, const char *key, int64_t value) |
int trie_dict_set(TRIE_NODE *p_dict, const char *key, int64_t value) |
| 365 |
|
|
| 366 |
_trie_dict_traverse(p_dict, cb, key, 0); |
_trie_dict_traverse(p_dict, cb, key, 0); |
| 367 |
} |
} |
| 368 |
|
|
| 369 |
|
int trie_dict_used_nodes(void) |
| 370 |
|
{ |
| 371 |
|
return (p_trie_node_pool == NULL ? -1 : p_trie_node_pool->node_count); |
| 372 |
|
} |