aboutsummaryrefslogtreecommitdiffhomepage
path: root/mem.c
diff options
context:
space:
mode:
author lemon<lsof@mailbox.org>2026-03-17 13:22:00 +0100
committer lemon<lsof@mailbox.org>2026-03-17 13:22:00 +0100
commita8d6f8bf30c07edb775e56889f568ca20240bedf (patch)
treeb5a452b2675b2400f15013617291fe6061180bbf /mem.c
parent24f14b7ad1af08d872971d72ce089a529911f657 (diff)
REFACTOR: move sources to src/
Diffstat (limited to 'mem.c')
-rw-r--r--mem.c390
1 files changed, 0 insertions, 390 deletions
diff --git a/mem.c b/mem.c
deleted file mode 100644
index 9ee8864..0000000
--- a/mem.c
+++ /dev/null
@@ -1,390 +0,0 @@
-#include "common.h"
-#include <stdlib.h>
-#include <errno.h>
-#include <stdint.h>
-
-static void
-allocerr(const char *f)
-{
- efmt("%s: %s\n", f, strerror(errno));
- ioflush(&bstdout);
- ioflush(&bstderr);
- abort();
-}
-
-void *
-(xmalloc)(size_t n, const char *f)
-{
- void *p = malloc(n);
- if (!p) allocerr(f);
- return p;
-}
-
-void *
-(xcalloc)(size_t n, const char *f)
-{
- void *p = calloc(n, 1);
- if (!p) allocerr(f);
- return p;
-}
-
-void *
-(xrealloc)(void *p, size_t n, const char *f)
-{
- p = p ? realloc(p, n) : malloc(n);
- if (!p) allocerr(f);
- return p;
-}
-
-/** string interning **/
-internstr
-intern_(const char *s, uint len)
-{
- static uint N, n;
- static struct ht {
- internstr s;
- size_t h;
- } *ht;
- static struct { char m[sizeof(struct arena) + (2<<10)]; struct arena *_a; } amem;
- static struct arena *arena;
-
- if (!N) {
- ht = xcalloc((sizeof *ht) * (N = 1<<10));
- arena = (void *)amem.m, arena->cap = sizeof amem.m - sizeof(struct arena);
- }
-
- for (size_t h = len ? hashb(0, s, len) : hashs(0, s), i = h;;) {
- i &= N - 1;
- if (!ht[i].s) { /* insert */
- if (n < N/4*3 /*load factor 75%*/) {
- ++n;
- ht[i].h = h;
- ht[i].s = alloccopy(&arena, s, (len ? len : strlen(s))+1, 1);
- if (len) ((char *)ht[i].s)[len] = 0;
- return ht[i].s;
- }
- /* resize */
- size_t nnew = N * 2;
- struct ht *new = xcalloc(sizeof *new * nnew);
- for (uint i = 0; i < N; ++i) { /* rehash */
- if (!ht[i].s) continue;
- uint j = ht[i].h;
- while (new[j &= nnew-1].s) ++j;
- new[j] = ht[i];
- }
- free(ht);
- ht = new;
- N = nnew;
- i = h;
- continue;
- } else if (h == ht[i].h) {
- if (!len && !strcmp(s, &ht[i].s->c))
- return ht[i].s;
- else if (len && !strncmp(s, &ht[i].s->c, len) && ht[i].s[len].c == 0)
- return ht[i].s;
- }
- ++i;
- }
-}
-
-/** vec **/
-void
-vinit_(struct vecbase *v, void *inlbuf, uint cap, uint siz)
-{
- assert(!v->p);
- v->cap = cap;
- if (inlbuf) {
- v->p = inlbuf;
- v->dyn = 0;
- } else if (cap) {
- v->p = xmalloc(cap*siz);
- v->dyn = 1;
- }
-}
-
-void
-vpush_(struct vecbase *v, uint siz)
-{
- if (v->n < v->cap) return;
- if (!v->dyn && v->n >= v->cap) { /* empty or inline buffer */
- int cap = v->cap ? v->cap * 2 : 8;
- void *old = v->p;
- v->p = xmalloc(cap * siz);
- if (old) memcpy(v->p, old, v->cap * siz);
- v->cap = cap;
- v->dyn = 1;
- } else if (v->dyn && v->n >= v->cap) { /* dyn buf */
- v->p = xrealloc(v->p, (v->cap *= 2) * siz);
- }
- while (v->n >= v->cap)
- v->p = xrealloc(v->p, (v->cap *= 2) * siz);
- assert(v->cap > v->n && "overflow");
-}
-
-void *
-vpushn_(struct vecbase *v, uint siz, const void *dat, uint ndat)
-{
- void *beg;
-
- if (!ndat) return v->p;
- v->n += ndat;
- while (v->n >= v->cap)
- vpush_(v, siz);
- beg = (char *)v->p + (v->n - ndat) * siz;
- assert(dat);
- memcpy(beg, dat, ndat * siz);
- return beg;
-}
-
-void
-vresize_(struct vecbase *v, uint siz, uint N)
-{
- while (v->cap < N) {
- vpush_(v, siz);
- v->n = v->cap;
- }
- v->n = N;
-}
-
-/** arena **/
-struct arena *
-newarena(uint chunksiz)
-{
- struct arena *ar = xmalloc(offsetof(struct arena, mem) + chunksiz);
- assert(chunksiz < 1u<<31 && "toobig");
- ar->prev = NULL;
- ar->cap = chunksiz;
- ar->dyn = 1;
- ar->n = 0;
- return ar;
-}
-
-void *
-alloc(struct arena **par, uint siz, uint align)
-{
- uint idx;
- struct arena *new;
-
- if (siz > (*par)->cap) {
- new = newarena(siz);
- new->n = siz;
- new->prev = (*par)->prev;
- (*par)->prev = new;
- return new->mem;
- }
- align = align ? align : sizeof(void *);
- idx = (uchar *)alignup((uintptr_t)&(*par)->mem[(*par)->n], align) - (*par)->mem;
- if ((*par)->cap - idx >= siz) {
- (*par)->n = idx + siz;
- return (*par)->mem + idx;
- }
- new = newarena((*par)->cap);
- new->prev = *par;
- *par = new;
- new->n = siz;
- return new->mem;
-}
-
-void *
-allocz(struct arena **par, uint siz, uint align)
-{
- return memset(alloc(par, siz, align), 0, siz);
-}
-
-void
-freearena(struct arena **par)
-{
- struct arena *prev;
- for (; *par; *par = prev) {
- prev = (*par)->prev;
- if ((*par)->dyn)
- free(*par);
- else {
- if (prev) freearena(&prev);
- (*par)->prev = NULL;
- (*par)->n = 0;
- return;
- }
- }
-}
-
-/** integer hashmap **/
-void
-imap_init_(struct imapbase *m, void **v, uint vsiz, uint N)
-{
- uint sizk = N*sizeof*m->k,
- sizv = N*vsiz,
- sizbs = BSSIZE(N)*sizeof(struct bitset);
-
- assert(ispo2(N));
- m->k = xcalloc(sizk + sizv + sizbs);
- *v = (char *)m->k + sizk;
- m->bs = (struct bitset *)((char *)*v + sizv);
- m->N = N;
-}
-
-int
-imap_get_(struct imapbase *m, short k)
-{
- if (!m->N) return -1;
- for (int i = k;; ++i) {
- bool notempty = bstest(m->bs, i &= m->N - 1);
- if (bstest(m->bs, i) && m->k[i] == k) return i;
- if (!notempty) return -1;
- }
-}
-
-static void
-imap_rehash(struct imapbase *m, void **v, uint vsiz)
-{
- short *newk, k;
- int i, j;
- void *newv;
- struct bitset *newbs;
- uint N2 = m->N ? m->N << 1 : 16,
- sizk = N2*sizeof*m->k,
- sizv = N2*vsiz,
- sizbs = BSSIZE(N2)*sizeof(struct bitset);
-
- assert(N2);
- newk = xcalloc(sizk + sizv + sizbs);
- memset(newk, 0, sizk + sizv + sizbs);
- newv = (char *)newk + sizk;
- newbs = (struct bitset *)((char *)newv + sizv);
- for (i = 0; i < m->N; ++i) {
- if (!bstest(m->bs, i))
- continue;
- j = k = m->k[i];
- for (;; ++j) {
- j &= N2 - 1;
- if (!bstest(newbs, j)) {
- bsset(newbs, j);
- newk[j] = k;
- memcpy((char *)newv + j*vsiz, (char *)*v + i*vsiz, vsiz);
- break;
- }
- }
- }
- free(m->k);
- m->k = newk;
- *v = newv;
- m->bs = newbs;
- m->N = N2;
-}
-
-int
-imap_set_(struct imapbase *m, void **v, uint vsiz, short k)
-{
- if (m->n >= m->N/4*3 /*load factor 75*/) {
- imap_rehash(m, v, vsiz);
- assert(m->n < m->N);
- }
- for (int i = k;; ++i) {
- bool notempty = bstest(m->bs, i &= m->N - 1);
- if (notempty && m->k[i] == k)
- return i;
- if (!notempty) {
- m->k[i] = k;
- bsset(m->bs, i);
- ++m->n;
- return i;
- }
- }
-}
-
-/** pointer hashmap **/
-void
-pmap_init_(struct pmapbase *m, void **v, uint vsiz, uint N)
-{
- assert(ispo2(N));
- uint sizk = N*sizeof*m->k,
- sizv = N*vsiz;
-
- m->k = xcalloc(sizk + sizv);
- *v = (char *)m->k + sizk;
- m->N = N;
-}
-
-int
-pmap_get_(struct pmapbase *m, const void *k)
-{
- assert(k && "null key");
- if (!m->N) return -1;
- for (size_t i = ptrhash(k);; ++i) {
- i &= m->N - 1;
- if (m->k[i] == k) return i;
- if (!m->k[i]) return -1;
- }
-}
-
-char pmap_tombstone_[1];
-
-static void
-pmap_rehash(struct pmapbase *m, void **v, uint vsiz)
-{
- void **newk;
- int i, j;
- void *k;
- void *newv;
- uint N2 = m->N ? m->N << 1 : 16,
- sizk = N2*sizeof*m->k,
- sizv = N2*vsiz;
-
- assert(N2);
- newk = xcalloc(sizk + sizv);
- newv = (char *)newk + sizk;
- for (i = 0; i < m->N; ++i) {
- if (!m->k[i] || m->k[i] == pmap_tombstone_)
- continue;
- j = ptrhash(k = m->k[i]);
- for (;; ++j) {
- j &= N2 - 1;
- if (!newk[j]) {
- newk[j] = k;
- memcpy((char *)newv + j*vsiz, (char *)*v + i*vsiz, vsiz);
- break;
- }
- }
- }
- free(m->k);
- m->k = newk;
- *v = newv;
- m->N = N2;
-}
-
-int
-pmap_set_(struct pmapbase *m, void **v, uint vsiz, const void *k)
-{
- assert(k && "null key");
- if (m->n >= m->N/4*3 /*load factor 75%*/) {
- pmap_rehash(m, v, vsiz);
- assert(m->n < m->N);
- }
- for (size_t i = ptrhash(k);; ++i) {
- i &= m->N - 1;
- if (m->k[i] == k)
- return i;
- if (!m->k[i] || m->k[i] == pmap_tombstone_) {
- m->k[i] = (void *)k;
- ++m->n;
- return i;
- }
- }
-}
-
-void
-pmap_del_(struct pmapbase *m, const void *k)
-{
- assert(k && "null key");
- for (size_t i = ptrhash(k);; ++i) {
- i &= m->N - 1;
- if (m->k[i] == k) {
- m->k[i] = pmap_tombstone_;
- --m->n;
- return;
- } else if (!m->k[i])
- return;
- }
-}
-
-/* vim:set ts=3 sw=3 expandtab: */