123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- module.exports = (function() {
- var __MODS__ = {};
- var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; };
- var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
- var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
- var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
- __DEFINE__(1682324647526, function(require, module, exports) {
- // Copyright Takatoshi Kondo 2021
- //
- // Distributed under the MIT License
- const NumberAllocator = require('./lib/number-allocator.js')
- module.exports.NumberAllocator = NumberAllocator
- }, function(modId) {var map = {"./lib/number-allocator.js":1682324647527}; return __REQUIRE__(map[modId], modId); })
- __DEFINE__(1682324647527, function(require, module, exports) {
- // Copyright Takatoshi Kondo 2021
- //
- // Distributed under the MIT License
- const SortedSet = require('js-sdsl').OrderedSet
- const debugTrace = require('debug')('number-allocator:trace')
- const debugError = require('debug')('number-allocator:error')
- /**
- * Interval constructor
- * @constructor
- * @param {Number} low - The lowest value of the interval
- * @param {Number} high - The highest value of the interval
- */
- function Interval (low, high) {
- this.low = low
- this.high = high
- }
- Interval.prototype.equals = function (other) {
- return this.low === other.low && this.high === other.high
- }
- Interval.prototype.compare = function (other) {
- if (this.low < other.low && this.high < other.low) return -1
- if (other.low < this.low && other.high < this.low) return 1
- return 0
- }
- /**
- * NumberAllocator constructor.
- * The all numbers are set to vacant status.
- * Time Complexity O(1)
- * @constructor
- * @param {Number} min - The maximum number of allocatable. The number must be integer.
- * @param {Number} maxh - The minimum number of allocatable. The number must be integer.
- */
- function NumberAllocator (min, max) {
- if (!(this instanceof NumberAllocator)) {
- return new NumberAllocator(min, max)
- }
- this.min = min
- this.max = max
- this.ss = new SortedSet(
- [],
- (lhs, rhs) => {
- return lhs.compare(rhs)
- }
- )
- debugTrace('Create')
- this.clear()
- }
- /**
- * Get the first vacant number. The status of the number is not updated.
- * Time Complexity O(1)
- * @return {Number} - The first vacant number. If all numbers are occupied, return null.
- * When alloc() is called then the same value will be allocated.
- */
- NumberAllocator.prototype.firstVacant = function () {
- if (this.ss.size() === 0) return null
- return this.ss.front().low
- }
- /**
- * Allocate the first vacant number. The number become occupied status.
- * Time Complexity O(1)
- * @return {Number} - The first vacant number. If all numbers are occupied, return null.
- */
- NumberAllocator.prototype.alloc = function () {
- if (this.ss.size() === 0) {
- debugTrace('alloc():empty')
- return null
- }
- const it = this.ss.begin()
- const low = it.pointer.low
- const high = it.pointer.high
- const num = low
- if (num + 1 <= high) {
- // x|----|
- this.ss.updateKeyByIterator(it, new Interval(low + 1, high))
- } else {
- this.ss.eraseElementByPos(0)
- }
- debugTrace('alloc():' + num)
- return num
- }
- /**
- * Use the number. The number become occupied status.
- * If the number has already been occupied, then return false.
- * Time Complexity O(logN) : N is the number of intervals (not numbers)
- * @param {Number} num - The number to request use.
- * @return {Boolean} - If `num` was not occupied, then return true, otherwise return false.
- */
- NumberAllocator.prototype.use = function (num) {
- const key = new Interval(num, num)
- const it = this.ss.lowerBound(key)
- if (!it.equals(this.ss.end())) {
- const low = it.pointer.low
- const high = it.pointer.high
- if (it.pointer.equals(key)) {
- // |x|
- this.ss.eraseElementByIterator(it)
- debugTrace('use():' + num)
- return true
- }
- // x |-----|
- if (low > num) return false
- // |x----|
- if (low === num) {
- // x|----|
- this.ss.updateKeyByIterator(it, new Interval(low + 1, high))
- debugTrace('use():' + num)
- return true
- }
- // |----x|
- if (high === num) {
- // |----|x
- this.ss.updateKeyByIterator(it, new Interval(low, high - 1))
- debugTrace('use():' + num)
- return true
- }
- // |--x--|
- // x|--|
- this.ss.updateKeyByIterator(it, new Interval(num + 1, high))
- // |--|x|--|
- this.ss.insert(new Interval(low, num - 1))
- debugTrace('use():' + num)
- return true
- }
- debugTrace('use():failed')
- return false
- }
- /**
- * Deallocate the number. The number become vacant status.
- * Time Complexity O(logN) : N is the number of intervals (not numbers)
- * @param {Number} num - The number to deallocate. The number must be occupied status.
- * In other words, the number must be allocated by alloc() or occupied be use().
- */
- NumberAllocator.prototype.free = function (num) {
- if (num < this.min || num > this.max) {
- debugError('free():' + num + ' is out of range')
- return
- }
- const key = new Interval(num, num)
- const it = this.ss.upperBound(key)
- if (it.equals(this.ss.end())) {
- // ....v
- if (it.equals(this.ss.begin())) {
- // Insert new interval
- this.ss.insert(key)
- return
- }
- it.pre()
- const low = it.pointer.high
- const high = it.pointer.high
- if (high + 1 === num) {
- // Concat to left
- this.ss.updateKeyByIterator(it, new Interval(low, num))
- } else {
- // Insert new interval
- this.ss.insert(key)
- }
- } else {
- if (it.equals(this.ss.begin())) {
- // v....
- if (num + 1 === it.pointer.low) {
- // Concat to right
- const low = it.pointer.high - 1
- const high = it.pointer.high
- this.ss.updateKeyByIterator(it, new Interval(low, high))
- } else {
- // Insert new interval
- this.ss.insert(key)
- }
- } else {
- // ..v..
- const rLow = it.pointer.low
- const rHigh = it.pointer.high
- it.pre()
- const lLow = it.pointer.low
- const lHigh = it.pointer.high
- if (lHigh + 1 === num) {
- if (num + 1 === rLow) {
- // Concat to left and right
- this.ss.eraseElementByIterator(it)
- const high = it.pointer.high
- this.ss.updateKeyByIterator(it, new Interval(lLow, high))
- } else {
- // Concat to left
- this.ss.updateKeyByIterator(it, new Interval(lLow, num))
- }
- } else {
- if (num + 1 === rLow) {
- // Concat to right
- this.ss.eraseElementByIterator(it.next())
- this.ss.insert(new Interval(num, rHigh))
- } else {
- // Insert new interval
- this.ss.insert(key)
- }
- }
- }
- }
- debugTrace('free():' + num)
- }
- /**
- * Clear all occupied numbers.
- * The all numbers are set to vacant status.
- * Time Complexity O(1)
- */
- NumberAllocator.prototype.clear = function () {
- debugTrace('clear()')
- this.ss.clear()
- this.ss.insert(new Interval(this.min, this.max))
- }
- /**
- * Get the number of intervals. Interval is internal structure of this library.
- * This function is for debugging.
- * Time Complexity O(1)
- * @return {Number} - The number of intervals.
- */
- NumberAllocator.prototype.intervalCount = function () {
- return this.ss.size()
- }
- /**
- * Dump the internal structor of the library.
- * This function is for debugging.
- * Time Complexity O(N) : N is the number of intervals (not numbers)
- */
- NumberAllocator.prototype.dump = function () {
- console.log('length:' + this.ss.size())
- for (const element of this.ss) {
- console.log(element)
- }
- }
- module.exports = NumberAllocator
- }, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
- return __REQUIRE__(1682324647526);
- })()
- //miniprogram-npm-outsideDeps=["js-sdsl","debug"]
- //# sourceMappingURL=index.js.map
|