Files
dealplustech/dealplustech-astro/node_modules/@libsql/hrana-client/lib-esm/id_alloc.js
Kunthawat b2e427791b feat: Add complete PDPA compliance pages
- Admin dashboard (/admin/consent-logs) with password auth
- Consent API (/api/consent) with SQLite + IP hashing
- Privacy Policy (Thai) - PDPA Section 36 compliant
- Terms & Conditions (Thai) - 9 standard clauses
- .env.example template with Umami placeholder

All pages preserve current design system.
2026-03-10 21:28:23 +07:00

48 lines
1.8 KiB
JavaScript

import { InternalError } from "./errors.js";
// An allocator of non-negative integer ids.
//
// This clever data structure has these "ideal" properties:
// - It consumes memory proportional to the number of used ids (which is optimal).
// - All operations are O(1) time.
// - The allocated ids are small (with a slight modification, we could always provide the smallest possible
// id).
export class IdAlloc {
// Set of all allocated ids
#usedIds;
// Set of all free ids lower than `#usedIds.size`
#freeIds;
constructor() {
this.#usedIds = new Set();
this.#freeIds = new Set();
}
// Returns an id that was free, and marks it as used.
alloc() {
// this "loop" is just a way to pick an arbitrary element from the `#freeIds` set
for (const freeId of this.#freeIds) {
this.#freeIds.delete(freeId);
this.#usedIds.add(freeId);
// maintain the invariant of `#freeIds`
if (!this.#usedIds.has(this.#usedIds.size - 1)) {
this.#freeIds.add(this.#usedIds.size - 1);
}
return freeId;
}
// the `#freeIds` set is empty, so there are no free ids lower than `#usedIds.size`
// this means that `#usedIds` is a set that contains all numbers from 0 to `#usedIds.size - 1`,
// so `#usedIds.size` is free
const freeId = this.#usedIds.size;
this.#usedIds.add(freeId);
return freeId;
}
free(id) {
if (!this.#usedIds.delete(id)) {
throw new InternalError("Freeing an id that is not allocated");
}
// maintain the invariant of `#freeIds`
this.#freeIds.delete(this.#usedIds.size);
if (id < this.#usedIds.size) {
this.#freeIds.add(id);
}
}
}