aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-14 07:25:40 +0200
committerlemon <lsof@mailbox.org>2022-08-14 07:25:53 +0200
commitf0def28d9aeeb7f1f9b3d8880a34a05ec59d80ed (patch)
tree72b4f9776a8bc1964d32b3db2e8bf2d78120ad57 /src
parent4a656bf19a45e0b3f553f9c518e7e842cc6cbf51 (diff)
multiline comment and stuff
Diffstat (limited to 'src')
-rw-r--r--src/map.hff34
-rw-r--r--src/set.hff40
-rw-r--r--src/vec.hff4
3 files changed, 32 insertions, 46 deletions
diff --git a/src/map.hff b/src/map.hff
index d8bbf52..6900878 100644
--- a/src/map.hff
+++ b/src/map.hff
@@ -31,35 +31,6 @@ struct Map<K, V, KTraits> {
assert(#f, "unreachable");
}
- fn put(self *Map, key K, val V) void {
- if self.keys == #null {
- assert(self.vals == #null and self.bitmap == #null and self.N == 0 and self.count == 0,
- "?");
- self.keys = xcalloc(self.N = 16, sizeof K);
- self.vals = xcalloc(self.N, sizeof V);
- self.bitmap = xcalloc(self.N / 8, 1);
- }
-
- if self.count == self.N / 2 {
- // rehash
- }
- let i0 u32 = KTraits:hash(key);
- let i = i0 & (self.N - 1);
- do {
- if self->_iempty(i) {
- self.bitmap[i/8] |= (1 << (i%8));
- ++self.count;
- self.vals[i] = val;
- return;
- } else if KTraits:eq(self.keys[i], key) {
- self.vals[i] = val;
- return;
- }
- i = (i + 1) & (self.N - 1);
- } while i != i0;
- assert(#f, "unreachable");
- }
-
fn get_slot(self *Map, key K) *V {
if self.keys == #null {
assert(self.vals == #null and self.bitmap == #null and self.N == 0 and self.count == 0,
@@ -88,4 +59,9 @@ struct Map<K, V, KTraits> {
assert(#f, "unreachable");
}
+
+ fn put(self *Map, key K, val V) void {
+ *self->get_slot(key) = val;
+ }
+
}
diff --git a/src/set.hff b/src/set.hff
index 28e67be..396d63c 100644
--- a/src/set.hff
+++ b/src/set.hff
@@ -1,32 +1,34 @@
import "vec.hff";
import "all.hff";
-// KTraits:
-// :hash(K) u32
-// :eq(T, T) bool
-// :dup(T) T
+
+
+#!{ KTraits:
+ :hash(K) u32
+ :eq(T, T) bool
+ :dup(T) T }
struct Set<T, Traits> {
buf Vec<T>,
- set **const T,
+ set *int,
N int,
count int,
fn intern(self *Set, x T) *const T {
if self.set == #null {
- self.set = xcalloc(self.N = 16, sizeof *T);
+ self.set = xcalloc(self.N = 16, sizeof int);
}
if self.count == self.N / 2 {
free(self.set);
- self.set = xcalloc(self.N *= 2, sizeof *T);
+ self.set = xcalloc(self.N *= 2, sizeof int);
vec_each(p, i, self.buf,
- let i = Traits:hash(p) & (self.N - 1);
+ let j = Traits:hash(p) & (self.N - 1);
for ;; {
- if self.set[i] == #null {
- self.set[i] = &self.buf.dat[i];
+ if self.set[j] == 0 {
+ self.set[j] = i + 1;
break;
}
- i = (i + 1) & (self.N - 1);
+ j = (j + 1) & (self.N - 1);
}
)
}
@@ -34,12 +36,16 @@ struct Set<T, Traits> {
let i0 u32 = Traits:hash(x) & (self.N - 1);
let i int = i0;
do {
- if self.set[i] == #null {
+ if self.set[i] == 0 {
++self.count;
self.buf->push(Traits:dup(x));
- return self.set[i] = &self.buf.dat[self.buf.len - 1];
- } else if Traits:eq(*self.set[i], x) {
- return self.set[i];
+ self.set[i] = self.buf.len;
+ return self.buf->lastp();
+ } else {
+ let x2 = &self.buf.dat[self.set[i] - 1];
+ if Traits:eq(*x2, x) {
+ return x2;
+ }
}
i = (i + 1) & (self.N - 1);
} while i != i0;
@@ -50,9 +56,9 @@ struct Set<T, Traits> {
let i0 u32 = Traits:hash(x) & (self.N - 1);
let i int = i0;
do {
- if self.set[i] == #null {
+ if self.set[i] == 0 {
return #f;
- } else if Traits:eq(*self.set[i], x) {
+ } else if Traits:eq(self.buf.dat[self.set[i] - 1], x) {
return #t;
}
i = (i + 1) & (self.N - 1);
diff --git a/src/vec.hff b/src/vec.hff
index 9099b85..be29fec 100644
--- a/src/vec.hff
+++ b/src/vec.hff
@@ -33,6 +33,10 @@ struct Vec<T> {
}
return vec.dat[0::vec.len];
}
+
+ fn last(vec *const Vec) T { return vec.dat[vec.len - 1]; }
+
+ fn lastp(vec *Vec) *T { return &vec.dat[vec.len - 1]; }
}
defmacro vec_each(x, i, v, ...body) [