molstar
Version:
A comprehensive macromolecular library.
187 lines (186 loc) • 6.04 kB
JavaScript
/**
* Copyright (c) 2017 Mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
// TODO check if the removal of FastSet and the removal of the context object for forEach
// have any performance implications
function _ascSort(a, b) {
return a - b;
}
export function sortAsc(array) {
Array.prototype.sort.call(array, _ascSort);
return array;
}
var Mask;
(function (Mask) {
var EmptyMask = /** @class */ (function () {
function EmptyMask() {
this.size = 0;
}
EmptyMask.prototype.has = function (i) { return false; };
EmptyMask.prototype.forEach = function (f, ctx) { return ctx; };
return EmptyMask;
}());
var SingletonMask = /** @class */ (function () {
function SingletonMask(idx) {
this.idx = idx;
this.size = 1;
}
SingletonMask.prototype.has = function (i) { return i === this.idx; };
SingletonMask.prototype.forEach = function (f, ctx) { f(this.idx, ctx); return ctx; };
return SingletonMask;
}());
var BitMask = /** @class */ (function () {
function BitMask(mask, size) {
this.mask = mask;
this.size = size;
this.length = mask.length;
}
BitMask.prototype.has = function (i) { return i < this.length && !!this.mask[i]; };
BitMask.prototype._forEach = function (f, ctx) {
for (var i = 0; i < this.length; i++) {
if (this.mask[i])
f(i, ctx);
}
};
BitMask.prototype.forEach = function (f, ctx) {
this._forEach(f, ctx);
return ctx;
};
return BitMask;
}());
var AllMask = /** @class */ (function () {
function AllMask(size) {
this.size = size;
}
AllMask.prototype.has = function (i) { return true; };
AllMask.prototype._forEach = function (f, ctx) {
for (var i = 0; i < this.size; i++) {
f(i, ctx);
}
};
AllMask.prototype.forEach = function (f, ctx) {
this._forEach(f, ctx);
return ctx;
};
return AllMask;
}());
var SetMask = /** @class */ (function () {
function SetMask(set) {
this.set = set;
this._flat = void 0;
this.size = set.size;
}
SetMask.prototype.has = function (i) { return this.set.has(i); };
SetMask.prototype._forEach = function (f, ctx) {
for (var _i = 0, _a = this.flatten(); _i < _a.length; _i++) {
var idx = _a[_i];
f(idx, ctx);
}
};
SetMask.prototype.flatten = function () {
if (this._flat)
return this._flat;
var indices = new Int32Array(this.size);
var offset = 0;
this.set.forEach(function (i) { return indices[offset++] = i; });
sortAsc(indices);
this._flat = indices;
return this._flat;
};
SetMask.prototype.forEach = function (f, ctx) {
this._forEach(f, ctx);
return ctx;
};
return SetMask;
}());
function always(size) { return new AllMask(size); }
Mask.always = always;
Mask.never = new EmptyMask();
function ofSet(set) {
return new SetMask(set);
}
Mask.ofSet = ofSet;
function singleton(i) {
return new SingletonMask(i);
}
Mask.singleton = singleton;
function ofUniqueIndices(indices) {
var len = indices.length;
if (len === 0)
return new EmptyMask();
if (len === 1)
return new SingletonMask(indices[0]);
var max = 0;
for (var _i = 0, _a = indices; _i < _a.length; _i++) {
var i = _a[_i];
if (i > max)
max = i;
}
if (len === max)
return new AllMask(len);
var f = len / max;
if (f < 1 / 12) {
var set = new Set();
for (var _b = 0, _c = indices; _b < _c.length; _b++) {
var i = _c[_b];
set.add(i);
}
return new SetMask(set);
}
var mask = new Int8Array(max + 1);
for (var _d = 0, _e = indices; _d < _e.length; _d++) {
var i = _e[_d];
mask[i] = 1;
}
return new BitMask(mask, indices.length);
}
Mask.ofUniqueIndices = ofUniqueIndices;
function ofMask(mask, size) {
return new BitMask(mask, size);
}
Mask.ofMask = ofMask;
function hasAny(mask, xs) {
for (var _i = 0, xs_1 = xs; _i < xs_1.length; _i++) {
var x = xs_1[_i];
if (mask.has(x))
return true;
}
return false;
}
Mask.hasAny = hasAny;
function complement(mask, against) {
var count = 0;
var max = 0;
against.forEach(function (i) {
if (!mask.has(i)) {
count++;
if (i > max)
max = i;
}
});
if (count / max < 1 / 12) {
// set based
var set_1 = new Set();
against.forEach(function (i) {
if (!mask.has(i)) {
set_1.add(i);
}
});
return ofSet(set_1);
}
else {
// mask based
var target_1 = new Uint8Array(max + 1);
against.forEach(function (i) {
if (!mask.has(i)) {
target_1[i] = 1;
}
});
return ofMask(target_1, count);
}
}
Mask.complement = complement;
})(Mask || (Mask = {}));
export { Mask };