From ddcca62a276c528a4390c8e3d58403b865f81869 Mon Sep 17 00:00:00 2001 From: lemon Date: Sat, 13 Aug 2022 20:53:39 +0200 Subject: ok.. --- src/map.hff | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/map.hff (limited to 'src/map.hff') diff --git a/src/map.hff b/src/map.hff new file mode 100644 index 0000000..d8bbf52 --- /dev/null +++ b/src/map.hff @@ -0,0 +1,91 @@ +import "all.hff"; + +// KTraits: +// :hash(K) u32 +// :eq(T, T) bool +struct Map { + keys *K, + vals *V, + bitmap *u8, + N int, + count int, + + fn _iempty(self *Map, i int) bool { + return (self.bitmap[i/8] & (1 << (i%8))) == 0; + } + + fn get(self *Map, key K) *V { + if self.N == 0 { + return #null; + } + let i0 u32 = KTraits:hash(key); + let i = i0 & (self.N - 1); + do { + if self->_iempty(i) { + return #null; + } else if KTraits:eq(self.keys[i], key) { + return &self.vals[i]; + } + i = (i + 1) & (self.N - 1); + } while i != i0; + 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, + "?"); + 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] = {}; + return &self.vals[i]; + } else if KTraits:eq(self.keys[i], key) { + return &self.vals[i]; + } + i = (i + 1) & (self.N - 1); + } while i != i0; + assert(#f, "unreachable"); + } + +} -- cgit v1.2.3