cmpstr
Version:
CmpStr is a lightweight, fast and well performing package for calculating string similarity
115 lines (112 loc) • 3.1 kB
JavaScript
// CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
import { CmpStrUsageError, ErrorUtil } from './Errors.mjs';
class RingPool {
maxSize;
buffers = [];
pointer = 0;
constructor(maxSize) {
this.maxSize = maxSize;
}
acquire(minSize, allowOversize) {
return ErrorUtil.wrap(
() => {
const len = this.buffers.length;
for (let i = 0; i < len; i++) {
const idx = (this.pointer + i) & (len - 1);
const item = this.buffers[idx];
if (
item.size >= minSize &&
(allowOversize || item.size === minSize)
) {
this.pointer = (idx + 1) & (len - 1);
return item;
}
}
return null;
},
`Failed to acquire buffer of size >= ${minSize} from pool`,
{ minSize, allowOversize }
);
}
release(item) {
ErrorUtil.wrap(
() => {
if (this.buffers.length < this.maxSize)
return void [this.buffers.push(item)];
this.buffers[this.pointer] = item;
this.pointer = (this.pointer + 1) % this.maxSize;
},
`Failed to release buffer back to pool`,
{ item }
);
}
clear() {
this.buffers = [];
this.pointer = 0;
}
}
class Pool {
static CONFIG = {
int32: {
type: 'int32',
maxSize: 64,
maxItemSize: 2048,
allowOversize: true
},
'number[]': {
type: 'number[]',
maxSize: 16,
maxItemSize: 1024,
allowOversize: false
},
'string[]': {
type: 'string[]',
maxSize: 2,
maxItemSize: 1024,
allowOversize: false
},
set: { type: 'set', maxSize: 8, maxItemSize: 0, allowOversize: false },
map: { type: 'map', maxSize: 8, maxItemSize: 0, allowOversize: false }
};
static POOLS = {
int32: new RingPool(64),
'number[]': new RingPool(16),
'string[]': new RingPool(2),
set: new RingPool(8),
map: new RingPool(8)
};
static allocate(type, size) {
switch (type) {
case 'int32':
return new Int32Array(size);
case 'number[]':
return new Float64Array(size);
case 'string[]':
return new Array(size);
case 'set':
return new Set();
case 'map':
return new Map();
}
}
static acquire(type, size) {
const CONFIG = this.CONFIG[type];
if (!CONFIG)
throw new CmpStrUsageError(`Unsupported pool type <${type}>`, { type });
if (size > CONFIG.maxItemSize) return this.allocate(type, size);
const item = this.POOLS[type].acquire(size, CONFIG.allowOversize);
if (item)
return type === 'int32' ? item.buffer.subarray(0, size) : item.buffer;
return this.allocate(type, size);
}
static acquireMany(type, sizes) {
return sizes.map((size) => this.acquire(type, size));
}
static release(type, buffer, size) {
const CONFIG = this.CONFIG[type];
if (!CONFIG)
throw new CmpStrUsageError(`Unsupported pool type <${type}>`, { type });
if (size <= CONFIG.maxItemSize) this.POOLS[type].release({ buffer, size });
}
}
export { Pool };