commit 696fba72d238d361b65997b495c9c29af1bdd582
parent 68bd00eb117a41663ffe75c2e38febfee9ceacd2
Author: lash <dev@holbrook.no>
Date: Tue, 23 Apr 2024 07:50:10 +0100
Add ledger cache for item accumulation
Diffstat:
7 files changed, 88 insertions(+), 29 deletions(-)
diff --git a/src/gtk/kee-entry-item-store.c b/src/gtk/kee-entry-item-store.c
@@ -29,12 +29,10 @@ struct _KeeEntryItemStore {
static void kee_entry_item_store_iface_init(GListModelInterface *ifc);
G_DEFINE_TYPE_WITH_CODE(KeeEntryItemStore, kee_entry_item_store, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL, kee_entry_item_store_iface_init));
+static int kee_entry_item_store_scan(KeeEntryItemStore *o);
static void kee_entry_item_store_finalize(GObject *o);
-static int kee_entry_item_store_seek(KeeEntryItemStore *o, int idx);
-
-
static void kee_entry_item_store_class_init(KeeEntryItemStoreClass *kls) {
GObjectClass *oc = G_OBJECT_CLASS(kls);
oc->finalize = kee_entry_item_store_finalize;
@@ -79,7 +77,7 @@ KeeEntryItemStore* kee_entry_item_store_new(struct db_ctx *db, struct kee_ledger
o->ledger = ledger;
o->resolver = resolver;
- o->last_count = kee_entry_item_store_seek(o, INT_MAX);
+ o->last_count = kee_entry_item_store_scan(o);
g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "max key index is: %d", o->last_count - 1);
return o;
}
@@ -87,7 +85,7 @@ KeeEntryItemStore* kee_entry_item_store_new(struct db_ctx *db, struct kee_ledger
/// \todo always scans from 0, inefficient
/// \todo enum lookup states
-static int kee_entry_item_store_seek(KeeEntryItemStore *o, int idx) {
+static int kee_entry_item_store_scan(KeeEntryItemStore *o) {
struct kee_ledger_item_t *item;
int r;
int i;
@@ -107,7 +105,7 @@ static int kee_entry_item_store_seek(KeeEntryItemStore *o, int idx) {
memcpy(entry_key, last_key, entry_ref_len);
i = 0;
- while (i <= idx) {
+ while (i <= INT_MAX) {
last_value_length = 2048;
r = db_next(o->db, DbKeyLedgerEntry, &last_key, &key_len, &last_value, &last_value_length);
if (r) {
diff --git a/src/gtk/kee-entry-item.c b/src/gtk/kee-entry-item.c
@@ -69,7 +69,8 @@ void kee_entry_item_apply_list_item_widget(KeeEntryItem *o) {
GtkWidget *widget;
kee_content_resolve(&o->item->content, o->resolver);
- widget = gtk_label_new(o->item->content.subject);
+ sprintf(o->header, "%s\nalice: %i\nbob: %i\n", o->item->content.subject, o->item->alice_credit_delta, o->item->bob_credit_delta);
+ widget = gtk_label_new(o->header);
gtk_box_append(GTK_BOX(o), widget);
return;
}
diff --git a/src/gtk/kee-entry.c b/src/gtk/kee-entry.c
@@ -36,16 +36,13 @@ extern const asn1_static_node schema_entry_asn1_tab[];
/// \todo factor out separate struct for listitem
struct _KeeEntry {
GtkWidget parent;
+ GtkWidget *entry_list;
int state;
char header[1024];
struct kee_dn_t bob_dn;
char current_id[64];
struct kee_ledger_t ledger;
struct Cadiz *resolver;
- int alice_credit_balance;
- int bob_credit_balance;
- int alice_collateral_balance;
- int bob_collateral_balance;
int is_displaying;
struct db_ctx *db;
};
@@ -96,6 +93,8 @@ static void kee_entry_init(KeeEntry *o) {
o->state = 2;
o->resolver = NULL;
o->is_displaying = 0;
+ kee_ledger_init(&o->ledger);
+ kee_ledger_reset_cache(&o->ledger);
}
KeeEntry* kee_entry_new(struct db_ctx *db) {
@@ -110,6 +109,20 @@ void kee_entry_set_resolver(KeeEntry *o, struct Cadiz *resolver) {
o->resolver = resolver;
}
+static void kee_entry_init_list_widget(KeeEntry *o) {
+ GtkSingleSelection *sel;
+ GtkListItemFactory *factory;
+ KeeEntryItemStore *model;
+
+ factory = gtk_signal_list_item_factory_new();
+ g_signal_connect(factory, "setup", G_CALLBACK(kee_entry_handle_item_setup), NULL);
+ g_signal_connect(factory, "bind", G_CALLBACK(kee_entry_handle_item_bind), NULL);
+
+ model = kee_entry_item_store_new(o->db, &o->ledger, o->resolver);
+ sel = gtk_single_selection_new(G_LIST_MODEL(model));
+ o->entry_list = gtk_list_view_new(GTK_SELECTION_MODEL(sel), GTK_LIST_ITEM_FACTORY(factory));
+}
+
int kee_entry_deserialize(KeeEntry *o, const char *data, size_t data_len) {
int r;
size_t key_len;
@@ -162,6 +175,8 @@ int kee_entry_deserialize(KeeEntry *o, const char *data, size_t data_len) {
o->state = 0;
+ kee_entry_init_list_widget(o);
+
return ERR_OK;
}
@@ -173,31 +188,20 @@ void kee_entry_apply_list_item_widget(KeeEntry *o) {
return;
}
- sprintf(o->header, "%s [%s]\n%s (%s)", o->ledger.content.subject, o->ledger.uoa, o->bob_dn.cn, o->bob_dn.uid);
+ sprintf(o->header, "%s [%s]\n%s (%s)\nalice: %d\nbob: %d", o->ledger.content.subject, o->ledger.uoa, o->bob_dn.cn, o->bob_dn.uid, o->ledger.cache->alice_credit_balance, o->ledger.cache->bob_credit_balance);
widget = gtk_label_new(o->header);
gtk_box_append(GTK_BOX(o), widget);
o->is_displaying = 0;
return;
}
-int kee_entry_apply_display_widget(KeeEntry *o) {
- GtkWidget *widget;
- GtkSingleSelection *sel;
- GtkListItemFactory *factory;
- KeeEntryItemStore *model;
+int kee_entry_apply_display_widget(KeeEntry *o) {
if (o->is_displaying) {
return 1;
}
o->is_displaying = 1;
- factory = gtk_signal_list_item_factory_new();
- g_signal_connect(factory, "setup", G_CALLBACK(kee_entry_handle_item_setup), NULL);
- g_signal_connect(factory, "bind", G_CALLBACK(kee_entry_handle_item_bind), NULL);
-
- model = kee_entry_item_store_new(o->db, &o->ledger, o->resolver);
- sel = gtk_single_selection_new(G_LIST_MODEL(model));
- widget = gtk_list_view_new(GTK_SELECTION_MODEL(sel), GTK_LIST_ITEM_FACTORY(factory));
- gtk_box_append(GTK_BOX(o), widget);
+ gtk_box_append(GTK_BOX(o), o->entry_list);
return 0;
}
diff --git a/src/ledger.c b/src/ledger.c
@@ -1,4 +1,5 @@
#include <stddef.h>
+#include <string.h>
#include <libtasn1.h>
#include <gcrypt.h>
@@ -189,6 +190,26 @@ static int verify_item(asn1_node item, const char *pubkey_first_data, const char
return 0;
}
+void kee_ledger_item_apply_cache(struct kee_ledger_t *ledger, struct kee_ledger_item_t *item) {
+ if (ledger->cache == NULL) {
+ return;
+ }
+
+ ledger->cache->alice_credit_balance += item->alice_credit_delta;
+ ledger->cache->bob_credit_balance += item->bob_credit_delta;
+ ledger->cache->alice_collateral_balance += item->alice_collateral_delta;
+ ledger->cache->bob_collateral_balance += item->bob_collateral_delta;
+ ledger->cache->count++;
+}
+
+void kee_ledger_reset_cache(struct kee_ledger_t *ledger) {
+ if (ledger->cache == NULL) {
+ ledger->cache = calloc(sizeof(struct kee_ledger_cache_t), 1);
+ } else {
+ memset(ledger->cache, 0, sizeof(struct kee_ledger_cache_t));
+ }
+}
+
struct kee_ledger_item_t *kee_ledger_parse_item(struct kee_ledger_t *ledger, const char *data, size_t data_len) {
int r;
int c;
@@ -293,6 +314,8 @@ struct kee_ledger_item_t *kee_ledger_parse_item(struct kee_ledger_t *ledger, con
return NULL;
}
+ kee_ledger_item_apply_cache(ledger, cur);
+
return cur;
}
@@ -307,9 +330,16 @@ void kee_ledger_item_free(struct kee_ledger_item_t *item) {
}
void kee_ledger_free(struct kee_ledger_t *ledger) {
+ if (ledger->cache) {
+ free(ledger->cache);
+ }
kee_ledger_item_free(ledger->last_item);
}
+void kee_ledger_init(struct kee_ledger_t *ledger) {
+ memset(ledger, 0, sizeof(struct kee_ledger_t));
+}
+
int kee_ledger_parse(struct kee_ledger_t *ledger, const char *data, size_t data_len) {
int r;
char err[1024];
@@ -318,7 +348,6 @@ int kee_ledger_parse(struct kee_ledger_t *ledger, const char *data, size_t data_
int c;
char content_key[64];
- memset(ledger, 0, sizeof(struct kee_ledger_t));
memset(&root, 0, sizeof(root));
memset(&item, 0, sizeof(item));
r = asn1_array2tree(schema_entry_asn1_tab, &root, err);
diff --git a/src/ledger.h b/src/ledger.h
@@ -6,12 +6,11 @@
#include "content.h"
#include "cadiz.h"
-enum kee_initiator {
+enum kee_initiator_e {
ALICE,
BOB,
};
-
struct kee_ledger_item_t {
struct kee_ledger_item_t *prev_item;
int alice_credit_delta;
@@ -19,11 +18,19 @@ struct kee_ledger_item_t {
int alice_collateral_delta;
int bob_collateral_delta;
time_t time;
- enum kee_initiator initiator;
+ enum kee_initiator_e initiator;
char response;
struct kee_content_t content;
};
+struct kee_ledger_cache_t {
+ int count;
+ int alice_credit_balance;
+ int bob_credit_balance;
+ int alice_collateral_balance;
+ int bob_collateral_balance;
+};
+
struct kee_ledger_t {
const char digest[64];
struct kee_ledger_item_t *last_item;
@@ -32,12 +39,15 @@ struct kee_ledger_t {
char uoa_decimals;
char uoa[64];
struct kee_content_t content;
+ struct kee_ledger_cache_t *cache;
};
struct kee_ledger_item_t *kee_ledger_parse_item(struct kee_ledger_t *ledger, const char *data, size_t data_len);
int kee_ledger_parse(struct kee_ledger_t *ledger, const char *data, size_t data_len);
+void kee_ledger_init(struct kee_ledger_t *ledger);
void kee_ledger_free(struct kee_ledger_t *ledger);
void kee_ledger_item_free(struct kee_ledger_item_t *item);
void kee_ledger_resolve(struct kee_ledger_t *ledger, Cadiz *cadiz);
+void kee_ledger_reset_cache(struct kee_ledger_t *ledger);
#endif
diff --git a/src/tests/ledger.c b/src/tests/ledger.c
@@ -21,6 +21,9 @@ int main() {
cadiz.locator = "./testdata_resource";
+ kee_ledger_init(&ledger);
+ kee_ledger_reset_cache(&ledger);
+
c = hex2bin(test_ledger_data, (unsigned char*)data);
r = kee_ledger_parse(&ledger, data, c);
if (r) {
@@ -41,6 +44,19 @@ int main() {
kee_ledger_resolve(&ledger, &cadiz);
+ if (ledger.cache->alice_credit_balance == 0) {
+ return 1;
+ }
+ if (ledger.cache->bob_credit_balance == 0) {
+ return 1;
+ }
+ if (ledger.cache->alice_collateral_balance == 0) {
+ return 1;
+ }
+ if (ledger.cache->bob_collateral_balance == 0) {
+ return 1;
+ }
+
kee_ledger_free(&ledger);
return 0;
diff --git a/testdata_asn1.py b/testdata_asn1.py
@@ -36,6 +36,7 @@ NOSIG = b''
PFX_LEDGER_HEAD = b'\x01'
PFX_LEDGER_ENTRY = b'\x02'
PFX_LEDGER_PUBKEY = b'\x03'
+PFX_LEDGER_CACHE_SUMS = b'\x80'
random.seed(int(time.time_ns()))