#ifndef SP_TRACK_H_ #define SP_TRACK_H_ /* * sophia database * sphia.org * * Copyright (c) Dmitry Simonenko * BSD License */ typedef struct sptrack sptrack; struct sptrack { spa *a; uint64_t max; uint64_t *i; int count; int size; }; static inline int sp_trackinit(sptrack *t, spa *a, int size) { t->a = a; t->max = 0; t->count = 0; t->size = size; int sz = size * sizeof(uint64_t); t->i = sp_malloc(a, sz); if (spunlikely(t->i == NULL)) return -1; memset(t->i, 0, sz); return 0; } static inline void sp_trackfree(sptrack *t) { if (spunlikely(t->i == NULL)) return; sp_free(t->a, t->i); t->i = NULL; } static inline void sp_trackinsert(sptrack *t, uint64_t id) { uint32_t pos = id % t->size; for (;;) { if (spunlikely(t->i[pos] != 0)) { pos = (pos + 1) % t->size; continue; } if (id > t->max) t->max = id; t->i[pos] = id; break; } t->count++; } static inline int sp_trackresize(sptrack *t) { sptrack nt; int rc = sp_trackinit(&nt, t->a, t->size * 2); if (spunlikely(rc == -1)) return -1; int i = 0; while (i < t->size) { if (t->i[i]) sp_trackinsert(&nt, t->i[i]); i++; } sp_trackfree(t); *t = nt; return 0; } static inline int sp_trackset(sptrack *t, uint64_t id) { if (spunlikely(t->count > (t->size / 2))) if (spunlikely(sp_trackresize(t) == -1)) return -1; sp_trackinsert(t, id); return 0; } static inline int sp_trackhas(sptrack *t, uint64_t id) { uint32_t pos = id % t->size; for (;;) { if (spunlikely(t->i[pos] == 0)) return 0; if (t->i[pos] == id) return 1; pos = (pos + 1) % t->size; continue; } return 0; } #endif