summaryrefslogtreecommitdiff
path: root/vere/pkg/noun/zave.c
diff options
context:
space:
mode:
Diffstat (limited to 'vere/pkg/noun/zave.c')
-rw-r--r--vere/pkg/noun/zave.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/vere/pkg/noun/zave.c b/vere/pkg/noun/zave.c
new file mode 100644
index 0000000..2530718
--- /dev/null
+++ b/vere/pkg/noun/zave.c
@@ -0,0 +1,157 @@
+/// @file
+
+#include "zave.h"
+
+#include "allocate.h"
+#include "hashtable.h"
+#include "imprison.h"
+#include "options.h"
+#include "vortex.h"
+
+/* u3z_key(): construct a memo cache-key. Arguments retained.
+*/
+u3_noun
+u3z_key(c3_m fun, u3_noun one)
+{
+ return u3nc(fun, u3k(one));
+}
+u3_noun
+u3z_key_2(c3_m fun, u3_noun one, u3_noun two)
+{
+ return u3nt(fun, u3k(one), u3k(two));
+}
+u3_noun
+u3z_key_3(c3_m fun, u3_noun one, u3_noun two, u3_noun tri)
+{
+ return u3nq(fun, u3k(one), u3k(two), u3k(tri));
+}
+u3_noun
+u3z_key_4(c3_m fun, u3_noun one, u3_noun two, u3_noun tri, u3_noun qua)
+{
+ return u3nc(fun, u3nq(u3k(one), u3k(two), u3k(tri), u3k(qua)));
+}
+u3_noun
+u3z_key_5(c3_m fun, u3_noun one, u3_noun two, u3_noun tri, u3_noun qua, u3_noun qin)
+{
+ return u3nc(fun, u3nq(u3k(one), u3k(two), u3k(tri), u3nc(u3k(qua), u3k(qin))));
+}
+
+/* _har(): get the memo cache for the given cid.
+*/
+static u3p(u3h_root)
+_har(u3a_road* rod_u, u3z_cid cid)
+{
+ switch ( cid ) {
+ case u3z_memo_toss:
+ return rod_u->cax.har_p;
+ case u3z_memo_keep:
+ return rod_u->cax.per_p;
+ }
+ u3_assert(0);
+}
+
+/* u3z_find(): find in memo cache. Arguments retained.
+*/
+u3_weak
+u3z_find(u3z_cid cid, u3_noun key)
+{
+ if ( (u3z_memo_toss == cid) || (u3C.wag_w & u3o_cash) ) {
+ // XX under cash lookup in parent roads,
+ // copying cache hits into the current road
+ return u3h_get(_har(u3R, cid), key);
+ }
+ else {
+ // XX needs to be benchmarked (up vs. down search)
+ u3a_road* rod_u = &(u3H->rod_u);
+ while ( 1 ) {
+ u3_weak got = u3h_get(_har(rod_u, cid), key);
+ if ( u3_none != got ) {
+ return got;
+ }
+ if ( 0 == rod_u->kid_p ) {
+ return u3_none;
+ }
+ rod_u = u3to(u3a_road, rod_u->kid_p);
+ };
+ }
+}
+
+/* u3z_find_up(): find in persistent memo cache,
+ starting from the current road. Arguments retained
+*/
+u3_weak
+u3z_find_up(u3_noun key)
+{
+ u3a_road* rod_u = u3R;
+ while ( 1 ) {
+ u3_weak got = u3h_get(_har(rod_u, u3z_memo_keep), key);
+ if ( u3_none != got ) {
+ return got;
+ }
+ if ( rod_u == &(u3H->rod_u) ) {
+ return u3_none;
+ }
+ rod_u = u3to(u3a_road, rod_u->par_p);
+ }
+}
+
+u3_weak
+u3z_find_m(u3z_cid cid, c3_m fun, u3_noun one)
+{
+ u3_noun key = u3nc(fun, u3k(one));
+ u3_weak val;
+ val = u3z_find(cid, key);
+ u3z(key);
+
+ return val;
+}
+
+/* u3z_save(): save in memo cache. TRANSFER key; RETAIN val
+*/
+u3_noun
+u3z_save(u3z_cid cid, u3_noun key, u3_noun val)
+{
+ u3h_put(_har(u3R, cid), key, u3k(val));
+ u3z(key);
+ return val;
+}
+
+/* u3z_save_m(): save in memo cache. Arguments retained.
+*/
+u3_noun
+u3z_save_m(u3z_cid cid, c3_m fun, u3_noun one, u3_noun val)
+{
+ u3_noun key = u3nc(fun, u3k(one));
+
+ u3h_put(_har(u3R, cid), key, u3k(val));
+ u3z(key);
+ return val;
+}
+
+/* u3z_uniq(): uniquify with memo cache. XX not used.
+*/
+u3_noun
+u3z_uniq(u3z_cid cid, u3_noun som)
+{
+ u3_noun key = u3nc(c3__uniq, u3k(som));
+ u3_noun val = u3h_get(_har(u3R, cid), key);
+
+ if ( u3_none != val ) {
+ u3z(key); u3z(som); return val;
+ }
+ else {
+ u3h_put(_har(u3R, cid), key, u3k(som));
+ return som;
+ }
+}
+
+/* u3z_reap(): promote memoization cache state.
+*/
+void
+u3z_reap(u3z_cid cid, u3p(u3h_root) har_p)
+{
+ u3_assert(u3z_memo_toss != cid);
+
+ u3h_uni(_har(u3R, cid), har_p);
+ u3h_free(har_p);
+}