mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-19 05:44:12 +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):
|
def rewrite(self, queries):
|
||||||
for i, q in enumerate(queries):
|
for i, q in enumerate(queries):
|
||||||
|
if q['name'] is None:
|
||||||
|
continue
|
||||||
org = q['query']
|
org = q['query']
|
||||||
queries[i]['query'] = self.rewrite_single(org)
|
queries[i]['query'] = self.rewrite_single(org)
|
||||||
eprint("Rewritten statement\n\tfrom {}\n\t to {}".format(org, q['query']))
|
eprint("Rewritten statement\n\tfrom {}\n\t to {}".format(org, q['query']))
|
||||||
@ -136,10 +138,11 @@ static const struct sqlname_map ${colname}[] = {
|
|||||||
|
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
struct db_query db_${f}_queries[] = {
|
const struct db_query db_${f}_queries[] = {
|
||||||
|
|
||||||
% for elem in queries:
|
% for elem in queries:
|
||||||
{
|
{
|
||||||
|
% if elem['name'] is not None:
|
||||||
.name = "${elem['name']}",
|
.name = "${elem['name']}",
|
||||||
.query = "${elem['query']}",
|
.query = "${elem['query']}",
|
||||||
.placeholders = ${elem['placeholders']},
|
.placeholders = ${elem['placeholders']},
|
||||||
@ -147,19 +150,32 @@ struct db_query db_${f}_queries[] = {
|
|||||||
% if elem['colnames'] is not None:
|
% if elem['colnames'] is not None:
|
||||||
.colnames = ${elem['colnames']},
|
.colnames = ${elem['colnames']},
|
||||||
.num_colnames = ARRAY_SIZE(${elem['colnames']}),
|
.num_colnames = ARRAY_SIZE(${elem['colnames']}),
|
||||||
|
% endif
|
||||||
% endif
|
% endif
|
||||||
},
|
},
|
||||||
% endfor
|
% endfor
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DB_${f.upper()}_QUERY_COUNT ${len(queries)}
|
|
||||||
|
|
||||||
#endif /* HAVE_${f.upper()} */
|
#endif /* HAVE_${f.upper()} */
|
||||||
|
|
||||||
#endif /* LIGHTNINGD_WALLET_GEN_DB_${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):
|
def extract_queries(pofile):
|
||||||
# Given a po-file, extract all queries and their associated names, and
|
# Given a po-file, extract all queries and their associated names, and
|
||||||
# return them as a list.
|
# return them as a list.
|
||||||
@ -204,7 +220,7 @@ def extract_queries(pofile):
|
|||||||
'readonly': "true" if is_select else "false",
|
'readonly': "true" if is_select else "false",
|
||||||
'colnames': colnames,
|
'colnames': colnames,
|
||||||
})
|
})
|
||||||
return colhtables, queries
|
return colhtables, queries_htable(queries)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
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);
|
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,
|
struct db_stmt *db_prepare_v2_(const char *location, struct db *db,
|
||||||
const char *query_id)
|
const char *query_id)
|
||||||
{
|
{
|
||||||
struct db_stmt *stmt = tal(db, struct db_stmt);
|
struct db_stmt *stmt = tal(db, struct db_stmt);
|
||||||
size_t num_slots;
|
size_t num_slots, pos;
|
||||||
stmt->query = NULL;
|
|
||||||
|
|
||||||
/* Normalize query_id paths, because unit tests are compiled with this
|
/* Normalize query_id paths, because unit tests are compiled with this
|
||||||
* prefix. */
|
* prefix. */
|
||||||
@ -920,14 +928,16 @@ struct db_stmt *db_prepare_v2_(const char *location, struct db *db,
|
|||||||
"transaction: %s", location);
|
"transaction: %s", location);
|
||||||
|
|
||||||
/* Look up the query by its ID */
|
/* Look up the query by its ID */
|
||||||
for (size_t i = 0; i < db->config->num_queries; i++) {
|
pos = hash_djb2(query_id) % db->config->query_table_size;
|
||||||
if (streq(query_id, db->config->queries[i].name)) {
|
for (;;) {
|
||||||
stmt->query = &db->config->queries[i];
|
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;
|
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;
|
num_slots = stmt->query->placeholders;
|
||||||
/* Allocate the slots for placeholders/bindings, zeroed next since
|
/* Allocate the slots for placeholders/bindings, zeroed next since
|
||||||
@ -2335,15 +2345,6 @@ const char **db_changes(struct db *db)
|
|||||||
return db->changes;
|
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,
|
size_t db_query_colnum(const struct db_stmt *stmt,
|
||||||
const char *colname)
|
const char *colname)
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@ struct db_stmt {
|
|||||||
struct db *db;
|
struct db *db;
|
||||||
|
|
||||||
/* Which SQL statement are we trying to execute? */
|
/* 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? */
|
/* Which parameters are we binding to the statement? */
|
||||||
struct db_binding *bindings;
|
struct db_binding *bindings;
|
||||||
@ -109,8 +109,8 @@ struct db_stmt {
|
|||||||
|
|
||||||
struct db_config {
|
struct db_config {
|
||||||
const char *name;
|
const char *name;
|
||||||
struct db_query *queries;
|
const struct db_query *query_table;
|
||||||
size_t num_queries;
|
size_t query_table_size;
|
||||||
|
|
||||||
/* Function used to execute a statement that doesn't result in a
|
/* Function used to execute a statement that doesn't result in a
|
||||||
* response. */
|
* response. */
|
||||||
|
@ -275,8 +275,8 @@ static bool db_postgres_vacuum(struct db *db)
|
|||||||
|
|
||||||
struct db_config db_postgres_config = {
|
struct db_config db_postgres_config = {
|
||||||
.name = "postgres",
|
.name = "postgres",
|
||||||
.queries = db_postgres_queries,
|
.query_table = db_postgres_queries,
|
||||||
.num_queries = DB_POSTGRES_QUERY_COUNT,
|
.query_table_size = ARRAY_SIZE(db_postgres_queries),
|
||||||
.exec_fn = db_postgres_exec,
|
.exec_fn = db_postgres_exec,
|
||||||
.query_fn = db_postgres_query,
|
.query_fn = db_postgres_query,
|
||||||
.step_fn = db_postgres_step,
|
.step_fn = db_postgres_step,
|
||||||
|
@ -253,8 +253,8 @@ static bool db_sqlite3_vacuum(struct db *db)
|
|||||||
|
|
||||||
struct db_config db_sqlite3_config = {
|
struct db_config db_sqlite3_config = {
|
||||||
.name = "sqlite3",
|
.name = "sqlite3",
|
||||||
.queries = db_sqlite3_queries,
|
.query_table = db_sqlite3_queries,
|
||||||
.num_queries = DB_SQLITE3_QUERY_COUNT,
|
.query_table_size = ARRAY_SIZE(db_sqlite3_queries),
|
||||||
.exec_fn = &db_sqlite3_exec,
|
.exec_fn = &db_sqlite3_exec,
|
||||||
.query_fn = &db_sqlite3_query,
|
.query_fn = &db_sqlite3_query,
|
||||||
.step_fn = &db_sqlite3_step,
|
.step_fn = &db_sqlite3_step,
|
||||||
|
Loading…
Reference in New Issue
Block a user