Remove old db files
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
This commit is contained in:
158
src/db.c
158
src/db.c
@@ -1,158 +0,0 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "db.h"
|
||||
#include "str.h"
|
||||
|
||||
#define CBIT(X) (1 & (intptr_t)(X))
|
||||
#define CBIT_PTR(X) (uint8_t *)(1 | (intptr_t)(X))
|
||||
#define CBIT_NODE(X) (struct node *)(1 ^ (intptr_t)(X))
|
||||
|
||||
struct node {
|
||||
uint8_t *child[2];
|
||||
uint32_t point;
|
||||
};
|
||||
|
||||
_pure_ static inline size_t
|
||||
db_size(const uint8_t *a)
|
||||
{
|
||||
return (a[0] ?: str_len((char *)a + 1, 4096)) + 1;
|
||||
}
|
||||
|
||||
_pure_ static inline size_t
|
||||
db_cmp(const uint8_t *a, const uint8_t *b)
|
||||
{
|
||||
const size_t size = a[0];
|
||||
|
||||
if (size != b[0])
|
||||
return 1;
|
||||
|
||||
if (!size) {
|
||||
size_t i = str_cmp((char *)a + 1, (char *)b + 1);
|
||||
return i ? i + 1 : 0;
|
||||
}
|
||||
|
||||
for (size_t i = 1; i <= size; i++) {
|
||||
if (a[i] != b[i])
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_pure_ static inline int
|
||||
db_dir(const uint32_t point, uint8_t *data, const size_t size)
|
||||
{
|
||||
const size_t pos = point >> 8;
|
||||
|
||||
if (pos >= size)
|
||||
return 0;
|
||||
|
||||
return ((point | data[pos]) & 255) == 255;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
db_search(uint8_t **p, uint8_t *data)
|
||||
{
|
||||
if (_0_(!*p))
|
||||
return NULL;
|
||||
|
||||
uint8_t *r = *p;
|
||||
const size_t size = db_size(data);
|
||||
|
||||
while (CBIT(r)) {
|
||||
struct node *node = CBIT_NODE(r);
|
||||
r = node->child[db_dir(node->point, data, size)];
|
||||
}
|
||||
|
||||
if (!db_cmp(r, data))
|
||||
return r;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
db_insert(uint8_t **p, uint8_t *data)
|
||||
{
|
||||
if (_0_(CBIT(data)))
|
||||
return NULL;
|
||||
|
||||
if (_0_(!*p)) {
|
||||
*p = data;
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t *r = *p;
|
||||
size_t size = db_size(data);
|
||||
|
||||
while (CBIT(r)) {
|
||||
struct node *node = CBIT_NODE(r);
|
||||
r = node->child[db_dir(node->point, data, size)];
|
||||
}
|
||||
|
||||
const size_t diff = db_cmp(r, data);
|
||||
|
||||
if (_0_(!diff))
|
||||
return r;
|
||||
|
||||
const size_t pos = diff - 1;
|
||||
const uint8_t mask = ~((1u << 31) >> CLZ(r[pos] ^ data[pos]));
|
||||
const size_t point = (pos << 8) | mask;
|
||||
|
||||
while (CBIT(*p)) {
|
||||
struct node *node = CBIT_NODE(*p);
|
||||
|
||||
if (node->point > point)
|
||||
break;
|
||||
|
||||
p = node->child + db_dir(node->point, data, size);
|
||||
}
|
||||
|
||||
struct node *node = malloc(sizeof(struct node));
|
||||
|
||||
if (_0_(!node))
|
||||
return NULL;
|
||||
|
||||
const int dir = (mask | r[pos]) == 255;
|
||||
|
||||
node->child[dir] = *p;
|
||||
node->child[1 - dir] = data;
|
||||
node->point = point;
|
||||
|
||||
*p = CBIT_PTR(node);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
db_remove(uint8_t **p, uint8_t *data)
|
||||
{
|
||||
if (_0_(!*p))
|
||||
return NULL;
|
||||
|
||||
const size_t size = db_size(data);
|
||||
|
||||
uint8_t **p_old = NULL;
|
||||
struct node *node = NULL;
|
||||
int dir = 0;
|
||||
|
||||
while (CBIT(*p)) {
|
||||
p_old = p;
|
||||
node = CBIT_NODE(*p);
|
||||
dir = db_dir(node->point, data, size);
|
||||
p = node->child + dir;
|
||||
}
|
||||
|
||||
if (_0_(db_cmp(data, *p)))
|
||||
return NULL;
|
||||
|
||||
uint8_t *r = *p;
|
||||
|
||||
if (p_old) {
|
||||
*p_old = node->child[1 - dir];
|
||||
free(node);
|
||||
} else {
|
||||
*p = NULL;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
Reference in New Issue
Block a user