@jawis/shared-algs
Version:
Data structures for building concurrent programs.
132 lines (131 loc) • 3.97 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SharedValidityVector = void 0;
const _jab_1 = require("^jab");
/**
*
* - Stores index version, to be able to detect invalid references.
*
* notes
* - Linear complexity. Suited for base cases in larger structures.
*
* todo
* - quick fix: uses one word per validity bit.
*/
class SharedValidityVector {
/**
*
*/
constructor(deps) {
this.deps = deps;
/**
*
*/
this.get = () => {
const index = this.tryGet();
if (index === undefined) {
throw new Error("Not enough space to allocate more indexes, max: " + this.deps.size); // prettier-ignore
}
return index;
};
/**
*
*/
this.tryGet = () => {
for (let i = 0; i < this.deps.size; i++) {
if (this.deps.sharedArray[i] === 0) {
let version = 1; //default
if (this.deps.useChunkVersion) {
version = Math.floor(Math.random() * 15) + 1; //max 4 bits, and never zero.
}
this.deps.sharedArray[i] = version;
return { index: i, version };
}
}
//nothing found
return;
};
/**
*
*/
this.invalidate = (index, version) => {
if (index < 0 || index >= this.deps.size) {
throw new Error("Index out of range: " + index);
}
//assert valid.
if (this.deps.sharedArray[index] !== version) {
throw new Error("The index is invalid: " + index);
}
//set invalid
this.deps.sharedArray[index] = 0;
};
/**
*
*/
this.isValid = (index, version) => {
if (index < 0 || index >= this.deps.size) {
throw new Error("Index out of range: " + index);
}
return this.deps.sharedArray[index] === version;
};
/**
*
*/
this.isFull = () => {
for (let i = 0; i < this.deps.size; i++) {
if (this.deps.sharedArray[i] === 0) {
return false;
}
}
return true;
};
/**
*
*/
this.isEmpty = () => {
for (let i = 0; i < this.deps.size; i++) {
if (this.deps.sharedArray[i] !== 0) {
return false;
}
}
return true;
};
/**
*
*/
this.getCount = () => {
let count = 0;
for (let i = 0; i < this.deps.size; i++) {
if (this.deps.sharedArray[i] !== 0) {
count++;
}
}
return count;
};
const minimum = SharedValidityVector.getExpectedByteSize(this.deps.size);
if (this.deps.sharedArray.byteLength < minimum) {
(0, _jab_1.err)("SharedArray should minimum have byte size " + minimum + ", was:" + this.deps.sharedArray.byteLength); // prettier-ignore
}
this.deps.size = deps.size;
}
/**
*
*/
*[Symbol.iterator]() {
for (let i = 0; i < this.deps.size; i++) {
const version = this.deps.sharedArray[i];
if (version !== 0) {
yield { index: i, version };
}
}
}
}
exports.SharedValidityVector = SharedValidityVector;
_a = SharedValidityVector;
SharedValidityVector.BYTE_OVERHEAD = 4; //overhead comprise version and valid bit.
SharedValidityVector.BLOCK_SIZE = 1; //size of the blocks that are allocated.
/**
*
*/
SharedValidityVector.getExpectedByteSize = (n) => Math.ceil(n / _a.BLOCK_SIZE) * _a.BLOCK_SIZE * _a.BYTE_OVERHEAD;