add string_table to manage container STAB data
This commit is contained in:
110
src/string-table.c
Normal file
110
src/string-table.c
Normal file
@@ -0,0 +1,110 @@
|
||||
#include "string-table.h"
|
||||
|
||||
#include <blue/core/hash.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct string_table_entry {
|
||||
b_btree_node e_hash_node;
|
||||
b_btree_node e_offset_node;
|
||||
size_t e_hash;
|
||||
size_t e_offset;
|
||||
char e_str[];
|
||||
};
|
||||
|
||||
B_BTREE_DEFINE_SIMPLE_INSERT(
|
||||
struct string_table_entry,
|
||||
e_hash_node,
|
||||
e_hash,
|
||||
put_string_by_hash)
|
||||
|
||||
B_BTREE_DEFINE_SIMPLE_INSERT(
|
||||
struct string_table_entry,
|
||||
e_offset_node,
|
||||
e_offset,
|
||||
put_string_by_offset)
|
||||
|
||||
struct string_table_entry *get_string(const b_btree *hash_tree, const char *s)
|
||||
{
|
||||
size_t key = b_hash_string(s);
|
||||
|
||||
b_btree_node *cur = hash_tree->b_root;
|
||||
while (cur) {
|
||||
struct string_table_entry *cur_node
|
||||
= b_unbox(struct string_table_entry, cur, e_hash_node);
|
||||
|
||||
if (key == cur_node->e_hash && !strcmp(s, cur_node->e_str)) {
|
||||
return cur_node;
|
||||
}
|
||||
|
||||
if (key >= cur_node->e_hash) {
|
||||
cur = b_btree_right(cur);
|
||||
} else {
|
||||
cur = b_btree_left(cur);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct string_table_entry *create_entry(const char *s)
|
||||
{
|
||||
struct string_table_entry *out = NULL;
|
||||
|
||||
size_t s_len = strlen(s);
|
||||
size_t entry_len = s_len + 1 + sizeof *out;
|
||||
|
||||
out = malloc(entry_len);
|
||||
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, entry_len);
|
||||
memcpy(out->e_str, s, s_len);
|
||||
|
||||
out->e_hash = b_hash_string(s);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void string_table_init(struct string_table *out)
|
||||
{
|
||||
memset(out, 0x0, sizeof *out);
|
||||
}
|
||||
|
||||
void string_table_finish(struct string_table *tab)
|
||||
{
|
||||
b_btree_iterator it;
|
||||
b_btree_iterator_begin(&tab->s_hash_tree, &it);
|
||||
|
||||
while (b_btree_iterator_is_valid(&it)) {
|
||||
struct string_table_entry *entry = b_unbox(
|
||||
struct string_table_entry,
|
||||
it.node,
|
||||
e_hash_node);
|
||||
b_btree_iterator_erase(&it);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
free(tab);
|
||||
}
|
||||
|
||||
size_t string_table_get(struct string_table *tab, const char *s)
|
||||
{
|
||||
struct string_table_entry *entry = get_string(&tab->s_hash_tree, s);
|
||||
if (entry) {
|
||||
return entry->e_offset;
|
||||
}
|
||||
|
||||
entry = create_entry(s);
|
||||
|
||||
entry->e_offset = tab->s_next_offset;
|
||||
|
||||
tab->s_next_offset += strlen(s) + 1;
|
||||
|
||||
put_string_by_hash(&tab->s_hash_tree, entry);
|
||||
put_string_by_offset(&tab->s_offset_tree, entry);
|
||||
|
||||
return entry->e_offset;
|
||||
}
|
||||
17
src/string-table.h
Normal file
17
src/string-table.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef STRING_TABLE_H_
|
||||
#define STRING_TABLE_H_
|
||||
|
||||
#include <blue/core/btree.h>
|
||||
|
||||
struct string_table {
|
||||
b_btree s_hash_tree;
|
||||
b_btree s_offset_tree;
|
||||
size_t s_next_offset;
|
||||
};
|
||||
|
||||
extern void string_table_init(struct string_table *out);
|
||||
extern void string_table_finish(struct string_table *tab);
|
||||
|
||||
extern size_t string_table_get(struct string_table *tab, const char *s);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user