Post Scarcity
A prototype for a post scarcity programming environment
Loading...
Searching...
No Matches
hashmap.c
Go to the documentation of this file.
1/*
2 * hashmap.c
3 *
4 * Basic implementation of a hashmap.
5 *
6 * (c) 2021 Simon Brooke <simon@journeyman.cc>
7 * Licensed under GPL version 2.0, or, at your option, any later version.
8 */
9
10#include "arith/integer.h"
11#include "arith/peano.h"
12#include "authorise.h"
13#include "debug.h"
14#include "ops/intern.h"
15#include "io/print.h"
16#include "memory/conspage.h"
18#include "memory/hashmap.h"
19#include "memory/vectorspace.h"
20
21
22/**
23 * A lisp function signature conforming wrapper around get_hash, q.v..
24 */
26 struct cons_pointer frame_pointer,
27 struct cons_pointer env ) {
28 return make_integer( get_hash( frame->arg[0] ), NIL );
29}
30
31/**
32 * Lisp funtion of up to four args (all optional), where
33 *
34 * first is expected to be an integer, the number of buckets, or nil;
35 * second is expected to be a hashing function, or nil;
36 * third is expected to be an assocable, or nil;
37 * fourth is a list of user tokens, to be used as a write ACL, or nil.
38 */
40 struct cons_pointer frame_pointer,
41 struct cons_pointer env ) {
42 uint32_t n = DFLT_HASHMAP_BUCKETS;
43 struct cons_pointer hash_fn = NIL;
44 struct cons_pointer result = NIL;
45
46 if ( frame->args > 0 ) {
47 if ( integerp( frame->arg[0] ) ) {
48 n = to_long_int( frame->arg[0] ) % UINT32_MAX;
49 } else if ( !nilp( frame->arg[0] ) ) {
50 result =
52 ( L"First arg to `hashmap`, if passed, must "
53 L"be an integer or `nil`.`" ), NIL );
54 }
55 }
56 if ( frame->args > 1 ) {
57 if ( functionp( frame->arg[1] ) ) {
58 hash_fn = frame->arg[1];
59 } else if ( nilp( frame->arg[1] ) ) {
60 /* that's allowed */
61 } else {
62 result =
64 ( L"Second arg to `hashmap`, if passed, must "
65 L"be a function or `nil`.`" ), NIL );
66 }
67 }
68
69 if ( nilp( result ) ) {
70 /* if there are fewer than 4 args, then arg[3] ought to be nil anyway, which
71 * is fine */
72 result = make_hashmap( n, hash_fn, frame->arg[3] );
73 struct vector_space_object *map = pointer_to_vso( result );
74
75 if ( frame->args > 2 &&
76 truep( authorised( result, map->payload.hashmap.write_acl ) ) ) {
77 // then arg[2] ought to be an assoc list which we should iterate down
78 // populating the hashmap.
79 for ( struct cons_pointer cursor = frame->arg[2]; !nilp( cursor );
80 cursor = c_cdr( cursor ) ) {
81 struct cons_pointer pair = c_car( cursor );
82 struct cons_pointer key = c_car( pair );
83 struct cons_pointer val = c_cdr( pair );
84
85 uint32_t bucket_no =
86 get_hash( key ) % ( ( struct hashmap_payload * )
87 &( map->payload ) )->n_buckets;
88
89 map->payload.hashmap.buckets[bucket_no] =
90 make_cons( make_cons( key, val ),
91 map->payload.hashmap.buckets[bucket_no] );
92 }
93 }
94 }
95
96 return result;
97}
98
99/**
100 * Expects `frame->arg[1]` to be a hashmap or namespace; `frame->arg[2]` to be
101 * a string-like-thing (perhaps necessarily a keyword); frame->arg[3] to be
102 * any value. If
103 * current user is authorised to write to this hashmap, modifies the hashmap and
104 * returns it; if not, clones the hashmap, modifies the clone, and returns that.
105 */
107 struct cons_pointer frame_pointer,
108 struct cons_pointer env ) {
109 // TODO: if current user has write access to this hashmap
110
111 struct cons_pointer mapp = frame->arg[0];
112 struct cons_pointer key = frame->arg[1];
113 struct cons_pointer val = frame->arg[2];
114
115 struct cons_pointer result = hashmap_put( mapp, key, val );
116 struct cons_space_object *cell = &pointer2cell( result );
117 return result;
118
119 // TODO: else clone and return clone.
120}
121
122/**
123 * Lisp function expecting two arguments, a hashmap and an assoc list. Copies all
124 * key/value pairs from the assoc list into the map.
125 */
127 struct cons_pointer frame_pointer,
128 struct cons_pointer env ) {
129 return hashmap_put_all( frame->arg[0], frame->arg[1] );
130}
131
133 struct cons_pointer frame_pointer,
134 struct cons_pointer env ) {
135 return hashmap_keys( frame->arg[0] );
136}
137
138void dump_map( URL_FILE *output, struct cons_pointer pointer ) {
139 struct hashmap_payload *payload =
140 &pointer_to_vso( pointer )->payload.hashmap;
141 url_fwprintf( output, L"Hashmap with %d buckets:\n", payload->n_buckets );
142 url_fwprintf( output, L"\tHash function: " );
143 print( output, payload->hash_fn );
144 url_fwprintf( output, L"\n\tWrite ACL: " );
145 print( output, payload->write_acl );
146 url_fwprintf( output, L"\n\tBuckets:" );
147 for ( int i = 0; i < payload->n_buckets; i++ ) {
148 url_fwprintf( output, L"\n\t\t[%d]: ", i );
149 print( output, payload->buckets[i] );
150 }
151 url_fwprintf( output, L"\n" );
152}
struct cons_pointer authorised(struct cons_pointer target, struct cons_pointer acl)
TODO: does nothing, yet.
Definition authorise.c:18
#define truep(conspoint)
true if conspoint points to something that is truthy, i.e.
#define functionp(conspoint)
true if conspoint points to a function cell, else false
#define NIL
a cons pointer which points to the special NIL cell
struct cons_pointer make_exception(struct cons_pointer message, struct cons_pointer frame_pointer)
Construct an exception cell.
struct cons_pointer c_cdr(struct cons_pointer arg)
Implementation of cdr in C.
#define nilp(conspoint)
true if conspoint points to the special cell NIL, else false (there should only be one of these so it...
struct cons_pointer c_string_to_lisp_string(wchar_t *string)
Return a lisp string representation of this wide character string.
struct cons_pointer c_car(struct cons_pointer arg)
Implementation of car in C.
#define pointer2cell(pointer)
given a cons_pointer as argument, return the cell.
#define integerp(conspoint)
true if conspoint points to an integer cell, else false
struct cons_pointer make_cons(struct cons_pointer car, struct cons_pointer cdr)
Construct a cons cell from this pair of pointers.
An indirect pointer to a cons cell.
an object in cons space.
A stack frame.
#define url_fwprintf(f,...)
Definition fopen.h:50
struct cons_pointer lisp_hashmap_put_all(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Lisp function expecting two arguments, a hashmap and an assoc list.
Definition hashmap.c:126
void dump_map(URL_FILE *output, struct cons_pointer pointer)
Definition hashmap.c:138
struct cons_pointer lisp_get_hash(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
A lisp function signature conforming wrapper around get_hash, q.v.
Definition hashmap.c:25
struct cons_pointer lisp_hashmap_put(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Expects frame->arg[1] to be a hashmap or namespace; frame->arg[2] to be a string-like-thing (perhaps ...
Definition hashmap.c:106
struct cons_pointer lisp_make_hashmap(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Lisp funtion of up to four args (all optional), where.
Definition hashmap.c:39
struct cons_pointer lisp_hashmap_keys(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Definition hashmap.c:132
#define DFLT_HASHMAP_BUCKETS
Definition hashmap.h:18
struct cons_pointer make_integer(int64_t value, struct cons_pointer more)
Allocate an integer cell representing this value and return a cons_pointer to it.
Definition integer.c:89
struct cons_pointer hashmap_put(struct cons_pointer mapp, struct cons_pointer key, struct cons_pointer val)
Store this val as the value of this key in this hashmap mapp.
Definition intern.c:385
struct cons_pointer hashmap_put_all(struct cons_pointer mapp, struct cons_pointer assoc)
Copy all key/value pairs in this association list assoc into this hashmap mapp.
Definition intern.c:183
struct cons_pointer make_hashmap(uint32_t n_buckets, struct cons_pointer hash_fn, struct cons_pointer write_acl)
Make a hashmap with this number of buckets, using this hash_fn.
Definition intern.c:137
struct cons_pointer hashmap_keys(struct cons_pointer mapp)
return a flat list of all the keys in the hashmap indicated by map.
Definition intern.c:162
uint32_t get_hash(struct cons_pointer ptr)
Get the hash value for the cell indicated by this ptr; currently only implemented for string like thi...
Definition intern.c:81
int64_t to_long_int(struct cons_pointer arg)
Return the closest possible int64_t representation to the value of this arg, expected to be an intege...
Definition peano.c:176
struct cons_pointer print(URL_FILE *output, struct cons_pointer pointer)
Print the cons-space object indicated by pointer to the stream indicated by output.
Definition print.c:151
struct cons_pointer hash_fn
Definition vectorspace.h:89
uint32_t n_buckets
Definition vectorspace.h:95
struct cons_pointer write_acl
Definition vectorspace.h:91
union vector_space_object::@5 payload
we'll malloc size bytes for payload, payload is just the first of these.
#define pointer_to_vso(pointer)
given a pointer to a vector space object, return the object.
Definition vectorspace.h:55
struct cons_pointer buckets[]
Definition vectorspace.h:97
The payload of a hashmap.
Definition vectorspace.h:88
a vector_space_object is just a vector_space_header followed by a lump of bytes; what we deem to be i...