@thi.ng/idgen
Advanced tools
Comparing version 0.2.28 to 0.2.29
@@ -6,2 +6,13 @@ # Change Log | ||
## [0.2.29](https://github.com/thi-ng/umbrella/compare/@thi.ng/idgen@0.2.28...@thi.ng/idgen@0.2.29) (2021-01-02) | ||
### Performance Improvements | ||
* **idgen:** minor updates IDGen, add doc strings ([1c0e284](https://github.com/thi-ng/umbrella/commit/1c0e284e9f48d4a37a55f74db0fb2b6eade9dc89)) | ||
## [0.2.28](https://github.com/thi-ng/umbrella/compare/@thi.ng/idgen@0.2.27...@thi.ng/idgen@0.2.28) (2020-12-22) | ||
@@ -8,0 +19,0 @@ |
@@ -14,4 +14,14 @@ import { Event, IClear, INotify, Listener } from "@thi.ng/api"; | ||
protected shift: number; | ||
constructor(bits?: number, vbits?: number, cap?: number, next?: number); | ||
constructor(bits?: number, vbits?: number, cap?: number, start?: number); | ||
/** | ||
* Extract actual ID (without version bits). | ||
* | ||
* @param id | ||
*/ | ||
id(id: number): number; | ||
/** | ||
* Extract version from ID | ||
* | ||
* @param id | ||
*/ | ||
version(id: number): number; | ||
@@ -26,7 +36,7 @@ get capacity(): number; | ||
/** | ||
* Number of available IDs. | ||
* Number of remaining available IDs. | ||
*/ | ||
get available(): number; | ||
/** | ||
* Number of used IDs. | ||
* Number of currently used IDs. | ||
*/ | ||
@@ -40,3 +50,3 @@ get used(): number; | ||
/** | ||
* Frees all existing IDs and resets counter to zero. | ||
* Frees all existing IDs and resets counter to original start ID. | ||
*/ | ||
@@ -46,3 +56,3 @@ clear(): void; | ||
* Returns next available ID or throws error (assertion) if no further IDs | ||
* are currently available. | ||
* are currently available. Emits {@link EVENT_ADDED} if successful. | ||
*/ | ||
@@ -52,3 +62,3 @@ next(): number; | ||
* Marks given ID as available again and increases its version (if | ||
* versioning is enabled). | ||
* versioning is enabled). Emits {@link EVENT_REMOVED} if successful. | ||
* | ||
@@ -72,3 +82,17 @@ * @param id | ||
} | ||
export declare const idgen: (bits: number, vbits?: number | undefined, cap?: number | undefined, next?: number | undefined) => IDGen; | ||
/** | ||
* Returns a new {@link IDGen} instance configured to use given counter & | ||
* version bits. | ||
* | ||
* @remarks | ||
* Overall ID range/capacity can be explicitly limited using `cap` (default and | ||
* maximum: 2^bits). The start ID can be defined via `start` (default: 0) and | ||
* MUST be < `cap`. | ||
* | ||
* @param bits | ||
* @param vbits | ||
* @param cap | ||
* @param start | ||
*/ | ||
export declare const idgen: (bits: number, vbits?: number | undefined, cap?: number | undefined, start?: number | undefined) => IDGen; | ||
//# sourceMappingURL=index.d.ts.map |
53
index.js
@@ -6,3 +6,3 @@ import { __decorate } from "tslib"; | ||
let IDGen = class IDGen { | ||
constructor(bits = 32, vbits = 32 - bits, cap = 2 ** bits, next = 0) { | ||
constructor(bits = 32, vbits = 32 - bits, cap = 2 ** bits, start = 0) { | ||
const maxCap = 2 ** bits; | ||
@@ -12,4 +12,4 @@ assert(bits > 0 && bits + vbits <= 32, "wrong total bit size [1..32]"); | ||
this.ids = []; | ||
this.nextID = next; | ||
this.start = next; | ||
this.nextID = start; | ||
this.start = start; | ||
this._capacity = cap; | ||
@@ -22,5 +22,15 @@ this.num = 0; | ||
} | ||
/** | ||
* Extract actual ID (without version bits). | ||
* | ||
* @param id | ||
*/ | ||
id(id) { | ||
return id & this.mask; | ||
} | ||
/** | ||
* Extract version from ID | ||
* | ||
* @param id | ||
*/ | ||
version(id) { | ||
@@ -51,3 +61,3 @@ return (id >>> this.shift) & this.vmask; | ||
/** | ||
* Number of available IDs. | ||
* Number of remaining available IDs. | ||
*/ | ||
@@ -58,3 +68,3 @@ get available() { | ||
/** | ||
* Number of used IDs. | ||
* Number of currently used IDs. | ||
*/ | ||
@@ -71,5 +81,6 @@ get used() { | ||
*[Symbol.iterator]() { | ||
const { ids, mask } = this; | ||
for (let i = this.nextID; --i >= 0;) { | ||
const id = this.ids[i]; | ||
if ((id & this.mask) === i) | ||
const id = ids[i]; | ||
if ((id & mask) === i) | ||
yield id; | ||
@@ -79,3 +90,3 @@ } | ||
/** | ||
* Frees all existing IDs and resets counter to zero. | ||
* Frees all existing IDs and resets counter to original start ID. | ||
*/ | ||
@@ -90,3 +101,3 @@ clear() { | ||
* Returns next available ID or throws error (assertion) if no further IDs | ||
* are currently available. | ||
* are currently available. Emits {@link EVENT_ADDED} if successful. | ||
*/ | ||
@@ -97,3 +108,3 @@ next() { | ||
id = this._freeID; | ||
const rawID = this.id(id); | ||
const rawID = id & this.mask; | ||
this._freeID = this.ids[rawID]; | ||
@@ -113,3 +124,3 @@ this.ids[rawID] = id; | ||
* Marks given ID as available again and increases its version (if | ||
* versioning is enabled). | ||
* versioning is enabled). Emits {@link EVENT_REMOVED} if successful. | ||
* | ||
@@ -121,3 +132,3 @@ * @param id | ||
return false; | ||
this.ids[this.id(id)] = this._freeID; | ||
this.ids[id & this.mask] = this._freeID; | ||
this._freeID = this.nextVersion(id); | ||
@@ -134,3 +145,3 @@ this.num--; | ||
has(id) { | ||
const rawID = this.id(id); | ||
const rawID = id & this.mask; | ||
return id >= 0 && rawID < this.nextID && this.ids[rawID] === id; | ||
@@ -157,2 +168,16 @@ } | ||
export { IDGen }; | ||
export const idgen = (bits, vbits, cap, next) => new IDGen(bits, vbits, cap, next); | ||
/** | ||
* Returns a new {@link IDGen} instance configured to use given counter & | ||
* version bits. | ||
* | ||
* @remarks | ||
* Overall ID range/capacity can be explicitly limited using `cap` (default and | ||
* maximum: 2^bits). The start ID can be defined via `start` (default: 0) and | ||
* MUST be < `cap`. | ||
* | ||
* @param bits | ||
* @param vbits | ||
* @param cap | ||
* @param start | ||
*/ | ||
export const idgen = (bits, vbits, cap, start) => new IDGen(bits, vbits, cap, start); |
@@ -11,3 +11,3 @@ 'use strict'; | ||
exports.IDGen = class IDGen { | ||
constructor(bits = 32, vbits = 32 - bits, cap = 2 ** bits, next = 0) { | ||
constructor(bits = 32, vbits = 32 - bits, cap = 2 ** bits, start = 0) { | ||
const maxCap = 2 ** bits; | ||
@@ -17,4 +17,4 @@ api.assert(bits > 0 && bits + vbits <= 32, "wrong total bit size [1..32]"); | ||
this.ids = []; | ||
this.nextID = next; | ||
this.start = next; | ||
this.nextID = start; | ||
this.start = start; | ||
this._capacity = cap; | ||
@@ -59,5 +59,6 @@ this.num = 0; | ||
*[Symbol.iterator]() { | ||
const { ids, mask } = this; | ||
for (let i = this.nextID; --i >= 0;) { | ||
const id = this.ids[i]; | ||
if ((id & this.mask) === i) | ||
const id = ids[i]; | ||
if ((id & mask) === i) | ||
yield id; | ||
@@ -76,3 +77,3 @@ } | ||
id = this._freeID; | ||
const rawID = this.id(id); | ||
const rawID = id & this.mask; | ||
this._freeID = this.ids[rawID]; | ||
@@ -93,3 +94,3 @@ this.ids[rawID] = id; | ||
return false; | ||
this.ids[this.id(id)] = this._freeID; | ||
this.ids[id & this.mask] = this._freeID; | ||
this._freeID = this.nextVersion(id); | ||
@@ -101,3 +102,3 @@ this.num--; | ||
has(id) { | ||
const rawID = this.id(id); | ||
const rawID = id & this.mask; | ||
return id >= 0 && rawID < this.nextID && this.ids[rawID] === id; | ||
@@ -117,3 +118,3 @@ } | ||
], exports.IDGen); | ||
const idgen = (bits, vbits, cap, next) => new exports.IDGen(bits, vbits, cap, next); | ||
const idgen = (bits, vbits, cap, start) => new exports.IDGen(bits, vbits, cap, start); | ||
@@ -120,0 +121,0 @@ exports.EVENT_ADDED = EVENT_ADDED; |
@@ -1,1 +0,1 @@ | ||
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports,require("tslib"),require("@thi.ng/api")):"function"==typeof define&&define.amd?define(["exports","tslib","@thi.ng/api"],i):i(((t="undefined"!=typeof globalThis?globalThis:t||self).thi=t.thi||{},t.thi.ng=t.thi.ng||{},t.thi.ng.idgen={}),t.thi.ng[""],t.thi.ng.api)}(this,(function(t,i,e){"use strict";const s="added",h="removed";t.IDGen=class{constructor(t=32,i=32-t,s=2**t,h=0){const n=2**t;e.assert(t>0&&t+i<=32,"wrong total bit size [1..32]"),e.assert(s<=n,`requested capacity too large for bit size (max. ${n})`),this.ids=[],this.nextID=h,this.start=h,this._capacity=s,this.num=0,this.mask=n-1,this.vmask=(1<<i)-1,this.shift=t,this._freeID=-1}id(t){return t&this.mask}version(t){return t>>>this.shift&this.vmask}get capacity(){return this._capacity}set capacity(t){if(e.assert(!this.vmask,"can't change capacity w/ versioning enabled"),!(t>=this.mask+1))throw new Error("can't reduce capacity");{const i=Math.ceil(Math.log2(t));e.assert(i>0&&i<=32,"wrong bit size for new capacity [1..32]"),this._capacity=t,this.mask=2**i-1,this.shift=i}}get available(){return this._capacity-this.num-this.start}get used(){return this.num}get freeID(){return this._freeID}*[Symbol.iterator](){for(let t=this.nextID;--t>=0;){const i=this.ids[t];(i&this.mask)===t&&(yield i)}}clear(){this.ids.length=0,this.nextID=this.start,this.num=0,this._freeID=-1}next(){let t;if(-1!==this._freeID){t=this._freeID;const i=this.id(t);this._freeID=this.ids[i],this.ids[i]=t}else e.assert(this.nextID<this._capacity,"max capacity reached"),t=this.nextID++,this.ids[t]=t;return this.num++,this.notify({id:s,target:this,value:t}),t}free(t){return!!this.has(t)&&(this.ids[this.id(t)]=this._freeID,this._freeID=this.nextVersion(t),this.num--,this.notify({id:h,target:this,value:t}),!0)}has(t){const i=this.id(t);return t>=0&&i<this.nextID&&this.ids[i]===t}addListener(t,i,e){}removeListener(t,i,e){}notify(t){}nextVersion(t){return(t&this.mask|(this.version(t)+1&this.vmask)<<this.shift)>>>0}},t.IDGen=i.__decorate([e.INotifyMixin],t.IDGen);t.EVENT_ADDED=s,t.EVENT_REMOVED=h,t.idgen=(i,e,s,h)=>new t.IDGen(i,e,s,h),Object.defineProperty(t,"__esModule",{value:!0})})); | ||
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports,require("tslib"),require("@thi.ng/api")):"function"==typeof define&&define.amd?define(["exports","tslib","@thi.ng/api"],i):i(((t="undefined"!=typeof globalThis?globalThis:t||self).thi=t.thi||{},t.thi.ng=t.thi.ng||{},t.thi.ng.idgen={}),t.thi.ng[""],t.thi.ng.api)}(this,(function(t,i,e){"use strict";const s="added",h="removed";t.IDGen=class{constructor(t=32,i=32-t,s=2**t,h=0){const n=2**t;e.assert(t>0&&t+i<=32,"wrong total bit size [1..32]"),e.assert(s<=n,`requested capacity too large for bit size (max. ${n})`),this.ids=[],this.nextID=h,this.start=h,this._capacity=s,this.num=0,this.mask=n-1,this.vmask=(1<<i)-1,this.shift=t,this._freeID=-1}id(t){return t&this.mask}version(t){return t>>>this.shift&this.vmask}get capacity(){return this._capacity}set capacity(t){if(e.assert(!this.vmask,"can't change capacity w/ versioning enabled"),!(t>=this.mask+1))throw new Error("can't reduce capacity");{const i=Math.ceil(Math.log2(t));e.assert(i>0&&i<=32,"wrong bit size for new capacity [1..32]"),this._capacity=t,this.mask=2**i-1,this.shift=i}}get available(){return this._capacity-this.num-this.start}get used(){return this.num}get freeID(){return this._freeID}*[Symbol.iterator](){const{ids:t,mask:i}=this;for(let e=this.nextID;--e>=0;){const s=t[e];(s&i)===e&&(yield s)}}clear(){this.ids.length=0,this.nextID=this.start,this.num=0,this._freeID=-1}next(){let t;if(-1!==this._freeID){t=this._freeID;const i=t&this.mask;this._freeID=this.ids[i],this.ids[i]=t}else e.assert(this.nextID<this._capacity,"max capacity reached"),t=this.nextID++,this.ids[t]=t;return this.num++,this.notify({id:s,target:this,value:t}),t}free(t){return!!this.has(t)&&(this.ids[t&this.mask]=this._freeID,this._freeID=this.nextVersion(t),this.num--,this.notify({id:h,target:this,value:t}),!0)}has(t){const i=t&this.mask;return t>=0&&i<this.nextID&&this.ids[i]===t}addListener(t,i,e){}removeListener(t,i,e){}notify(t){}nextVersion(t){return(t&this.mask|(this.version(t)+1&this.vmask)<<this.shift)>>>0}},t.IDGen=i.__decorate([e.INotifyMixin],t.IDGen);t.EVENT_ADDED=s,t.EVENT_REMOVED=h,t.idgen=(i,e,s,h)=>new t.IDGen(i,e,s,h),Object.defineProperty(t,"__esModule",{value:!0})})); |
{ | ||
"name": "@thi.ng/idgen", | ||
"version": "0.2.28", | ||
"version": "0.2.29", | ||
"description": "Generator of opaque numeric identifiers with optional support for ID versioning and efficient re-use", | ||
@@ -36,3 +36,3 @@ "module": "./index.js", | ||
"doc:readme": "ts-node -P ../../tools/tsconfig.json ../../tools/src/readme.ts", | ||
"doc": "node_modules/.bin/typedoc --mode modules --out doc --theme ../../tools/doc/typedoc-theme src", | ||
"doc": "node_modules/.bin/typedoc --excludePrivate --out doc --theme ../../tools/doc/typedoc-theme src/index.ts", | ||
"doc:ae": "mkdir -p .ae/doc .ae/temp && node_modules/.bin/api-extractor run --local --verbose", | ||
@@ -49,7 +49,7 @@ "pub": "yarn build:release && yarn publish --access public" | ||
"ts-node": "^9.1.1", | ||
"typedoc": "^0.19.2", | ||
"typedoc": "^0.20.4", | ||
"typescript": "^4.1.3" | ||
}, | ||
"dependencies": { | ||
"@thi.ng/api": "^6.13.5", | ||
"@thi.ng/api": "^6.13.6", | ||
"tslib": "2.0.1" | ||
@@ -79,3 +79,3 @@ }, | ||
}, | ||
"gitHead": "8fed74edc94bfb65f84e8982e6724619bbfbd1d0" | ||
"gitHead": "a2127bae6d16682027fd94190452b8404bf99a47" | ||
} |
@@ -18,3 +18,3 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
- [ID generator with 16 bit range and no versioning](#id-generator-with-16-bit-range-and-no-versioning) | ||
- [ID generator w/ 24 bit range & 8 bit version range](#id-generator-w--24-bit-range--8-bit-version-range) | ||
- [ID generator w/ 24 bit range & 8 bit version range](#id-generator-w-24-bit-range--8-bit-version-range) | ||
- [IDGen is iterable](#idgen-is-iterable) | ||
@@ -67,3 +67,3 @@ - [Authors](#authors) | ||
Package sizes (gzipped, pre-treeshake): ESM: 843 bytes / CJS: 890 bytes / UMD: 1006 bytes | ||
Package sizes (gzipped, pre-treeshake): ESM: 857 bytes / CJS: 906 bytes / UMD: 1019 bytes | ||
@@ -193,2 +193,2 @@ ## Dependencies | ||
© 2019 - 2020 Karsten Schmidt // Apache Software License 2.0 | ||
© 2019 - 2021 Karsten Schmidt // Apache Software License 2.0 |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
42194
373
Updated@thi.ng/api@^6.13.6