mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
db: turn generated queries array into a simple hash table.
Since we have that functionality, let's use it. Also, make table const. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
53c9d9853d
commit
fcf3d0ce6c
@ -27,6 +27,8 @@ class Rewriter(object):
|
||||
|
||||
def rewrite(self, queries):
|
||||
for i, q in enumerate(queries):
|
||||
if q['name'] is None:
|
||||
continue
|
||||
org = q['query']
|
||||
queries[i]['query'] = self.rewrite_single(org)
|
||||
eprint("Rewritten statement\n\tfrom {}\n\t to {}".format(org, q['query']))
|
||||
@ -136,10 +138,11 @@ static const struct sqlname_map ${colname}[] = {
|
||||
|
||||
% endfor
|
||||
|
||||
struct db_query db_${f}_queries[] = {
|
||||
const struct db_query db_${f}_queries[] = {
|
||||
|
||||
% for elem in queries:
|
||||
{
|
||||
% if elem['name'] is not None:
|
||||
.name = "${elem['name']}",
|
||||
.query = "${elem['query']}",
|
||||
.placeholders = ${elem['placeholders']},
|
||||
@ -147,19 +150,32 @@ struct db_query db_${f}_queries[] = {
|
||||
% if elem['colnames'] is not None:
|
||||
.colnames = ${elem['colnames']},
|
||||
.num_colnames = ARRAY_SIZE(${elem['colnames']}),
|
||||
% endif
|
||||
% endif
|
||||
},
|
||||
% endfor
|
||||
};
|
||||
|
||||
#define DB_${f.upper()}_QUERY_COUNT ${len(queries)}
|
||||
|
||||
#endif /* HAVE_${f.upper()} */
|
||||
|
||||
#endif /* LIGHTNINGD_WALLET_GEN_DB_${f.upper()} */
|
||||
""")
|
||||
|
||||
|
||||
def queries_htable(queries):
|
||||
# Converts a list of queries into a hash table.
|
||||
tablesize = len(queries) * 2 - 1
|
||||
htable = [{'name': None}] * tablesize
|
||||
|
||||
for q in queries:
|
||||
pos = hash_djb2(q['name']) % tablesize
|
||||
while htable[pos]['name'] is not None:
|
||||
pos = (pos + 1) % tablesize
|
||||
htable[pos] = q
|
||||
|
||||
return htable
|
||||
|
||||
|
||||
def extract_queries(pofile):
|
||||
# Given a po-file, extract all queries and their associated names, and
|
||||
# return them as a list.
|
||||
@ -204,7 +220,7 @@ def extract_queries(pofile):
|
||||
'readonly': "true" if is_select else "false",
|
||||
'colnames': colnames,
|
||||
})
|
||||
return colhtables, queries
|
||||
return colhtables, queries_htable(queries)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
33
wallet/db.c
33
wallet/db.c
@ -903,12 +903,20 @@ static void db_stmt_free(struct db_stmt *stmt)
|
||||
assert(stmt->inner_stmt == NULL);
|
||||
}
|
||||
|
||||
/* Matches the hash function used in devtools/sql-rewrite.py */
|
||||
static u32 hash_djb2(const char *str)
|
||||
{
|
||||
u32 hash = 5381;
|
||||
for (size_t i = 0; str[i]; i++)
|
||||
hash = ((hash << 5) + hash) ^ str[i];
|
||||
return hash;
|
||||
}
|
||||
|
||||
struct db_stmt *db_prepare_v2_(const char *location, struct db *db,
|
||||
const char *query_id)
|
||||
{
|
||||
struct db_stmt *stmt = tal(db, struct db_stmt);
|
||||
size_t num_slots;
|
||||
stmt->query = NULL;
|
||||
size_t num_slots, pos;
|
||||
|
||||
/* Normalize query_id paths, because unit tests are compiled with this
|
||||
* prefix. */
|
||||
@ -920,14 +928,16 @@ struct db_stmt *db_prepare_v2_(const char *location, struct db *db,
|
||||
"transaction: %s", location);
|
||||
|
||||
/* Look up the query by its ID */
|
||||
for (size_t i = 0; i < db->config->num_queries; i++) {
|
||||
if (streq(query_id, db->config->queries[i].name)) {
|
||||
stmt->query = &db->config->queries[i];
|
||||
pos = hash_djb2(query_id) % db->config->query_table_size;
|
||||
for (;;) {
|
||||
if (!db->config->query_table[pos].name)
|
||||
fatal("Could not resolve query %s", query_id);
|
||||
if (streq(query_id, db->config->query_table[pos].name)) {
|
||||
stmt->query = &db->config->query_table[pos];
|
||||
break;
|
||||
}
|
||||
pos = (pos + 1) % db->config->query_table_size;
|
||||
}
|
||||
if (stmt->query == NULL)
|
||||
fatal("Could not resolve query %s", query_id);
|
||||
|
||||
num_slots = stmt->query->placeholders;
|
||||
/* Allocate the slots for placeholders/bindings, zeroed next since
|
||||
@ -2335,15 +2345,6 @@ const char **db_changes(struct db *db)
|
||||
return db->changes;
|
||||
}
|
||||
|
||||
/* Matches the hash function used in devtools/sql-rewrite.py */
|
||||
static u32 hash_djb2(const char *str)
|
||||
{
|
||||
u32 hash = 5381;
|
||||
for (size_t i = 0; str[i]; i++)
|
||||
hash = ((hash << 5) + hash) ^ str[i];
|
||||
return hash;
|
||||
}
|
||||
|
||||
size_t db_query_colnum(const struct db_stmt *stmt,
|
||||
const char *colname)
|
||||
{
|
||||
|
@ -84,7 +84,7 @@ struct db_stmt {
|
||||
struct db *db;
|
||||
|
||||
/* Which SQL statement are we trying to execute? */
|
||||
struct db_query *query;
|
||||
const struct db_query *query;
|
||||
|
||||
/* Which parameters are we binding to the statement? */
|
||||
struct db_binding *bindings;
|
||||
@ -109,8 +109,8 @@ struct db_stmt {
|
||||
|
||||
struct db_config {
|
||||
const char *name;
|
||||
struct db_query *queries;
|
||||
size_t num_queries;
|
||||
const struct db_query *query_table;
|
||||
size_t query_table_size;
|
||||
|
||||
/* Function used to execute a statement that doesn't result in a
|
||||
* response. */
|
||||
|
@ -275,8 +275,8 @@ static bool db_postgres_vacuum(struct db *db)
|
||||
|
||||
struct db_config db_postgres_config = {
|
||||
.name = "postgres",
|
||||
.queries = db_postgres_queries,
|
||||
.num_queries = DB_POSTGRES_QUERY_COUNT,
|
||||
.query_table = db_postgres_queries,
|
||||
.query_table_size = ARRAY_SIZE(db_postgres_queries),
|
||||
.exec_fn = db_postgres_exec,
|
||||
.query_fn = db_postgres_query,
|
||||
.step_fn = db_postgres_step,
|
||||
|
@ -253,8 +253,8 @@ static bool db_sqlite3_vacuum(struct db *db)
|
||||
|
||||
struct db_config db_sqlite3_config = {
|
||||
.name = "sqlite3",
|
||||
.queries = db_sqlite3_queries,
|
||||
.num_queries = DB_SQLITE3_QUERY_COUNT,
|
||||
.query_table = db_sqlite3_queries,
|
||||
.query_table_size = ARRAY_SIZE(db_sqlite3_queries),
|
||||
.exec_fn = &db_sqlite3_exec,
|
||||
.query_fn = &db_sqlite3_query,
|
||||
.step_fn = &db_sqlite3_step,
|
||||
|
Loading…
Reference in New Issue
Block a user