forked from github/server
do not use a list to store several million entries.
This commit is contained in:
parent
28d75f7cfc
commit
710fcd0a08
2
clibs
2
clibs
|
@ -1 +1 @@
|
||||||
Subproject commit 147584ad70b220abf6a4e97ca76e785729b9ac32
|
Subproject commit 7eb6713ff73d29e67d2bc87fb037a9c738c2c512
|
|
@ -38,24 +38,39 @@ typedef struct order_data {
|
||||||
int _refcount;
|
int _refcount;
|
||||||
} order_data;
|
} order_data;
|
||||||
|
|
||||||
#include <selist.h>
|
#include <critbit.h>
|
||||||
|
|
||||||
static selist * orders;
|
static critbit_tree cb_orders = { 0 };
|
||||||
|
static int auto_id = 0;
|
||||||
|
|
||||||
|
struct cb_entry {
|
||||||
|
int id;
|
||||||
|
order_data *data;
|
||||||
|
};
|
||||||
|
|
||||||
order_data *load_data(int id) {
|
order_data *load_data(int id) {
|
||||||
|
void * match;
|
||||||
|
|
||||||
if (id > 0) {
|
if (id > 0) {
|
||||||
order_data * od = (order_data *)selist_get(orders, id - 1);
|
if (cb_find_prefix(&cb_orders, &id, sizeof(id), &match, 1, 0) > 0) {
|
||||||
|
struct cb_entry *ent = (struct cb_entry *)match;
|
||||||
|
order_data * od = ent->data;
|
||||||
++od->_refcount;
|
++od->_refcount;
|
||||||
return od;
|
return od;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_data(order_data *od) {
|
int save_data(order_data *od) {
|
||||||
if (od->_str) {
|
if (od->_str) {
|
||||||
|
struct cb_entry ent;
|
||||||
|
|
||||||
++od->_refcount;
|
++od->_refcount;
|
||||||
selist_push(&orders, od);
|
ent.id = ++auto_id;
|
||||||
return selist_length(orders);
|
ent.data = od;
|
||||||
|
cb_insert(&cb_orders, &ent, sizeof(ent));
|
||||||
|
return ent.id;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -69,18 +84,19 @@ static void release_data(order_data * data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_data_cb(void *entry) {
|
int free_data_cb(const void *match, const void *key, size_t keylen, void *udata) {
|
||||||
order_data *od = (order_data *)entry;
|
struct cb_entry * ent = (struct cb_entry *)match;
|
||||||
|
order_data *od = ent->data;
|
||||||
if (od->_refcount > 1) {
|
if (od->_refcount > 1) {
|
||||||
log_error("refcount=%d for order %s", od->_refcount, od->_str);
|
log_error("refcount=%d for order %d, %s", od->_refcount, ent->id, od->_str);
|
||||||
}
|
}
|
||||||
release_data(od);
|
release_data(od);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_data(void) {
|
void free_data(void) {
|
||||||
selist_foreach(orders, free_data_cb);
|
cb_foreach(&cb_orders, NULL, 0, free_data_cb, NULL);
|
||||||
selist_free(orders);
|
cb_clear(&cb_orders);
|
||||||
orders = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void replace_order(order ** dlist, order * orig, const order * src)
|
void replace_order(order ** dlist, order * orig, const order * src)
|
||||||
|
@ -276,7 +292,7 @@ static order *create_order_i(order *ord, keyword_t kwd, const char *sptr, bool p
|
||||||
while (isspace(*(unsigned char *)sptr)) ++sptr;
|
while (isspace(*(unsigned char *)sptr)) ++sptr;
|
||||||
|
|
||||||
od = create_data(kwd, sptr);
|
od = create_data(kwd, sptr);
|
||||||
ord->id = add_data(od);
|
ord->id = save_data(od);
|
||||||
release_data(od);
|
release_data(od);
|
||||||
|
|
||||||
return ord;
|
return ord;
|
||||||
|
|
Loading…
Reference in New Issue