remove node_modules and .gitignore them

This commit is contained in:
2023-11-24 14:40:32 -05:00
parent 5f6e638903
commit a74d7b91b8
8963 changed files with 1 additions and 874175 deletions
-80
View File
@@ -1,80 +0,0 @@
/**
* Barrier for critical sections.
*
* The Barrier class blocks critical sections until the downward counter to be zero. Unlike the
* {@link Latch} class whose downward counter is disposable, `Barrier` can re-use the downward
* counter repeatedly, resetting counter to be initial value whenever reach to the zero.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class Barrier {
private cv_;
private size_;
private count_;
/**
* Initializer Constructor
*
* @param size Size of the downward counter.
*/
constructor(size: number);
/**
* Waits until the counter to be zero.
*
* Blocks the function calling until internal counter to be reached to the zero.
*/
wait(): Promise<void>;
/**
* Tries to wait until the counter to be zero in timeout.
*
* Attempts to block the function calling until internal counter to be reached to the zero
* in timeout. If succeeded to waiting the counter to be reached to the zero, it returns
* `true`. Otherwise, the {@link Barrier} fails to reach to the zero in the given time, the
* function gives up the waiting and returns `false`.
*
* @param ms The maximum miliseconds for waiting.
* @return Whether succeeded to waiting in the given time.
*/
wait_for(ms: number): Promise<boolean>;
/**
* Tries to wait until the counter to be zero in time expiration.
*
* Attempts to block the function calling until internal counter to be reached to the zero
* in time expiration. If succeeded to waiting the counter to be reached to the zero, it
* returns `true`. Otherwise, the {@link Barrier} fails to reach to the zero in the given
* time, the function gives up the waiting and returns `false`.
*
* @param at The maximum time point to wait.
* @return Whether succeeded to waiting in the given time.
*/
wait_until(at: Date): Promise<boolean>;
/**
* Derecements the counter.
*
* Decrements the counter by *n* without blocking.
*
* If the parametric value *n* is equal to or greater than internal counter, so that the
* internal counter be equal to or less than zero, everyone who are {@link wait waiting} for
* the {@link Latch} would continue their executions.
*
* @param n Value of the decrement. Default is 1.
*/
arrive(n?: number): Promise<void>;
/**
* Decrements the counter and waits until the counter to be zero.
*
* Decrements the counter by one and blocks the section until internal counter to be zero.
*
* If the the remained counter be zero by this decrement, everyone who are
* {@link wait waiting} for the {@link Barrier} would continue their executions including
* this one.
*/
arrive_and_wait(): Promise<void>;
/**
* Decrements the counter and initial size at the same time.
*
* Decrements not only internal counter, but also initialize size of the counter at the same
* time. If the remained counter be zero by the decrement, everyone who are
* {@link wait waiting} for the {@link Barrier} would continue their executions.
*/
arrive_and_drop(): Promise<void>;
}
-187
View File
@@ -1,187 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Barrier = void 0;
//================================================================
/**
* @packageDocumentation
* @module std
*/
//================================================================
var ConditionVariable_1 = require("./ConditionVariable");
/**
* Barrier for critical sections.
*
* The Barrier class blocks critical sections until the downward counter to be zero. Unlike the
* {@link Latch} class whose downward counter is disposable, `Barrier` can re-use the downward
* counter repeatedly, resetting counter to be initial value whenever reach to the zero.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var Barrier = /** @class */ (function () {
/**
* Initializer Constructor
*
* @param size Size of the downward counter.
*/
function Barrier(size) {
this.cv_ = new ConditionVariable_1.ConditionVariable();
this.size_ = size;
this.count_ = size;
}
/* ---------------------------------------------------------
WAIT FUNCTIONS
--------------------------------------------------------- */
/**
* Waits until the counter to be zero.
*
* Blocks the function calling until internal counter to be reached to the zero.
*/
Barrier.prototype.wait = function () {
return this.cv_.wait();
};
/**
* Tries to wait until the counter to be zero in timeout.
*
* Attempts to block the function calling until internal counter to be reached to the zero
* in timeout. If succeeded to waiting the counter to be reached to the zero, it returns
* `true`. Otherwise, the {@link Barrier} fails to reach to the zero in the given time, the
* function gives up the waiting and returns `false`.
*
* @param ms The maximum miliseconds for waiting.
* @return Whether succeeded to waiting in the given time.
*/
Barrier.prototype.wait_for = function (ms) {
return this.cv_.wait_for(ms);
};
/**
* Tries to wait until the counter to be zero in time expiration.
*
* Attempts to block the function calling until internal counter to be reached to the zero
* in time expiration. If succeeded to waiting the counter to be reached to the zero, it
* returns `true`. Otherwise, the {@link Barrier} fails to reach to the zero in the given
* time, the function gives up the waiting and returns `false`.
*
* @param at The maximum time point to wait.
* @return Whether succeeded to waiting in the given time.
*/
Barrier.prototype.wait_until = function (at) {
return this.cv_.wait_until(at);
};
/* ---------------------------------------------------------
ARRIVAL FUNCTIONS
--------------------------------------------------------- */
/**
* Derecements the counter.
*
* Decrements the counter by *n* without blocking.
*
* If the parametric value *n* is equal to or greater than internal counter, so that the
* internal counter be equal to or less than zero, everyone who are {@link wait waiting} for
* the {@link Latch} would continue their executions.
*
* @param n Value of the decrement. Default is 1.
*/
Barrier.prototype.arrive = function (n) {
if (n === void 0) { n = 1; }
return __awaiter(this, void 0, void 0, function () {
var completed;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
completed = (this.count_ += n) <= this.size_;
if (completed === false)
return [2 /*return*/];
this.count_ %= this.size_;
return [4 /*yield*/, this.cv_.notify_all()];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Decrements the counter and waits until the counter to be zero.
*
* Decrements the counter by one and blocks the section until internal counter to be zero.
*
* If the the remained counter be zero by this decrement, everyone who are
* {@link wait waiting} for the {@link Barrier} would continue their executions including
* this one.
*/
Barrier.prototype.arrive_and_wait = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.arrive()];
case 1:
_a.sent();
return [4 /*yield*/, this.wait()];
case 2:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Decrements the counter and initial size at the same time.
*
* Decrements not only internal counter, but also initialize size of the counter at the same
* time. If the remained counter be zero by the decrement, everyone who are
* {@link wait waiting} for the {@link Barrier} would continue their executions.
*/
Barrier.prototype.arrive_and_drop = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
--this.size_;
return [4 /*yield*/, this.arrive(0)];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
return Barrier;
}());
exports.Barrier = Barrier;
//# sourceMappingURL=Barrier.js.map
-101
View File
@@ -1,101 +0,0 @@
/**
* Condition variable.
*
* The `ConditionVariable` class blocks critical sections until be notified.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class ConditionVariable {
private resolvers_;
/**
* Default Constructor.
*/
constructor();
/**
* Wait until notified.
*/
wait(): Promise<void>;
/**
* Wait until predicator returns true.
*
* This method is equivalent to:
*
```typescript
while (!await predicator())
await this.wait();
```
*
* @param predicator A predicator function determines completion.
*/
wait(predicator: ConditionVariable.Predicator): Promise<void>;
/**
* Wait for timeout or until notified.
*
* @param ms The maximum miliseconds for waiting.
* @return Whether awaken by notification or timeout.
*/
wait_for(ms: number): Promise<boolean>;
/**
* Wait until timeout or predicator returns true.
*
* This method is equivalent to:
```typescript
const at: Date = new Date(Date.now() + ms);
while (!await predicator())
{
if (!await this.wait_until(at))
return await predicator();
}
return true;
```
*
* @param ms The maximum miliseconds for waiting.
* @param predicator A predicator function determines the completion.
* @return Returned value of the *predicator*.
*/
wait_for(ms: number, predicator: ConditionVariable.Predicator): Promise<boolean>;
/**
* Wait until notified or time expiration.
*
* @param at The maximum time point to wait.
* @return Whether awaken by notification or time expiration.
*/
wait_until(at: Date): Promise<boolean>;
/**
* Wait until time expiration or predicator returns true.
*
* This method is equivalent to:
```typescript
while (!await predicator())
{
if (!await this.wait_until(at))
return await predicator();
}
return true;
```
*
* @param at The maximum time point to wait.
* @param predicator A predicator function determines the completion.
* @return Returned value of the *predicator*.
*/
wait_until(at: Date, predicator: ConditionVariable.Predicator): Promise<boolean>;
private _Wait;
private _Wait_until;
/**
* Notify, wake only one up.
*/
notify_one(): Promise<void>;
/**
* Notify, wake all up.
*/
notify_all(): Promise<void>;
}
/**
*
*/
export declare namespace ConditionVariable {
/**
* Type of predicator function who determines the completion.
*/
type Predicator = () => boolean | Promise<boolean>;
}
-209
View File
@@ -1,209 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConditionVariable = void 0;
//================================================================
/**
* @packageDocumentation
* @module std
*/
//================================================================
var List_1 = require("../container/List");
var global_1 = require("./global");
/**
* Condition variable.
*
* The `ConditionVariable` class blocks critical sections until be notified.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var ConditionVariable = /** @class */ (function () {
/* ---------------------------------------------------------
CONSTRUCTORS
--------------------------------------------------------- */
/**
* Default Constructor.
*/
function ConditionVariable() {
this.resolvers_ = new List_1.List();
}
ConditionVariable.prototype.wait = function (predicator) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!!predicator) return [3 /*break*/, 2];
return [4 /*yield*/, this._Wait()];
case 1: return [2 /*return*/, _a.sent()];
case 2: return [4 /*yield*/, predicator()];
case 3:
if (!!(_a.sent())) return [3 /*break*/, 5];
return [4 /*yield*/, this._Wait()];
case 4:
_a.sent();
return [3 /*break*/, 2];
case 5: return [2 /*return*/];
}
});
});
};
ConditionVariable.prototype.wait_for = function (ms, predicator) {
var at = new Date(Date.now() + ms);
return this.wait_until(at, predicator);
};
ConditionVariable.prototype.wait_until = function (at, predicator) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!!predicator) return [3 /*break*/, 2];
return [4 /*yield*/, this._Wait_until(at)];
case 1: return [2 /*return*/, _a.sent()];
case 2: return [4 /*yield*/, predicator()];
case 3:
if (!!(_a.sent())) return [3 /*break*/, 7];
return [4 /*yield*/, this._Wait_until(at)];
case 4:
if (!!(_a.sent())) return [3 /*break*/, 6];
return [4 /*yield*/, predicator()];
case 5: return [2 /*return*/, _a.sent()];
case 6: return [3 /*break*/, 2];
case 7: return [2 /*return*/, true];
}
});
});
};
ConditionVariable.prototype._Wait = function () {
var _this = this;
return new Promise(function (resolve) {
_this.resolvers_.push_back({
handler: resolve,
lockType: 0 /* LockType.HOLD */,
});
});
};
ConditionVariable.prototype._Wait_until = function (at) {
var _this = this;
return new Promise(function (resolve) {
var it = _this.resolvers_.insert(_this.resolvers_.end(), {
handler: resolve,
lockType: 1 /* LockType.KNOCK */,
});
// AUTOMATIC UNLOCK
(0, global_1.sleep_until)(at).then(function () {
if (it.erased_ === true)
return;
// DO UNLOCK
_this.resolvers_.erase(it); // POP THE LISTENER
resolve(false); // RETURN FAILURE
});
});
};
/* ---------------------------------------------------------
NOTIFIERS
--------------------------------------------------------- */
/**
* Notify, wake only one up.
*/
ConditionVariable.prototype.notify_one = function () {
return __awaiter(this, void 0, void 0, function () {
var it;
return __generator(this, function (_a) {
// NOTHING TO NOTIFY
if (this.resolvers_.empty())
return [2 /*return*/];
it = this.resolvers_.begin();
this.resolvers_.erase(it);
// CALL ITS HANDLER
if (it.value.lockType === 0 /* LockType.HOLD */)
it.value.handler();
else
it.value.handler(true);
return [2 /*return*/];
});
});
};
/**
* Notify, wake all up.
*/
ConditionVariable.prototype.notify_all = function () {
return __awaiter(this, void 0, void 0, function () {
var resolverList, resolverList_1, resolverList_1_1, resolver;
var e_1, _a;
return __generator(this, function (_b) {
// NOTHING TO NOTIFY
if (this.resolvers_.empty())
return [2 /*return*/];
resolverList = this.resolvers_.toJSON();
this.resolvers_.clear();
try {
// ITERATE RESOLVERS
for (resolverList_1 = __values(resolverList), resolverList_1_1 = resolverList_1.next(); !resolverList_1_1.done; resolverList_1_1 = resolverList_1.next()) {
resolver = resolverList_1_1.value;
if (resolver.lockType === 0 /* LockType.HOLD */)
resolver.handler();
else
resolver.handler(true);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (resolverList_1_1 && !resolverList_1_1.done && (_a = resolverList_1.return)) _a.call(resolverList_1);
}
finally { if (e_1) throw e_1.error; }
}
return [2 /*return*/];
});
});
};
return ConditionVariable;
}());
exports.ConditionVariable = ConditionVariable;
//# sourceMappingURL=ConditionVariable.js.map
-90
View File
@@ -1,90 +0,0 @@
/**
* Latch for critical sections.
*
* The `Latch` class blocks critical sections until the downward counter to be zero. Howver,
* unlike {@link Barrier} who can reusable that downward counter be reset whenever reach to the
* zero, downward of the `Latch` is not reusable but diposable.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class Latch {
private cv_;
private count_;
/**
* Initializer Constructor.
*
* @param size Size of the downward counter.
*/
constructor(size: number);
/**
* Waits until the counter to be zero.
*
* Blocks the function calling until internal counter to be reached to the zero.
*
* If the {@link Latch} already has been reached to the zero, it would be returned
* immediately.
*/
wait(): Promise<void>;
/**
* Test whether the counter has been reached to the zero.
*
* The {@link try_wait} function tests whether the internal counter has been reached to the
* zero.
*
* @return Whether reached to zero or not.
*/
try_wait(): Promise<boolean>;
/**
* Tries to wait until the counter to be zero in timeout.
*
* Attempts to block the function calling until internal counter to be reached to the zero
* in timeout. If succeeded to waiting the counter to be reached to the zero, it returns
* `true`. Otherwise, the {@link Latch} fails to reach to the zero in the given time, the
* function gives up the waiting and returns `false`.
*
* If the {@link Latch} already has been reached to the zero, it would return `true` directly.
*
* @param ms The maximum miliseconds for waiting.
* @return Whether succeeded to waiting in the given time.
*/
wait_for(ms: number): Promise<boolean>;
/**
* Tries to wait until the counter to be zero in time expiration.
*
* Attempts to block the function calling until internal counter to be reached to the zero
* in time expiration. If succeeded to waiting the counter to be reached to the zero, it
* returns `true`. Otherwise, the {@link Latch} fails to reach to the zero in the given time,
* the function gives up the waiting and returns `false`.
*
* If the {@link Latch} already has been reached to the zero, it would return `true` directly.
*
* @param at The maximum time point to wait.
* @return Whether succeeded to waiting in the given time.
*/
wait_until(at: Date): Promise<boolean>;
private _Try_wait;
/**
* Derecements the counter.
*
* Decrements the counter by *n* without blocking.
*
* If the parametric value *n* is equal to or greater than internal counter, so that the
* internal counter be equal to or less than zero, everyone who are {@link wait waiting} for
* the {@link Latch} would continue their execution.
*
* @param n Value of the decrement. Default is 1.
*/
count_down(n?: number): Promise<void>;
/**
* Decrements the counter and waits until the counter to be zero.
*
* Decrements the counter by *n* and blocks the section until internal counter to be zero.
*
* If the parametric value *n* is equal to or greater than internal counter, so that the
* internal counter be equal to or less than zero, everyone who are {@link wait waiting} for
* the {@link Latch} would continue their execution including this one.
*
* @param n Value of the decrement. Default is 1.
*/
arrive_and_wait(n?: number): Promise<void>;
}
-226
View File
@@ -1,226 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Latch = void 0;
//================================================================
/**
* @packageDocumentation
* @module std
*/
//================================================================
var ConditionVariable_1 = require("./ConditionVariable");
/**
* Latch for critical sections.
*
* The `Latch` class blocks critical sections until the downward counter to be zero. Howver,
* unlike {@link Barrier} who can reusable that downward counter be reset whenever reach to the
* zero, downward of the `Latch` is not reusable but diposable.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var Latch = /** @class */ (function () {
/* ---------------------------------------------------------
CONSTRUCTORS
--------------------------------------------------------- */
/**
* Initializer Constructor.
*
* @param size Size of the downward counter.
*/
function Latch(size) {
this.cv_ = new ConditionVariable_1.ConditionVariable();
this.count_ = size;
}
/* ---------------------------------------------------------
WAIT FUNCTIONS
--------------------------------------------------------- */
/**
* Waits until the counter to be zero.
*
* Blocks the function calling until internal counter to be reached to the zero.
*
* If the {@link Latch} already has been reached to the zero, it would be returned
* immediately.
*/
Latch.prototype.wait = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this._Try_wait() === false)) return [3 /*break*/, 2];
return [4 /*yield*/, this.cv_.wait()];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/];
}
});
});
};
/**
* Test whether the counter has been reached to the zero.
*
* The {@link try_wait} function tests whether the internal counter has been reached to the
* zero.
*
* @return Whether reached to zero or not.
*/
Latch.prototype.try_wait = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/, this._Try_wait()];
});
});
};
/**
* Tries to wait until the counter to be zero in timeout.
*
* Attempts to block the function calling until internal counter to be reached to the zero
* in timeout. If succeeded to waiting the counter to be reached to the zero, it returns
* `true`. Otherwise, the {@link Latch} fails to reach to the zero in the given time, the
* function gives up the waiting and returns `false`.
*
* If the {@link Latch} already has been reached to the zero, it would return `true` directly.
*
* @param ms The maximum miliseconds for waiting.
* @return Whether succeeded to waiting in the given time.
*/
Latch.prototype.wait_for = function (ms) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this._Try_wait() === true)) return [3 /*break*/, 1];
return [2 /*return*/, true];
case 1: return [4 /*yield*/, this.cv_.wait_for(ms)];
case 2: return [2 /*return*/, _a.sent()];
}
});
});
};
/**
* Tries to wait until the counter to be zero in time expiration.
*
* Attempts to block the function calling until internal counter to be reached to the zero
* in time expiration. If succeeded to waiting the counter to be reached to the zero, it
* returns `true`. Otherwise, the {@link Latch} fails to reach to the zero in the given time,
* the function gives up the waiting and returns `false`.
*
* If the {@link Latch} already has been reached to the zero, it would return `true` directly.
*
* @param at The maximum time point to wait.
* @return Whether succeeded to waiting in the given time.
*/
Latch.prototype.wait_until = function (at) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this._Try_wait() === true)) return [3 /*break*/, 1];
return [2 /*return*/, true];
case 1: return [4 /*yield*/, this.cv_.wait_until(at)];
case 2: return [2 /*return*/, _a.sent()];
}
});
});
};
Latch.prototype._Try_wait = function () {
return this.count_ <= 0;
};
/* -----------------------------------------------------------
ARRIVAL FUNCTIONS
----------------------------------------------------------- */
/**
* Derecements the counter.
*
* Decrements the counter by *n* without blocking.
*
* If the parametric value *n* is equal to or greater than internal counter, so that the
* internal counter be equal to or less than zero, everyone who are {@link wait waiting} for
* the {@link Latch} would continue their execution.
*
* @param n Value of the decrement. Default is 1.
*/
Latch.prototype.count_down = function (n) {
if (n === void 0) { n = 1; }
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.count_ -= n;
if (!(this._Try_wait() === true)) return [3 /*break*/, 2];
return [4 /*yield*/, this.cv_.notify_all()];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/];
}
});
});
};
/**
* Decrements the counter and waits until the counter to be zero.
*
* Decrements the counter by *n* and blocks the section until internal counter to be zero.
*
* If the parametric value *n* is equal to or greater than internal counter, so that the
* internal counter be equal to or less than zero, everyone who are {@link wait waiting} for
* the {@link Latch} would continue their execution including this one.
*
* @param n Value of the decrement. Default is 1.
*/
Latch.prototype.arrive_and_wait = function (n) {
if (n === void 0) { n = 1; }
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.count_down(n)];
case 1:
_a.sent();
return [4 /*yield*/, this.wait()];
case 2:
_a.sent();
return [2 /*return*/];
}
});
});
};
return Latch;
}());
exports.Latch = Latch;
//# sourceMappingURL=Latch.js.map
-105
View File
@@ -1,105 +0,0 @@
/**
* Mutable singleton generator.
*
* The `MutableSingleton` is an asynchronous singleton generator class who guarantees the *lazy
* constructor* to be called *"only one at time"*. The *"only one at time"* would always be
* kepted, even in the race condition.
*
* Create a `MutableSingleton` instance with your custom *lazy constructor* and get the promised
* value through the {@link MutableSingleton.get}() method. The {@link MutableSingleton.get}()
* method would construct the return value following below logics:
*
* - At the first time: calls the *lazy constructor* and returns the value.
* - After the *lazy construction*: returns the pre-constructed value.
* - Race condition:
* - simultaneously call happens during the *lazy construction*.
* - guarantees the *"only one at time"* through a *mutex*.
*
* If you want to reload the promised value, regardless of whether the *lazy construction* has
* been completed or not, call the {@link MutableSingleton.reload}() method. It would call the
* *lazy constructor* forcibly, even if the *lany construction* has been completed in sometime.
*
* @template T Type of the promised value to be lazy-constructed.
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class MutableSingleton<T, Args extends any[] = []> {
/**
* @hidden
*/
private readonly closure_;
/**
* @hidden
*/
private readonly mutex_;
/**
* @hidden
*/
private value_;
/**
* Initializer Constructor.
*
* Create a new `Singleton` instance with the *lazy consturctor*.
*
* @param closure Lazy constructor function returning the promised value.
*/
constructor(closure: (...args: Args) => Promise<T>);
/**
* Reload value.
*
* The `MutableSingleton.reload()` method enforces to call the *lazy constructor*, regardless
* of whether the *lazy construction* has been completed or not. Therefore, even if the *lazy
* construction* has been completed in sometime, the `MutableSingleton.reload()` will call
* the *lazy constructor* again.
*
* @return Re-constructed value.
*/
reload(...args: Args): Promise<T>;
/**
* Configure value.
*
* The `MutableSingleton.set()` method enforces the singleton to have a specific value.
*
* @param value The value to configure
*/
set(value: T): Promise<void>;
/**
* Clear value.
*
* The `MutableSingleton.clear()` is a method clearing cached value.
*
* Therefore, when {@link get} being called, closure of constructor would be reused.
*/
clear(): Promise<void>;
/**
* Get promised value.
*
* `MutableSingleton.get()` method returns the *lazy constructed value*. It guarantees the
* *lazy constructor* to be called *"only one at time"*. It ensures the *"only one at time"*,
* even in the race condition.
*
* If the promised value is not constructed yet (call this method at the first time), the
* *lazy constructor* would be called and returns the promised value. Otherwise, the promised
* value has been already constructed by the *lazy constructor* (this method already had been
* called), returns the pre-generated value.
*
* Also, you don't need to worry anything about the race condition, who may be occured by
* calling the `MutableSingleton.get()` method simultaneously during the *lazy construction*
* is on going. The `MutableSingleton` guarantees the *lazy constructor* to be called
* only one at time by using the {@link UniqueLock.lock} on a {@link Mutex}.
*
* @return The *lazy constructed* value.
*/
get(...args: Args): Promise<T>;
/**
* Test whether the value has been loaded.
*
* The `MutableSingleton.is_loaded()` method tests whether the singleton has coompleted to
* constructing its value or not. If the singleton value is on the construction by the
* {@link MutableSingleton.get} or {@link MutableSingleton.reload} method, the
* `MutableSingleton.is_loaded()` would wait returning value until the construction has been
* completed.
*
* @returns Whether loaded or not
*/
is_loaded(): Promise<boolean>;
}
-304
View File
@@ -1,304 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MutableSingleton = void 0;
//================================================================
/**
* @packageDocumentation
* @module std
*/
//================================================================
var SharedMutex_1 = require("./SharedMutex");
var SharedLock_1 = require("./SharedLock");
var UniqueLock_1 = require("./UniqueLock");
/**
* Mutable singleton generator.
*
* The `MutableSingleton` is an asynchronous singleton generator class who guarantees the *lazy
* constructor* to be called *"only one at time"*. The *"only one at time"* would always be
* kepted, even in the race condition.
*
* Create a `MutableSingleton` instance with your custom *lazy constructor* and get the promised
* value through the {@link MutableSingleton.get}() method. The {@link MutableSingleton.get}()
* method would construct the return value following below logics:
*
* - At the first time: calls the *lazy constructor* and returns the value.
* - After the *lazy construction*: returns the pre-constructed value.
* - Race condition:
* - simultaneously call happens during the *lazy construction*.
* - guarantees the *"only one at time"* through a *mutex*.
*
* If you want to reload the promised value, regardless of whether the *lazy construction* has
* been completed or not, call the {@link MutableSingleton.reload}() method. It would call the
* *lazy constructor* forcibly, even if the *lany construction* has been completed in sometime.
*
* @template T Type of the promised value to be lazy-constructed.
* @author Jeongho Nam - https://github.com/samchon
*/
var MutableSingleton = /** @class */ (function () {
/* ---------------------------------------------------------------
CONSTRUCTORS
--------------------------------------------------------------- */
/**
* Initializer Constructor.
*
* Create a new `Singleton` instance with the *lazy consturctor*.
*
* @param closure Lazy constructor function returning the promised value.
*/
function MutableSingleton(closure) {
this.closure_ = closure;
this.mutex_ = new SharedMutex_1.SharedMutex();
this.value_ = NOT_MOUNTED_YET;
}
/**
* Reload value.
*
* The `MutableSingleton.reload()` method enforces to call the *lazy constructor*, regardless
* of whether the *lazy construction* has been completed or not. Therefore, even if the *lazy
* construction* has been completed in sometime, the `MutableSingleton.reload()` will call
* the *lazy constructor* again.
*
* @return Re-constructed value.
*/
MutableSingleton.prototype.reload = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
var output;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, UniqueLock_1.UniqueLock.lock(this.mutex_, function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.closure_.apply(this, __spreadArray([], __read(args), false))];
case 1:
output = _a.sent();
this.value_ = output;
return [2 /*return*/];
}
});
}); })];
case 1:
_a.sent();
return [2 /*return*/, output];
}
});
});
};
/**
* Configure value.
*
* The `MutableSingleton.set()` method enforces the singleton to have a specific value.
*
* @param value The value to configure
*/
MutableSingleton.prototype.set = function (value) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, UniqueLock_1.UniqueLock.lock(this.mutex_, function () {
_this.value_ = value;
})];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Clear value.
*
* The `MutableSingleton.clear()` is a method clearing cached value.
*
* Therefore, when {@link get} being called, closure of constructor would be reused.
*/
MutableSingleton.prototype.clear = function () {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, UniqueLock_1.UniqueLock.lock(this.mutex_, function () {
_this.value_ = NOT_MOUNTED_YET;
})];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/* ---------------------------------------------------------------
ACCESSORS
--------------------------------------------------------------- */
/**
* Get promised value.
*
* `MutableSingleton.get()` method returns the *lazy constructed value*. It guarantees the
* *lazy constructor* to be called *"only one at time"*. It ensures the *"only one at time"*,
* even in the race condition.
*
* If the promised value is not constructed yet (call this method at the first time), the
* *lazy constructor* would be called and returns the promised value. Otherwise, the promised
* value has been already constructed by the *lazy constructor* (this method already had been
* called), returns the pre-generated value.
*
* Also, you don't need to worry anything about the race condition, who may be occured by
* calling the `MutableSingleton.get()` method simultaneously during the *lazy construction*
* is on going. The `MutableSingleton` guarantees the *lazy constructor* to be called
* only one at time by using the {@link UniqueLock.lock} on a {@link Mutex}.
*
* @return The *lazy constructed* value.
*/
MutableSingleton.prototype.get = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
var output;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
output = NOT_MOUNTED_YET;
return [4 /*yield*/, SharedLock_1.SharedLock.lock(this.mutex_, function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
output = this.value_;
return [2 /*return*/];
});
}); })];
case 1:
_a.sent();
if (!(output === NOT_MOUNTED_YET)) return [3 /*break*/, 3];
return [4 /*yield*/, UniqueLock_1.UniqueLock.lock(this.mutex_, function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
// COULD BE COMPLETED DURING WAITING
if (this.value_ !== NOT_MOUNTED_YET) {
output = this.value_;
return [2 /*return*/];
}
return [4 /*yield*/, this.closure_.apply(this, __spreadArray([], __read(args), false))];
case 1:
// CALL THE LAZY-CONSTRUCTOR
output = _a.sent();
this.value_ = output;
return [2 /*return*/];
}
});
}); })];
case 2:
_a.sent();
_a.label = 3;
case 3: return [2 /*return*/, output];
}
});
});
};
/**
* Test whether the value has been loaded.
*
* The `MutableSingleton.is_loaded()` method tests whether the singleton has coompleted to
* constructing its value or not. If the singleton value is on the construction by the
* {@link MutableSingleton.get} or {@link MutableSingleton.reload} method, the
* `MutableSingleton.is_loaded()` would wait returning value until the construction has been
* completed.
*
* @returns Whether loaded or not
*/
MutableSingleton.prototype.is_loaded = function () {
return __awaiter(this, void 0, void 0, function () {
var loaded;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
loaded = false;
return [4 /*yield*/, SharedLock_1.SharedLock.lock(this.mutex_, function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
loaded = this.value_ !== NOT_MOUNTED_YET;
return [2 /*return*/];
});
}); })];
case 1:
_a.sent();
return [2 /*return*/, loaded];
}
});
});
};
return MutableSingleton;
}());
exports.MutableSingleton = MutableSingleton;
/**
* @hidden
*/
var NOT_MOUNTED_YET = {};
//# sourceMappingURL=MutableSingleton.js.map
-29
View File
@@ -1,29 +0,0 @@
/**
* @packageDocumentation
* @module std
*/
import { ILockable } from "../base/thread/ILockable";
/**
* Mutex.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class Mutex implements ILockable {
private mutex_;
/**
* Default Constructor.
*/
constructor();
/**
* @inheritDoc
*/
lock(): Promise<void>;
/**
* @inheritDoc
*/
try_lock(): Promise<boolean>;
/**
* @inheritDoc
*/
unlock(): Promise<void>;
}
-44
View File
@@ -1,44 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Mutex = void 0;
var SharedTimedMutex_1 = require("./SharedTimedMutex");
/**
* Mutex.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var Mutex = /** @class */ (function () {
/* ---------------------------------------------------------
CONSTRUCTOR
--------------------------------------------------------- */
/**
* Default Constructor.
*/
function Mutex() {
this.mutex_ = new SharedTimedMutex_1.SharedTimedMutex(this);
}
/* ---------------------------------------------------------
LOCK & UNLOCK
--------------------------------------------------------- */
/**
* @inheritDoc
*/
Mutex.prototype.lock = function () {
return this.mutex_.lock();
};
/**
* @inheritDoc
*/
Mutex.prototype.try_lock = function () {
return this.mutex_.try_lock();
};
/**
* @inheritDoc
*/
Mutex.prototype.unlock = function () {
return this.mutex_.unlock();
};
return Mutex;
}());
exports.Mutex = Mutex;
//# sourceMappingURL=Mutex.js.map
-138
View File
@@ -1,138 +0,0 @@
import { ITimedLockable } from "../base/thread/ITimedLockable";
/**
* Counting semaphore.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class Semaphore<Max extends number = number> {
private queue_;
private acquiring_;
private max_;
/**
* Initializer Constructor.
*
* @param max Number of maximum sections acquirable.
*/
constructor(max: Max);
/**
* Get number of maximum sections lockable.
*
* @return Number of maximum sections lockable.
*/
max(): Max;
/**
* Acquires a section.
*
* Acquires a section until be {@link release released}. If all of the sections in the
* semaphore already have been acquired by others, the function call would be blocked until
* one of them returns its acquisition by calling the {@link release} method.
*
* In same reason, if you don't call the {@link release} function after you business, the
* others who want to {@link acquire} a section from the semaphore would be fall into the
* forever sleep. Therefore, never forget to calling the {@link release} function or utilize
* the {@link UniqueLock.lock} function instead with {@link Semaphore.get_lockable} to ensure
* the safety.
*/
acquire(): Promise<void>;
/**
* Tries to acquire a section.
*
* Attempts to acquire a section without blocking. If succeeded to acquire a section from the
* semaphore immediately, it returns `true` directly. Otherwise all of the sections in the
* semaphore are full, the function gives up the trial immediately and returns `false`
* directly.
*
* Note that, if you succeeded to acquire a section from the semaphore (returns `true) but do
* not call the {@link release} function after your business, the others who want to
* {@link acquire} a section from the semaphore would be fall into the forever sleep.
* Therefore, never forget to calling the {@link release} function or utilize the
* {@link UniqueLock.try_lock} function instead with {@link Semaphore.get_lockable} to ensure
* the safety.
*
* @return Whether succeeded to acquire or not.
*/
try_acquire(): Promise<boolean>;
/**
* Tries to acquire a section until timeout.
*
* Attempts to acquire a section from the semaphore until timeout. If succeeded to acquire a
* section until the timeout, it returns `true`. Otherwise failed to acquiring a section in
* given the time, the function gives up the trial and returns `false`.
*
* Failed to acquiring a section in the given time (returns `false`), it means that there're
* someone who have already {@link acquire acquired} sections and do not return them over the
* time expiration.
*
* Note that, if you succeeded to acquire a section from the semaphore (returns `true) but do
* not call the {@link release} function after your business, the others who want to
* {@link acquire} a section from the semaphore would be fall into the forever sleep.
* Therefore, never forget to calling the {@link release} function or utilize the
* {@link UniqueLock.try_acquire_for} function instead with {@link Semaphore.get_lockable} to
* ensure the safety.
*
* @param ms The maximum miliseconds for waiting.
* @return Whether succeded to acquire or not.
*/
try_acquire_for(ms: number): Promise<boolean>;
/**
* Tries to acquire a section until timeout.
*
* Attempts to acquire a section from the semaphore until time expiration. If succeeded to
* acquire a section until the time expiration, it returns `true`. Otherwise failed to
* acquiring a section in the given time, the function gives up the trial and returns `false`.
*
* Failed to acquiring a section in the given time (returns `false`), it means that there're
* someone who have already {@link acquire acquired} sections and do not return them over the
* time expiration.
*
* Note that, if you succeeded to acquire a section from the semaphore (returns `true) but do
* not call the {@link release} function after your business, the others who want to
* {@link acquire} a section from the semaphore would be fall into the forever sleep.
* Therefore, never forget to calling the {@link release} function or utilize the
* {@link UniqueLock.try_acquire_until} function instead with {@link Semaphore.get_lockable}
* to ensure the safety.
*
* @param at The maximum time point to wait.
* @return Whether succeded to acquire or not.
*/
try_acquire_until(at: Date): Promise<boolean>;
/**
* Release sections.
*
* When you call this {@link release} method and there're someone who are currently blocked
* by attemping to {@link acquire} a section from this semaphore, *n* of them
* (FIFO; first-in-first-out) would {@link acquire} those {@link release released} sections
* and continue their executions.
*
* Otherwise, there's not anyone who is {@link acquire acquiring} the section or number of
* the blocked are less than *n*, the {@link OutOfRange} error would be thrown.
*
* > As you know, when you succeeded to {@link acquire} a section, you don't have to forget
* > to calling this {@link release} method after your business. If you forget it, it would
* > be a terrible situation for the others who're attempting to {@link acquire} a section
* > from this semaphore.
* >
* > However, if you utilize the {@link UniqueLock} with {@link Semaphore.get_lockable}, you
* > don't need to consider about this {@link release} method. Just define your business into
* > a callback function as a parameter of methods of the {@link UniqueLock}, then this
* > {@link release} method would be automatically called by the {@link UniqueLock} after the
* > business.
*
* @param n Number of sections to be released. Default is 1.
* @throw {@link OutOfRange} when *n* is greater than currently {@link acquire acquired} sections.
*/
release(n?: number): Promise<void>;
private _Cancel;
}
/**
*
*/
export declare namespace Semaphore {
/**
* Capsules a {@link Semaphore} to be suitable for the {@link UniqueLock}.
*
* @param semaphore Target semaphore to capsule.
* @return Lockable instance suitable for the {@link UniqueLock}
*/
function get_lockable<SemaphoreT extends Pick<Semaphore, "acquire" | "try_acquire" | "try_acquire_for" | "try_acquire_until" | "release">>(semaphore: SemaphoreT): ITimedLockable;
}
-363
View File
@@ -1,363 +0,0 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Semaphore = void 0;
//================================================================
/**
* @packageDocumentation
* @module std
*/
//================================================================
var List_1 = require("../container/List");
var InvalidArgument_1 = require("../exception/InvalidArgument");
var OutOfRange_1 = require("../exception/OutOfRange");
var global_1 = require("./global");
/**
* Counting semaphore.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var Semaphore = /** @class */ (function () {
/* ---------------------------------------------------------
CONSTRUCTORS
--------------------------------------------------------- */
/**
* Initializer Constructor.
*
* @param max Number of maximum sections acquirable.
*/
function Semaphore(max) {
this.queue_ = new List_1.List();
this.acquiring_ = 0;
this.max_ = max;
}
/**
* Get number of maximum sections lockable.
*
* @return Number of maximum sections lockable.
*/
Semaphore.prototype.max = function () {
return this.max_;
};
/* ---------------------------------------------------------
ACQUIRANCES
--------------------------------------------------------- */
/**
* Acquires a section.
*
* Acquires a section until be {@link release released}. If all of the sections in the
* semaphore already have been acquired by others, the function call would be blocked until
* one of them returns its acquisition by calling the {@link release} method.
*
* In same reason, if you don't call the {@link release} function after you business, the
* others who want to {@link acquire} a section from the semaphore would be fall into the
* forever sleep. Therefore, never forget to calling the {@link release} function or utilize
* the {@link UniqueLock.lock} function instead with {@link Semaphore.get_lockable} to ensure
* the safety.
*/
Semaphore.prototype.acquire = function () {
var _this = this;
return new Promise(function (resolve) {
if (_this.acquiring_ < _this.max_) {
++_this.acquiring_;
resolve();
}
else {
_this.queue_.push_back({
handler: resolve,
lockType: 0 /* LockType.HOLD */,
});
}
});
};
/**
* Tries to acquire a section.
*
* Attempts to acquire a section without blocking. If succeeded to acquire a section from the
* semaphore immediately, it returns `true` directly. Otherwise all of the sections in the
* semaphore are full, the function gives up the trial immediately and returns `false`
* directly.
*
* Note that, if you succeeded to acquire a section from the semaphore (returns `true) but do
* not call the {@link release} function after your business, the others who want to
* {@link acquire} a section from the semaphore would be fall into the forever sleep.
* Therefore, never forget to calling the {@link release} function or utilize the
* {@link UniqueLock.try_lock} function instead with {@link Semaphore.get_lockable} to ensure
* the safety.
*
* @return Whether succeeded to acquire or not.
*/
Semaphore.prototype.try_acquire = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
// ALL OR NOTHING
if (this.acquiring_ < this.max_) {
++this.acquiring_;
return [2 /*return*/, true];
}
else
return [2 /*return*/, false];
return [2 /*return*/];
});
});
};
/**
* Tries to acquire a section until timeout.
*
* Attempts to acquire a section from the semaphore until timeout. If succeeded to acquire a
* section until the timeout, it returns `true`. Otherwise failed to acquiring a section in
* given the time, the function gives up the trial and returns `false`.
*
* Failed to acquiring a section in the given time (returns `false`), it means that there're
* someone who have already {@link acquire acquired} sections and do not return them over the
* time expiration.
*
* Note that, if you succeeded to acquire a section from the semaphore (returns `true) but do
* not call the {@link release} function after your business, the others who want to
* {@link acquire} a section from the semaphore would be fall into the forever sleep.
* Therefore, never forget to calling the {@link release} function or utilize the
* {@link UniqueLock.try_acquire_for} function instead with {@link Semaphore.get_lockable} to
* ensure the safety.
*
* @param ms The maximum miliseconds for waiting.
* @return Whether succeded to acquire or not.
*/
Semaphore.prototype.try_acquire_for = function (ms) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2 /*return*/, new Promise(function (resolve) {
if (_this.acquiring_ < _this.max_) {
++_this.acquiring_;
resolve(true);
}
else {
// RESERVE ACQUIRE
var it_1 = _this.queue_.insert(_this.queue_.end(), {
handler: resolve,
lockType: 1 /* LockType.KNOCK */,
});
// AUTOMATIC RELEASE AFTER TIMEOUT
(0, global_1.sleep_for)(ms).then(function () {
// NOT YET, THEN DO RELEASE
if (it_1.value.handler !== null)
_this._Cancel(it_1);
});
}
})];
});
});
};
/**
* Tries to acquire a section until timeout.
*
* Attempts to acquire a section from the semaphore until time expiration. If succeeded to
* acquire a section until the time expiration, it returns `true`. Otherwise failed to
* acquiring a section in the given time, the function gives up the trial and returns `false`.
*
* Failed to acquiring a section in the given time (returns `false`), it means that there're
* someone who have already {@link acquire acquired} sections and do not return them over the
* time expiration.
*
* Note that, if you succeeded to acquire a section from the semaphore (returns `true) but do
* not call the {@link release} function after your business, the others who want to
* {@link acquire} a section from the semaphore would be fall into the forever sleep.
* Therefore, never forget to calling the {@link release} function or utilize the
* {@link UniqueLock.try_acquire_until} function instead with {@link Semaphore.get_lockable}
* to ensure the safety.
*
* @param at The maximum time point to wait.
* @return Whether succeded to acquire or not.
*/
Semaphore.prototype.try_acquire_until = function (at) {
// COMPUTE MILLISECONDS TO WAIT
var now = new Date();
var ms = at.getTime() - now.getTime();
return this.try_acquire_for(ms);
};
/* ---------------------------------------------------------
RELEASES
--------------------------------------------------------- */
/**
* Release sections.
*
* When you call this {@link release} method and there're someone who are currently blocked
* by attemping to {@link acquire} a section from this semaphore, *n* of them
* (FIFO; first-in-first-out) would {@link acquire} those {@link release released} sections
* and continue their executions.
*
* Otherwise, there's not anyone who is {@link acquire acquiring} the section or number of
* the blocked are less than *n*, the {@link OutOfRange} error would be thrown.
*
* > As you know, when you succeeded to {@link acquire} a section, you don't have to forget
* > to calling this {@link release} method after your business. If you forget it, it would
* > be a terrible situation for the others who're attempting to {@link acquire} a section
* > from this semaphore.
* >
* > However, if you utilize the {@link UniqueLock} with {@link Semaphore.get_lockable}, you
* > don't need to consider about this {@link release} method. Just define your business into
* > a callback function as a parameter of methods of the {@link UniqueLock}, then this
* > {@link release} method would be automatically called by the {@link UniqueLock} after the
* > business.
*
* @param n Number of sections to be released. Default is 1.
* @throw {@link OutOfRange} when *n* is greater than currently {@link acquire acquired} sections.
*/
Semaphore.prototype.release = function (n) {
if (n === void 0) { n = 1; }
return __awaiter(this, void 0, void 0, function () {
var resolverList, resolver, resolverList_1, resolverList_1_1, resolver;
var e_1, _a;
return __generator(this, function (_b) {
//----
// VALIDATION
//----
if (n < 1)
throw new InvalidArgument_1.InvalidArgument("Error on std.Semaphore.release(): parametric n is less than 1 -> (n = ".concat(n, ")."));
else if (n > this.max_)
throw new OutOfRange_1.OutOfRange("Error on std.Semaphore.release(): parametric n is greater than max -> (n = ".concat(n, ", max = ").concat(this.max_, ")."));
else if (n > this.acquiring_)
throw new OutOfRange_1.OutOfRange("Error on std.Semaphore.release(): parametric n is greater than acquiring -> (n = ".concat(n, ", acquiring = ").concat(this.acquiring_, ")."));
resolverList = [];
while (this.queue_.empty() === false && resolverList.length < n) {
resolver = this.queue_.front();
if (resolver.handler !== null)
resolverList.push(__assign({}, resolver));
// DESTRUCT
this.queue_.pop_front();
resolver.handler = null;
}
// COMPUTE REMAINED ACQUIRANCES
this.acquiring_ -= n - resolverList.length;
try {
// CALL HANDLERS
for (resolverList_1 = __values(resolverList), resolverList_1_1 = resolverList_1.next(); !resolverList_1_1.done; resolverList_1_1 = resolverList_1.next()) {
resolver = resolverList_1_1.value;
if (resolver.lockType === 0 /* LockType.HOLD */)
resolver.handler();
else
resolver.handler(true);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (resolverList_1_1 && !resolverList_1_1.done && (_a = resolverList_1.return)) _a.call(resolverList_1);
}
finally { if (e_1) throw e_1.error; }
}
return [2 /*return*/];
});
});
};
Semaphore.prototype._Cancel = function (it) {
// POP THE LISTENER
var handler = it.value.handler;
// DESTRUCTION
it.value.handler = null;
this.queue_.erase(it);
// RETURNS FAILURE
handler(false);
};
return Semaphore;
}());
exports.Semaphore = Semaphore;
/**
*
*/
(function (Semaphore) {
/**
* Capsules a {@link Semaphore} to be suitable for the {@link UniqueLock}.
*
* @param semaphore Target semaphore to capsule.
* @return Lockable instance suitable for the {@link UniqueLock}
*/
function get_lockable(semaphore) {
return new Lockable(semaphore);
}
Semaphore.get_lockable = get_lockable;
/**
* @internal
*/
var Lockable = /** @class */ (function () {
function Lockable(semaphore) {
this.semahpore_ = semaphore;
}
Lockable.prototype.lock = function () {
return this.semahpore_.acquire();
};
Lockable.prototype.unlock = function () {
return this.semahpore_.release();
};
Lockable.prototype.try_lock = function () {
return this.semahpore_.try_acquire();
};
Lockable.prototype.try_lock_for = function (ms) {
return this.semahpore_.try_acquire_for(ms);
};
Lockable.prototype.try_lock_until = function (at) {
return this.semahpore_.try_acquire_until(at);
};
return Lockable;
}());
Semaphore.Lockable = Lockable;
})(Semaphore = exports.Semaphore || (exports.Semaphore = {}));
exports.Semaphore = Semaphore;
//# sourceMappingURL=Semaphore.js.map
-136
View File
@@ -1,136 +0,0 @@
/**
* @packageDocumentation
* @module std
*/
import { ISharedLockable } from "../base/thread/ISharedLockable";
import { ISharedTimedLockable } from "../base/thread/ISharedTimedLockable";
/**
*
*/
export declare class SharedLock {
}
/**
* Shared mutex wrapper for the safe read lock.
*
* The module {@link SharedLock} is a collection of general purpose functions wrapping shared
* mutex for ensuring the safe lock. If you *lock* a mutex (with your business logic code) through
* any function of the {@link SharedLock} module, the shared mutex would be automatically
* *unlocked* after your business, even if an error has been occured in your business.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare namespace SharedLock {
/**
* Read locks a shared mutex with your business.
*
* Shares a mutex until be the *closure* has been completed. If there're someone who have
* already {@link ILockable.lock monopolied} the mutex, the function call would be blocked
* until all of them to {@link unlock return} their acquisitions.
*
* When succeeded to {@link ISharedLockable.lock_shared share} the mutex, the {@link lock}
* function will call the *closure*, a custom function defning your business. After the
* *closure* function be returned, the {@link lock} function automatically
* {@link ISharedLockable.unlock_shared unlocks} the mutex, even if the *closure* function
* throws any error.
*
* Therefore, when using this {@link lock} function, you don't need to consider about
* {@link ISharedLockable.unlock_shared returning} the lock acquistion after your business.
* It would just be done automatically.
*
* @param mutex Target shared mutex to read lock.
* @param closure A function defining your business.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
export function lock<Mutex extends Pick<ISharedLockable, "lock_shared" | "unlock_shared">>(mutex: Mutex, closure: Closure): Promise<void>;
/**
* Tries to read lock a shared mutex with your business.
*
* Attemps to share a mutex without blocking. If succeeded to share the mutex immediately, it
* returns `true` directly. Otherwise there's someone who has already
* {@link ILockable.lock monopolied} the mutex, the function gives up the trial immediately
* and returns `false` directly without calling the *closure*.
*
* When succeeded to {@link ISharedLockable.lock_shared share} the mutex, the {@link try_lock}
* function will call the *closure*, a custom function defning your business. After the
* *closure* function be returned, the {@link try_lock} function automatically
* {@link ISharedLockable.unlock_shared unlocks} the mutex, even if the *closure* function
* throws any error.
*
* Therefore, when using this {@link try_lock} function, you don't need to consider about
* {@link ISharedLockable.unlock_shared returning} the lock acquistion after your business.
* It would just be done automatically.
*
* @param mutex Target shared mutex to try read lock.
* @param closure A function defining your business.
* @return Whether succeeded to share the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
export function try_lock<Mutex extends Pick<ISharedLockable, "try_lock_shared" | "unlock_shared">>(mutex: Mutex, closure: Closure): Promise<boolean>;
/**
* Tries to read lock a shared mutex with your business until timeout.
*
* Attemps to share a mutex until timeout. If succeeded to share the mutex until timeout, it
* returns `true` after calling the *closure*. Otherwise failed to acquiring the shared lock
* in the given time, the function gives up the trial and returns `false` without calling the
* *closure*.
*
* Failed to acquring the shared lock in the given time (returns `false`), it means that
* there's someone who has already {@link ILockable.lock monopolied} the mutex and does not
* return it over the timeout.
*
* When succeeded to {@link ISharedLockable.lock_shared share} the mutex, the
* {@link try_lock_for} function will call the *closure*, a custom function defning your
* business. After the *closure* function be returned, the {@link try_lock} function
* automatically {@link ISharedLockable.unlock_shared unlocks} the mutex, even if the
* *closure* function throws any error.
*
* Therefore, when using this {@link try_lock_for} function, you don't need to consider about
* {@link ISharedLockable.unlock_shared returning} the lock acquistion after your business.
* It would just be done automatically.
*
* @param mutex Target mutex to try lock until timeout.
* @param ms The maximum miliseconds for waiting.
* @param closure A function defining your business.
* @return Whether succeeded to share the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
export function try_lock_for<Mutex extends Pick<ISharedTimedLockable, "try_lock_shared_for" | "unlock_shared">>(mutex: Mutex, ms: number, closure: Closure): Promise<boolean>;
/**
* Tries to read lock a shared mutex with your business until time expiration.
*
* Attemps to share a mutex until time expiration. If succeeded to share the mutex until the
* time expiration, it returns `true` after calling the *closure*. Otherwise failed to
* acquiring the shared lock in the given time, the function gives up the trial and returns
* `false` without calling the *closure*.
*
* Failed to acquring the shared lock in the given time (returns `false`), it means that
* there's someone who has already {@link ILockable.lock monopolied} the mutex and does not
* return it over the time expiration.
*
* When succeeded to {@link ISharedLockable.lock_shared share} the mutex, the
* {@link try_lock_until} function will call the *closure*, a custom function defning your
* business. After the *closure* function be returned, the {@link try_lock} function
* automatically {@link ISharedLockable.unlock_shared unlocks} the mutex, even if the
* *closure* function throws any error.
*
* Therefore, when using this {@link try_lock_until} function, you don't need to consider
* about {@link ISharedLockable.unlock_shared returning} the lock acquistion after your
* business. It would just be done automatically.
*
* @param mutex Target mutex to try lock until time expiration.
* @param at The maximum time point to wait.
* @param closure A function defining your business.
* @return Whether succeeded to share the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
export function try_lock_until<Mutex extends Pick<ISharedTimedLockable, "try_lock_shared_until" | "unlock_shared">>(mutex: Mutex, at: Date, closure: Closure): Promise<boolean>;
/**
* Type of closure function defining your business logic.
*/
type Closure = () => void | Promise<void>;
export {};
}
-147
View File
@@ -1,147 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SharedLock = void 0;
var SafeLock_1 = require("../internal/thread/SafeLock");
/**
*
*/
var SharedLock = /** @class */ (function () {
function SharedLock() {
}
return SharedLock;
}());
exports.SharedLock = SharedLock;
/**
* Shared mutex wrapper for the safe read lock.
*
* The module {@link SharedLock} is a collection of general purpose functions wrapping shared
* mutex for ensuring the safe lock. If you *lock* a mutex (with your business logic code) through
* any function of the {@link SharedLock} module, the shared mutex would be automatically
* *unlocked* after your business, even if an error has been occured in your business.
*
* @author Jeongho Nam - https://github.com/samchon
*/
(function (SharedLock) {
/**
* Read locks a shared mutex with your business.
*
* Shares a mutex until be the *closure* has been completed. If there're someone who have
* already {@link ILockable.lock monopolied} the mutex, the function call would be blocked
* until all of them to {@link unlock return} their acquisitions.
*
* When succeeded to {@link ISharedLockable.lock_shared share} the mutex, the {@link lock}
* function will call the *closure*, a custom function defning your business. After the
* *closure* function be returned, the {@link lock} function automatically
* {@link ISharedLockable.unlock_shared unlocks} the mutex, even if the *closure* function
* throws any error.
*
* Therefore, when using this {@link lock} function, you don't need to consider about
* {@link ISharedLockable.unlock_shared returning} the lock acquistion after your business.
* It would just be done automatically.
*
* @param mutex Target shared mutex to read lock.
* @param closure A function defining your business.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
function lock(mutex, closure) {
return SafeLock_1.SafeLock.lock(function () { return mutex.lock_shared(); }, function () { return mutex.unlock_shared(); }, closure);
}
SharedLock.lock = lock;
/**
* Tries to read lock a shared mutex with your business.
*
* Attemps to share a mutex without blocking. If succeeded to share the mutex immediately, it
* returns `true` directly. Otherwise there's someone who has already
* {@link ILockable.lock monopolied} the mutex, the function gives up the trial immediately
* and returns `false` directly without calling the *closure*.
*
* When succeeded to {@link ISharedLockable.lock_shared share} the mutex, the {@link try_lock}
* function will call the *closure*, a custom function defning your business. After the
* *closure* function be returned, the {@link try_lock} function automatically
* {@link ISharedLockable.unlock_shared unlocks} the mutex, even if the *closure* function
* throws any error.
*
* Therefore, when using this {@link try_lock} function, you don't need to consider about
* {@link ISharedLockable.unlock_shared returning} the lock acquistion after your business.
* It would just be done automatically.
*
* @param mutex Target shared mutex to try read lock.
* @param closure A function defining your business.
* @return Whether succeeded to share the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
function try_lock(mutex, closure) {
return SafeLock_1.SafeLock.try_lock(function () { return mutex.try_lock_shared(); }, function () { return mutex.unlock_shared(); }, closure);
}
SharedLock.try_lock = try_lock;
/**
* Tries to read lock a shared mutex with your business until timeout.
*
* Attemps to share a mutex until timeout. If succeeded to share the mutex until timeout, it
* returns `true` after calling the *closure*. Otherwise failed to acquiring the shared lock
* in the given time, the function gives up the trial and returns `false` without calling the
* *closure*.
*
* Failed to acquring the shared lock in the given time (returns `false`), it means that
* there's someone who has already {@link ILockable.lock monopolied} the mutex and does not
* return it over the timeout.
*
* When succeeded to {@link ISharedLockable.lock_shared share} the mutex, the
* {@link try_lock_for} function will call the *closure*, a custom function defning your
* business. After the *closure* function be returned, the {@link try_lock} function
* automatically {@link ISharedLockable.unlock_shared unlocks} the mutex, even if the
* *closure* function throws any error.
*
* Therefore, when using this {@link try_lock_for} function, you don't need to consider about
* {@link ISharedLockable.unlock_shared returning} the lock acquistion after your business.
* It would just be done automatically.
*
* @param mutex Target mutex to try lock until timeout.
* @param ms The maximum miliseconds for waiting.
* @param closure A function defining your business.
* @return Whether succeeded to share the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
function try_lock_for(mutex, ms, closure) {
return SafeLock_1.SafeLock.try_lock(function () { return mutex.try_lock_shared_for(ms); }, function () { return mutex.unlock_shared(); }, closure);
}
SharedLock.try_lock_for = try_lock_for;
/**
* Tries to read lock a shared mutex with your business until time expiration.
*
* Attemps to share a mutex until time expiration. If succeeded to share the mutex until the
* time expiration, it returns `true` after calling the *closure*. Otherwise failed to
* acquiring the shared lock in the given time, the function gives up the trial and returns
* `false` without calling the *closure*.
*
* Failed to acquring the shared lock in the given time (returns `false`), it means that
* there's someone who has already {@link ILockable.lock monopolied} the mutex and does not
* return it over the time expiration.
*
* When succeeded to {@link ISharedLockable.lock_shared share} the mutex, the
* {@link try_lock_until} function will call the *closure*, a custom function defning your
* business. After the *closure* function be returned, the {@link try_lock} function
* automatically {@link ISharedLockable.unlock_shared unlocks} the mutex, even if the
* *closure* function throws any error.
*
* Therefore, when using this {@link try_lock_until} function, you don't need to consider
* about {@link ISharedLockable.unlock_shared returning} the lock acquistion after your
* business. It would just be done automatically.
*
* @param mutex Target mutex to try lock until time expiration.
* @param at The maximum time point to wait.
* @param closure A function defining your business.
* @return Whether succeeded to share the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
function try_lock_until(mutex, at, closure) {
return SafeLock_1.SafeLock.try_lock(function () { return mutex.try_lock_shared_until(at); }, function () { return mutex.unlock_shared(); }, closure);
}
SharedLock.try_lock_until = try_lock_until;
})(SharedLock = exports.SharedLock || (exports.SharedLock = {}));
exports.SharedLock = SharedLock;
//# sourceMappingURL=SharedLock.js.map
-41
View File
@@ -1,41 +0,0 @@
/**
* @packageDocumentation
* @module std
*/
import { ISharedLockable } from "../base/thread/ISharedLockable";
/**
* Shared mutex.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class SharedMutex implements ISharedLockable {
private mutex_;
/**
* Default Constructor.
*/
constructor();
/**
* @inheritDoc
*/
lock(): Promise<void>;
/**
* @inheritDoc
*/
try_lock(): Promise<boolean>;
/**
* @inheritDoc
*/
unlock(): Promise<void>;
/**
* @inheritDoc
*/
lock_shared(): Promise<void>;
/**
* @inheritDoc
*/
try_lock_shared(): Promise<boolean>;
/**
* @inheritDoc
*/
unlock_shared(): Promise<void>;
}
-65
View File
@@ -1,65 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SharedMutex = void 0;
var SharedTimedMutex_1 = require("./SharedTimedMutex");
/**
* Shared mutex.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var SharedMutex = /** @class */ (function () {
/* ---------------------------------------------------------
CONSTRUCTOR
--------------------------------------------------------- */
/**
* Default Constructor.
*/
function SharedMutex() {
this.mutex_ = new SharedTimedMutex_1.SharedTimedMutex(this);
}
/* ---------------------------------------------------------
WRITE LOCK
--------------------------------------------------------- */
/**
* @inheritDoc
*/
SharedMutex.prototype.lock = function () {
return this.mutex_.lock();
};
/**
* @inheritDoc
*/
SharedMutex.prototype.try_lock = function () {
return this.mutex_.try_lock();
};
/**
* @inheritDoc
*/
SharedMutex.prototype.unlock = function () {
return this.mutex_.unlock();
};
/* ---------------------------------------------------------
READ LOCK
--------------------------------------------------------- */
/**
* @inheritDoc
*/
SharedMutex.prototype.lock_shared = function () {
return this.mutex_.lock_shared();
};
/**
* @inheritDoc
*/
SharedMutex.prototype.try_lock_shared = function () {
return this.mutex_.try_lock_shared();
};
/**
* @inheritDoc
*/
SharedMutex.prototype.unlock_shared = function () {
return this.mutex_.unlock_shared();
};
return SharedMutex;
}());
exports.SharedMutex = SharedMutex;
//# sourceMappingURL=SharedMutex.js.map
-59
View File
@@ -1,59 +0,0 @@
import { ISharedTimedLockable } from "../base/thread/ISharedTimedLockable";
/**
* Shared timed mutex.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class SharedTimedMutex implements ISharedTimedLockable {
private source_;
private queue_;
private writing_;
private reading_;
/**
* Default Constructor.
*/
constructor();
private _Current_access_type;
/**
* @inheritDoc
*/
lock(): Promise<void>;
/**
* @inheritDoc
*/
try_lock(): Promise<boolean>;
/**
* @inheritDoc
*/
try_lock_for(ms: number): Promise<boolean>;
/**
* @inheritDoc
*/
try_lock_until(at: Date): Promise<boolean>;
/**
* @inheritDoc
*/
unlock(): Promise<void>;
/**
* @inheritDoc
*/
lock_shared(): Promise<void>;
/**
* @inheritDoc
*/
try_lock_shared(): Promise<boolean>;
/**
* @inheritDoc
*/
try_lock_shared_for(ms: number): Promise<boolean>;
/**
* @inheritDoc
*/
try_lock_shared_until(at: Date): Promise<boolean>;
/**
* @inheritDoc
*/
unlock_shared(): Promise<void>;
private _Release;
private _Cancel;
}
-355
View File
@@ -1,355 +0,0 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SharedTimedMutex = void 0;
var List_1 = require("../container/List");
var InvalidArgument_1 = require("../exception/InvalidArgument");
var global_1 = require("./global");
/**
* Shared timed mutex.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var SharedTimedMutex = /** @class */ (function () {
function SharedTimedMutex(source) {
if (source === void 0) { source = null; }
this.source_ = source !== null ? source : this;
this.queue_ = new List_1.List();
this.writing_ = 0;
this.reading_ = 0;
}
SharedTimedMutex.prototype._Current_access_type = function () {
return this.queue_.empty() ? null : this.queue_.front().accessType;
};
/* ---------------------------------------------------------
WRITE LOCK
--------------------------------------------------------- */
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.lock = function () {
var _this = this;
return new Promise(function (resolve) {
// CONSTRUCT RESOLVER
var resolver = {
handler: _this.writing_++ === 0 && _this.reading_ === 0
? null
: resolve,
accessType: 0 /* AccessType.WRITE */,
lockType: 0 /* LockType.HOLD */,
};
_this.queue_.push_back(resolver);
// LOCK OR WAIT
if (resolver.handler === null)
resolve();
});
};
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.try_lock = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
// LOCKABLE ?
if (this.writing_ !== 0 || this.reading_ !== 0)
return [2 /*return*/, false];
// CONSTRUCT RESOLVER
this.queue_.push_back({
handler: null,
accessType: 0 /* AccessType.WRITE */,
lockType: 1 /* LockType.KNOCK */,
});
// RETURNS
++this.writing_;
return [2 /*return*/, true];
});
});
};
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.try_lock_for = function (ms) {
var _this = this;
return new Promise(function (resolve) {
// CONSTRUCT RESOLVER
var it = _this.queue_.insert(_this.queue_.end(), {
handler: _this.writing_++ === 0 && _this.reading_ === 0
? null
: resolve,
accessType: 0 /* AccessType.WRITE */,
lockType: 1 /* LockType.KNOCK */,
});
if (it.value.handler === null)
resolve(true); // SUCCESS
else {
// AUTOMATIC UNLOCK AFTER TIMEOUT
(0, global_1.sleep_for)(ms).then(function () {
// NOT YET, THEN DO UNLOCK
if (it.value.handler !== null) {
--_this.writing_;
_this._Cancel(it);
}
});
}
});
};
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.try_lock_until = function (at) {
return __awaiter(this, void 0, void 0, function () {
var now, ms;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
now = new Date();
ms = at.getTime() - now.getTime();
return [4 /*yield*/, this.try_lock_for(ms)];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.unlock = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
if (this._Current_access_type() !== 0 /* AccessType.WRITE */)
throw new InvalidArgument_1.InvalidArgument("Error on std.".concat(this.source_.constructor.name, ".unlock(): this mutex is free on the unique lock."));
--this.writing_;
this.queue_.pop_front();
this._Release();
return [2 /*return*/];
});
});
};
/* ---------------------------------------------------------
READ LOCK
--------------------------------------------------------- */
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.lock_shared = function () {
var _this = this;
return new Promise(function (resolve) {
var resolver = {
handler: _this.writing_ === 0 ? null : resolve,
accessType: 1 /* AccessType.READ */,
lockType: 0 /* LockType.HOLD */,
};
_this.queue_.push_back(resolver);
++_this.reading_;
if (resolver.handler === null)
resolve();
});
};
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.try_lock_shared = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
if (this.writing_ !== 0)
return [2 /*return*/, false];
++this.reading_;
this.queue_.push_back({
handler: null,
accessType: 1 /* AccessType.READ */,
lockType: 1 /* LockType.KNOCK */,
});
return [2 /*return*/, true];
});
});
};
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.try_lock_shared_for = function (ms) {
var _this = this;
return new Promise(function (resolve) {
// CONSTRUCT RESOLVER
var it = _this.queue_.insert(_this.queue_.end(), {
handler: _this.writing_ === 0 ? null : resolve,
accessType: 1 /* AccessType.READ */,
lockType: 1 /* LockType.KNOCK */,
});
++_this.reading_;
if (it.value.handler === null)
resolve(true);
else {
// AUTOMATIC UNLOCK AFTER TIMEOUT
(0, global_1.sleep_for)(ms).then(function () {
// NOT YET, THEN DO UNLOCK
if (it.value.handler !== null) {
--_this.reading_;
_this._Cancel(it);
}
});
}
});
};
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.try_lock_shared_until = function (at) {
return __awaiter(this, void 0, void 0, function () {
var now, ms;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
now = new Date();
ms = at.getTime() - now.getTime();
return [4 /*yield*/, this.try_lock_shared_for(ms)];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
/**
* @inheritDoc
*/
SharedTimedMutex.prototype.unlock_shared = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
if (this._Current_access_type() !== 1 /* AccessType.READ */)
throw new InvalidArgument_1.InvalidArgument("Error on std.".concat(this.source_.constructor.name, ".unlock_shared(): this mutex is free on the shared lock."));
--this.reading_;
this.queue_.pop_front();
this._Release();
return [2 /*return*/];
});
});
};
/* ---------------------------------------------------------
RELEASE
--------------------------------------------------------- */
SharedTimedMutex.prototype._Release = function () {
var e_1, _a, e_2, _b;
// STEP TO THE NEXT LOCKS
var current = this._Current_access_type();
var resolverList = [];
try {
for (var _c = __values(this.queue_), _d = _c.next(); !_d.done; _d = _c.next()) {
var resolver = _d.value;
// DIFFERENT ACCESS TYPE COMES?
if (resolver.accessType !== current)
break;
// COPY AND CLEAR
else if (resolver.handler !== null) {
resolverList.push(__assign({}, resolver));
resolver.handler = null;
}
// STOP AFTER WRITE LOCK
if (resolver.accessType === 0 /* AccessType.WRITE */)
break;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
try {
// CALL THE HANDLERS
for (var resolverList_1 = __values(resolverList), resolverList_1_1 = resolverList_1.next(); !resolverList_1_1.done; resolverList_1_1 = resolverList_1.next()) {
var resolver = resolverList_1_1.value;
if (resolver.lockType === 0 /* LockType.HOLD */)
resolver.handler();
else
resolver.handler(true);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (resolverList_1_1 && !resolverList_1_1.done && (_b = resolverList_1.return)) _b.call(resolverList_1);
}
finally { if (e_2) throw e_2.error; }
}
};
SharedTimedMutex.prototype._Cancel = function (it) {
//----
// POP THE RELEASE
//----
// DO RASE
this.queue_.erase(it);
// EXTRACT HANDLER TO AVOID THE `this._Release()`
var handler = it.value.handler;
it.value.handler = null;
//----
// POST-PROCESS
//----
// CHECK THE PREVIOUS RESOLVER
var prev = it.prev();
// RELEASE IF IT IS THE LASTEST RESOLVER
if (prev.equals(this.queue_.end()) === false &&
prev.value.handler === null)
this._Release();
// (LAZY) RETURNS FAILURE
handler(false);
};
return SharedTimedMutex;
}());
exports.SharedTimedMutex = SharedTimedMutex;
//# sourceMappingURL=SharedTimedMutex.js.map
-11
View File
@@ -1,11 +0,0 @@
/**
* Singleton generator.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class Singleton<T, Args extends any[] = []> {
private readonly closure_;
private value_;
constructor(closure: (...args: Args) => T);
get(...args: Args): T;
}
-52
View File
@@ -1,52 +0,0 @@
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Singleton = void 0;
/**
* Singleton generator.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var Singleton = /** @class */ (function () {
function Singleton(closure) {
this.closure_ = closure;
this.value_ = NOT_MOUNTED_YET;
}
Singleton.prototype.get = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (this.value_ === NOT_MOUNTED_YET)
this.value_ = this.closure_.apply(this, __spreadArray([], __read(args), false));
return this.value_;
};
return Singleton;
}());
exports.Singleton = Singleton;
var NOT_MOUNTED_YET = {};
//# sourceMappingURL=Singleton.js.map
-37
View File
@@ -1,37 +0,0 @@
/**
* @packageDocumentation
* @module std
*/
import { ITimedLockable } from "../base/thread/ITimedLockable";
/**
* Timed mutex.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class TimedMutex implements ITimedLockable {
private mutex_;
/**
* Default Constructor.
*/
constructor();
/**
* @inheritDoc
*/
lock(): Promise<void>;
/**
* @inheritDoc
*/
try_lock(): Promise<boolean>;
/**
* @inheritDoc
*/
unlock(): Promise<void>;
/**
* @inheritDoc
*/
try_lock_for(ms: number): Promise<boolean>;
/**
* @inheritDoc
*/
try_lock_until(at: Date): Promise<boolean>;
}
-59
View File
@@ -1,59 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimedMutex = void 0;
var SharedTimedMutex_1 = require("./SharedTimedMutex");
/**
* Timed mutex.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var TimedMutex = /** @class */ (function () {
/* ---------------------------------------------------------
CONSTRUCTOR
--------------------------------------------------------- */
/**
* Default Constructor.
*/
function TimedMutex() {
this.mutex_ = new SharedTimedMutex_1.SharedTimedMutex(this);
}
/* ---------------------------------------------------------
LOCK & UNLOCK
--------------------------------------------------------- */
/**
* @inheritDoc
*/
TimedMutex.prototype.lock = function () {
return this.mutex_.lock();
};
/**
* @inheritDoc
*/
TimedMutex.prototype.try_lock = function () {
return this.mutex_.try_lock();
};
/**
* @inheritDoc
*/
TimedMutex.prototype.unlock = function () {
return this.mutex_.unlock();
};
/* ---------------------------------------------------------
TIMED LOCK
--------------------------------------------------------- */
/**
* @inheritDoc
*/
TimedMutex.prototype.try_lock_for = function (ms) {
return this.mutex_.try_lock_for(ms);
};
/**
* @inheritDoc
*/
TimedMutex.prototype.try_lock_until = function (at) {
return this.mutex_.try_lock_until(at);
};
return TimedMutex;
}());
exports.TimedMutex = TimedMutex;
//# sourceMappingURL=TimedMutex.js.map
-28
View File
@@ -1,28 +0,0 @@
/**
* Timed singleton generator.
*
* The `TimedSingleton` is a type of {@link Singleton} class who re-constructs the singleton
* value repeatedly whenever specific time has been elapsed after the last lazy construction.
*
* @template T Type of the value to be lazy-constructed
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class TimedSingleton<T, Args extends any[] = []> {
private readonly interval_;
private readonly closure_;
private expired_at_;
private value_;
/**
* Initializer Constructor.
*
* @param interval Specific interval time, to determine whether re-generation of the singleton value is required or not, as milliseconds
* @param closure Lazy constructor function returning the target value
*/
constructor(interval: number, closure: (...args: Args) => T);
/**
* Get value.
*
* @returns The lazy constructed value
*/
get(...args: Args): T;
}
-70
View File
@@ -1,70 +0,0 @@
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimedSingleton = void 0;
/**
* Timed singleton generator.
*
* The `TimedSingleton` is a type of {@link Singleton} class who re-constructs the singleton
* value repeatedly whenever specific time has been elapsed after the last lazy construction.
*
* @template T Type of the value to be lazy-constructed
* @author Jeongho Nam - https://github.com/samchon
*/
var TimedSingleton = /** @class */ (function () {
/**
* Initializer Constructor.
*
* @param interval Specific interval time, to determine whether re-generation of the singleton value is required or not, as milliseconds
* @param closure Lazy constructor function returning the target value
*/
function TimedSingleton(interval, closure) {
this.interval_ = interval;
this.closure_ = closure;
this.value_ = null;
this.expired_at_ = 0;
}
/**
* Get value.
*
* @returns The lazy constructed value
*/
TimedSingleton.prototype.get = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (Date.now() >= this.expired_at_) {
this.expired_at_ = Date.now() + this.interval_;
this.value_ = this.closure_.apply(this, __spreadArray([], __read(args), false));
}
return this.value_;
};
return TimedSingleton;
}());
exports.TimedSingleton = TimedSingleton;
//# sourceMappingURL=TimedSingleton.js.map
-137
View File
@@ -1,137 +0,0 @@
/**
* @packageDocumentation
* @module std
*/
import { ILockable } from "../base/thread/ILockable";
import { ITimedLockable } from "../base/thread/ITimedLockable";
/**
*
*/
export declare class UniqueLock {
}
/**
* Mutex wrapper for the safe write lock.
*
* The module {@link UniqueLock} is a collection of general purpose functions wrapping mutex for
* ensuring the safe lock. If you *lock* a mutex (with your business logic code) through any
* function of the {@link UniqueLock} module, the mutex would be automatically *unlocked* after
* your business, even if an error has been occured in your business.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare namespace UniqueLock {
/**
* Write locks a mutex with your business logic code.
*
* Monopolies a mutex until be the *closure* has been completed. If there're someone who have
* already {@link ILockable.lock monopolied} or {@link ISharedLockable.lock shared} the mutex,
* the function call would be blocked until all of them return their acquisitions by calling
* {@link ILockable.unlock} or {@link ISharedLockable.unlock_shared} methods.
*
* When succeeded to {@link ILockable.lock monopoly} the mutex, the {@link lock} function will
* call the *closure*, a custom function definig your business. After the *closure* function
* be returned, the {@link lock} function automatically {@link ILockable.unlock unlocks} the
* mutex, even if the *closure* function throws any error.
*
* Therefore, when using this {@link lock} function, you don't need to consider about
* {@link ILockable.unlock returning} the lock acquistion after your business. It would just
* be done automatically.
*
* @param mutex Target mutex to write lock.
* @param closure A function defining your business.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
export function lock<Mutex extends Pick<ILockable, "lock" | "unlock">>(mutex: Mutex, closure: Closure): Promise<void>;
/**
* Tries to write lock a mutex with your business.
*
* Attempts to monopoly a mutex without blocking. If succeeded to monopoly the mutex
* immediately, it returns `true` after calling the *closure*. Otherwise there's someone who
* has already {@link ILockable.lock monopolied} or {@link ISharedLockable.lock shared} the
* mutex, the function gives up the trial immediately and returns `false` directly without
* calling the *closure*.
*
* When succeeded to {@link ILockable.lock monopoly} the mutex, the {@link try_lock} function
* will call the *closure*, a custom function definig your business. After the *closure*
* function be returned, the {@link try_lock} function automatically
* {@link ILockable.unlock unlocks} the mutex, even if the *closure* function throws any
* error.
*
* Therefore, when using this {@link try_lock} function, you don't need to consider about
* {@link ILockable.unlock returning} the lock acquistion after your business. It would just
* be done automatically.
*
* @param mutex Target mutex to try write lock.
* @param closure A function defining your business.
* @return Whether succeeded to monopoly the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
export function try_lock<Mutex extends Pick<ILockable, "try_lock" | "unlock">>(mutex: Mutex, closure: Closure): Promise<boolean>;
/**
* Tries to write lock a mutex with your business until timeout.
*
* Attempts to monopoly a mutex until timeout. If succeeded to monopoly the mutex until the
* timeout, it returns `true` after calling the *closure*. Otherwise failed to acquiring the
* lock in the given time, the function gives up the trial and returns `false` without calling
* the *closure*.
*
* Failed to acquiring the lock in the given time (returns `false`), it means that there's
* someone who has already {@link ILockable.lock monopolied} or {@link ISharedLockable.lock}
* the mutex and does not return it over the timeout.
*
* When succeeded to {@link ILockable.lock monopoly} the mutex, the {@link try_lock_for}
* function will call the *closure*, a custom function definig your business. After the
* *closure* function be returned, the {@link try_lock_for} function automatically
* {@link ILockable.unlock unlocks} the mutex and returns `true`, even if the *closure*
* function throws any error.
*
* Therefore, when using this {@link try_lock_for} function, you don't need to consider about
* {@link ILockable.unlock returning} the lock acquistion after your business. It would just
* be done automatically.
*
* @param mutex Target mutex to try write lock until timeout.
* @param ms The maximum miliseconds for waiting.
* @param closure A function defining your business.
* @return Whether succeeded to monopoly the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
export function try_lock_for<Mutex extends Pick<ITimedLockable, "try_lock_for" | "unlock">>(mutex: Mutex, ms: number, closure: Closure): Promise<boolean>;
/**
* Tries to write lock a mutex with your business until time expiration.
*
* Attempts to monopoly a mutex until time expiration. If succeeded to monopoly the mutex
* until the time expiration, it returns `true` after calling the *closure*. Otherwise failed
* to acquiring the lock in the given time, the function gives up the trial and returns
* `false` without calling the *closure*.
*
* Failed to acquiring the lock in the given time (returns `false`), it means that there's
* someone who has already {@link ILockable.lock monopolied} or {@link ISharedLockable.lock}
* the mutex and does not return it over the time expiration.
*
* When succeeded to {@link ILockable.lock monopoly} the mutex, the {@link try_lock_until}
* function will call the *closure*, a custom function definig your business. After the
* *closure* function be returned, the {@link try_lock_until} function automatically
* {@link ILockable.unlock unlocks} the mutex and returns `true`, even if the *closure*
* function throws any error.
*
* TTherefore, when using this {@link try_lock_until} function, you don't need to consider
* about {@link ILockable.unlock returning} the lock acquistion after your business. It would
* just be done automatically.
*
* @param mutex Target mutex to try write lock until time expiration.
* @param at The maximum time point to wait.
* @param closure A function defining your business.
* @return Whether succeeded to monopoly the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
export function try_lock_until<Mutex extends Pick<ITimedLockable, "try_lock_until" | "unlock">>(mutex: Mutex, at: Date, closure: Closure): Promise<boolean>;
/**
* Type of closure function defining your business logic.
*/
type Closure = () => void | Promise<void>;
export {};
}
-148
View File
@@ -1,148 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UniqueLock = void 0;
var SafeLock_1 = require("../internal/thread/SafeLock");
/**
*
*/
var UniqueLock = /** @class */ (function () {
function UniqueLock() {
}
return UniqueLock;
}());
exports.UniqueLock = UniqueLock;
/**
* Mutex wrapper for the safe write lock.
*
* The module {@link UniqueLock} is a collection of general purpose functions wrapping mutex for
* ensuring the safe lock. If you *lock* a mutex (with your business logic code) through any
* function of the {@link UniqueLock} module, the mutex would be automatically *unlocked* after
* your business, even if an error has been occured in your business.
*
* @author Jeongho Nam - https://github.com/samchon
*/
(function (UniqueLock) {
/**
* Write locks a mutex with your business logic code.
*
* Monopolies a mutex until be the *closure* has been completed. If there're someone who have
* already {@link ILockable.lock monopolied} or {@link ISharedLockable.lock shared} the mutex,
* the function call would be blocked until all of them return their acquisitions by calling
* {@link ILockable.unlock} or {@link ISharedLockable.unlock_shared} methods.
*
* When succeeded to {@link ILockable.lock monopoly} the mutex, the {@link lock} function will
* call the *closure*, a custom function definig your business. After the *closure* function
* be returned, the {@link lock} function automatically {@link ILockable.unlock unlocks} the
* mutex, even if the *closure* function throws any error.
*
* Therefore, when using this {@link lock} function, you don't need to consider about
* {@link ILockable.unlock returning} the lock acquistion after your business. It would just
* be done automatically.
*
* @param mutex Target mutex to write lock.
* @param closure A function defining your business.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
function lock(mutex, closure) {
return SafeLock_1.SafeLock.lock(function () { return mutex.lock(); }, function () { return mutex.unlock(); }, closure);
}
UniqueLock.lock = lock;
/**
* Tries to write lock a mutex with your business.
*
* Attempts to monopoly a mutex without blocking. If succeeded to monopoly the mutex
* immediately, it returns `true` after calling the *closure*. Otherwise there's someone who
* has already {@link ILockable.lock monopolied} or {@link ISharedLockable.lock shared} the
* mutex, the function gives up the trial immediately and returns `false` directly without
* calling the *closure*.
*
* When succeeded to {@link ILockable.lock monopoly} the mutex, the {@link try_lock} function
* will call the *closure*, a custom function definig your business. After the *closure*
* function be returned, the {@link try_lock} function automatically
* {@link ILockable.unlock unlocks} the mutex, even if the *closure* function throws any
* error.
*
* Therefore, when using this {@link try_lock} function, you don't need to consider about
* {@link ILockable.unlock returning} the lock acquistion after your business. It would just
* be done automatically.
*
* @param mutex Target mutex to try write lock.
* @param closure A function defining your business.
* @return Whether succeeded to monopoly the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
function try_lock(mutex, closure) {
return SafeLock_1.SafeLock.try_lock(function () { return mutex.try_lock(); }, function () { return mutex.unlock(); }, closure);
}
UniqueLock.try_lock = try_lock;
/**
* Tries to write lock a mutex with your business until timeout.
*
* Attempts to monopoly a mutex until timeout. If succeeded to monopoly the mutex until the
* timeout, it returns `true` after calling the *closure*. Otherwise failed to acquiring the
* lock in the given time, the function gives up the trial and returns `false` without calling
* the *closure*.
*
* Failed to acquiring the lock in the given time (returns `false`), it means that there's
* someone who has already {@link ILockable.lock monopolied} or {@link ISharedLockable.lock}
* the mutex and does not return it over the timeout.
*
* When succeeded to {@link ILockable.lock monopoly} the mutex, the {@link try_lock_for}
* function will call the *closure*, a custom function definig your business. After the
* *closure* function be returned, the {@link try_lock_for} function automatically
* {@link ILockable.unlock unlocks} the mutex and returns `true`, even if the *closure*
* function throws any error.
*
* Therefore, when using this {@link try_lock_for} function, you don't need to consider about
* {@link ILockable.unlock returning} the lock acquistion after your business. It would just
* be done automatically.
*
* @param mutex Target mutex to try write lock until timeout.
* @param ms The maximum miliseconds for waiting.
* @param closure A function defining your business.
* @return Whether succeeded to monopoly the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
function try_lock_for(mutex, ms, closure) {
return SafeLock_1.SafeLock.try_lock(function () { return mutex.try_lock_for(ms); }, function () { return mutex.unlock(); }, closure);
}
UniqueLock.try_lock_for = try_lock_for;
/**
* Tries to write lock a mutex with your business until time expiration.
*
* Attempts to monopoly a mutex until time expiration. If succeeded to monopoly the mutex
* until the time expiration, it returns `true` after calling the *closure*. Otherwise failed
* to acquiring the lock in the given time, the function gives up the trial and returns
* `false` without calling the *closure*.
*
* Failed to acquiring the lock in the given time (returns `false`), it means that there's
* someone who has already {@link ILockable.lock monopolied} or {@link ISharedLockable.lock}
* the mutex and does not return it over the time expiration.
*
* When succeeded to {@link ILockable.lock monopoly} the mutex, the {@link try_lock_until}
* function will call the *closure*, a custom function definig your business. After the
* *closure* function be returned, the {@link try_lock_until} function automatically
* {@link ILockable.unlock unlocks} the mutex and returns `true`, even if the *closure*
* function throws any error.
*
* TTherefore, when using this {@link try_lock_until} function, you don't need to consider
* about {@link ILockable.unlock returning} the lock acquistion after your business. It would
* just be done automatically.
*
* @param mutex Target mutex to try write lock until time expiration.
* @param at The maximum time point to wait.
* @param closure A function defining your business.
* @return Whether succeeded to monopoly the mutex or not.
*
* @throw Exception would be thrown if the *closure* function throws any error.
*/
function try_lock_until(mutex, at, closure) {
return SafeLock_1.SafeLock.try_lock(function () { return mutex.try_lock_until(at); }, function () { return mutex.unlock(); }, closure);
}
UniqueLock.try_lock_until = try_lock_until;
})(UniqueLock = exports.UniqueLock || (exports.UniqueLock = {}));
exports.UniqueLock = UniqueLock;
//# sourceMappingURL=UniqueLock.js.map
-26
View File
@@ -1,26 +0,0 @@
/**
* Variadic mutable singleton generator.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class VariadicMutableSingleton<T, Args extends any[]> {
/**
* @hidden
*/
private readonly closure_;
/**
* @hidden
*/
private readonly dict_;
constructor(closure: (...args: Args) => Promise<T>, hashFunc?: (args: Args) => number, pred?: (x: Args, y: Args) => boolean);
set(...items: [...Args, T]): Promise<void>;
reload(...args: Args): Promise<T>;
clear(): Promise<void>;
clear(...args: Args): Promise<void>;
get(...args: Args): Promise<T>;
is_loaded(...args: Args): Promise<boolean>;
/**
* @hidden
*/
private _Get_singleton;
}
-158
View File
@@ -1,158 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VariadicMutableSingleton = void 0;
//================================================================
/**
* @packageDocumentation
* @module std
*/
//================================================================
var HashMap_1 = require("../container/HashMap");
var MutableSingleton_1 = require("./MutableSingleton");
var iterations_1 = require("../ranges/algorithm/iterations");
var hash_1 = require("../functional/hash");
/**
* Variadic mutable singleton generator.
*
* @author Jeongho Nam - https://github.com/samchon
*/
var VariadicMutableSingleton = /** @class */ (function () {
/* ---------------------------------------------------------------
CONSTRUCTORS
--------------------------------------------------------------- */
function VariadicMutableSingleton(closure, hashFunc, pred) {
if (hashFunc === void 0) { hashFunc = function (args) { return hash_1.hash.apply(void 0, __spreadArray([], __read(args), false)); }; }
if (pred === void 0) { pred = iterations_1.equal; }
this.closure_ = closure;
this.dict_ = new HashMap_1.HashMap(hashFunc, pred);
}
VariadicMutableSingleton.prototype.set = function () {
var items = [];
for (var _i = 0; _i < arguments.length; _i++) {
items[_i] = arguments[_i];
}
var args = items.slice(0, items.length - 1);
var value = items[items.length - 1];
return this._Get_singleton(args).set(value);
};
VariadicMutableSingleton.prototype.reload = function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return (_a = this._Get_singleton(args)).reload.apply(_a, __spreadArray([], __read(args), false));
};
VariadicMutableSingleton.prototype.clear = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(args.length === 0)) return [3 /*break*/, 1];
this.dict_.clear();
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, this._Get_singleton(args).clear()];
case 2:
_a.sent();
_a.label = 3;
case 3: return [2 /*return*/];
}
});
});
};
/* ---------------------------------------------------------------
ACCESSORS
--------------------------------------------------------------- */
VariadicMutableSingleton.prototype.get = function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return (_a = this._Get_singleton(args)).get.apply(_a, __spreadArray([], __read(args), false));
};
VariadicMutableSingleton.prototype.is_loaded = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return this._Get_singleton(args).is_loaded();
};
/**
* @hidden
*/
VariadicMutableSingleton.prototype._Get_singleton = function (args) {
var it = this.dict_.find(args);
if (it.equals(this.dict_.end()) === true)
it = this.dict_.emplace(args, new MutableSingleton_1.MutableSingleton(this.closure_)).first;
return it.second;
};
return VariadicMutableSingleton;
}());
exports.VariadicMutableSingleton = VariadicMutableSingleton;
//# sourceMappingURL=VariadicMutableSingleton.js.map
-11
View File
@@ -1,11 +0,0 @@
/**
* Variadic singleton generator.
*
* @author Jeongho Nam - https://github.comm/samchon
*/
export declare class VariadicSingleton<T, Args extends any[]> {
private readonly closure_;
private readonly dict_;
constructor(closure: (...args: Args) => T, hashFunc?: (args: Args) => number, pred?: (x: Args, y: Args) => boolean);
get(...args: Args): T;
}
-65
View File
@@ -1,65 +0,0 @@
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VariadicSingleton = void 0;
//================================================================
/**
* @packageDocumentation
* @module std
*/
//================================================================
var Singleton_1 = require("./Singleton");
var HashMap_1 = require("../container/HashMap");
var hash_1 = require("../functional/hash");
var iterations_1 = require("../ranges/algorithm/iterations");
/**
* Variadic singleton generator.
*
* @author Jeongho Nam - https://github.comm/samchon
*/
var VariadicSingleton = /** @class */ (function () {
function VariadicSingleton(closure, hashFunc, pred) {
if (hashFunc === void 0) { hashFunc = function (args) { return hash_1.hash.apply(void 0, __spreadArray([], __read(args), false)); }; }
if (pred === void 0) { pred = iterations_1.equal; }
this.closure_ = closure;
this.dict_ = new HashMap_1.HashMap(hashFunc, pred);
}
VariadicSingleton.prototype.get = function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var it = this.dict_.find(args);
if (it.equals(this.dict_.end()) == true)
it = this.dict_.emplace(args, new Singleton_1.Singleton(this.closure_)).first;
return (_a = it.second).get.apply(_a, __spreadArray([], __read(args), false));
};
return VariadicSingleton;
}());
exports.VariadicSingleton = VariadicSingleton;
//# sourceMappingURL=VariadicSingleton.js.map
-32
View File
@@ -1,32 +0,0 @@
/**
* Variadic timed singleton generator.
*
* The `VariadicTimedSingleton` is a type of {@link VariadicSingleton} class who re-constructs
* the singleton value repeatedly whenever specific time has been elapsed after the last lazy
* construction.
*
* @template T Type of the value to be lazy-constructed
* @template Args Type of parameters of the lazy constructor function
* @author Jeongho Nam - https://github.com/samchon
*/
export declare class VariadicTimedSingleton<T, Args extends any[]> {
private readonly interval_;
private readonly closure_;
private readonly dict_;
/**
* Initializer Constructor.
*
* @param interval Specific interval time, to determine whether re-generation of the singleton value is required or not, as milliseconds
* @param closure Lazy constructor function returning the target value
* @param hasher Hash function for the *lazy constructor* function arguments
* @param pred Predicator function for the *lazy constructor* function arguments
*/
constructor(interval: number, closure: (...args: Args) => T, hasher?: (args: Args) => number, pred?: (x: Args, y: Args) => boolean);
/**
* Get value.
*
* @param args Parameters for the lazy constructor function
* @returns The lazy constructed value
*/
get(...args: Args): T;
}
-82
View File
@@ -1,82 +0,0 @@
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VariadicTimedSingleton = void 0;
var HashMap_1 = require("../container/HashMap");
var TimedSingleton_1 = require("./TimedSingleton");
var iterations_1 = require("../ranges/algorithm/iterations");
var hash_1 = require("../functional/hash");
/**
* Variadic timed singleton generator.
*
* The `VariadicTimedSingleton` is a type of {@link VariadicSingleton} class who re-constructs
* the singleton value repeatedly whenever specific time has been elapsed after the last lazy
* construction.
*
* @template T Type of the value to be lazy-constructed
* @template Args Type of parameters of the lazy constructor function
* @author Jeongho Nam - https://github.com/samchon
*/
var VariadicTimedSingleton = /** @class */ (function () {
/**
* Initializer Constructor.
*
* @param interval Specific interval time, to determine whether re-generation of the singleton value is required or not, as milliseconds
* @param closure Lazy constructor function returning the target value
* @param hasher Hash function for the *lazy constructor* function arguments
* @param pred Predicator function for the *lazy constructor* function arguments
*/
function VariadicTimedSingleton(interval, closure, hasher, pred) {
if (hasher === void 0) { hasher = function (args) { return hash_1.hash.apply(void 0, __spreadArray([], __read(args), false)); }; }
if (pred === void 0) { pred = iterations_1.equal; }
this.interval_ = interval;
this.closure_ = closure;
this.dict_ = new HashMap_1.HashMap(hasher, pred);
}
/**
* Get value.
*
* @param args Parameters for the lazy constructor function
* @returns The lazy constructed value
*/
VariadicTimedSingleton.prototype.get = function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var it = this.dict_.find(args);
if (it.equals(this.dict_.end()) == true) {
var singleton = new TimedSingleton_1.TimedSingleton(this.interval_, this.closure_);
it = this.dict_.emplace(args, singleton).first;
}
return (_a = it.second).get.apply(_a, __spreadArray([], __read(args), false));
};
return VariadicTimedSingleton;
}());
exports.VariadicTimedSingleton = VariadicTimedSingleton;
//# sourceMappingURL=VariadicTimedSingleton.js.map
-30
View File
@@ -1,30 +0,0 @@
/**
* @packageDocumentation
* @module std
*/
import { ILockable } from "../base/thread/ILockable";
/**
* Sleep for time span.
*
* @param ms The milliseconds to sleep.
*/
export declare function sleep_for(ms: number): Promise<void>;
/**
* Sleep until time expiration.
*
* @param at The time point to wake up.
*/
export declare function sleep_until(at: Date): Promise<void>;
/**
* Lock multiple mutexes.
*
* @param items Items to lock.
*/
export declare function lock(...items: Pick<ILockable, "lock">[]): Promise<void>;
/**
* Try lock mutexes.
*
* @param items Items to try lock.
* @return Index of mutex who failed to lock. None of them're failed, then returns `-1`.
*/
export declare function try_lock(...items: Pick<ILockable, "try_lock">[]): Promise<number>;
-146
View File
@@ -1,146 +0,0 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.try_lock = exports.lock = exports.sleep_until = exports.sleep_for = void 0;
/**
* Sleep for time span.
*
* @param ms The milliseconds to sleep.
*/
function sleep_for(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
}
exports.sleep_for = sleep_for;
/**
* Sleep until time expiration.
*
* @param at The time point to wake up.
*/
function sleep_until(at) {
var now = new Date();
var ms = at.getTime() - now.getTime(); // MILLISECONDS TO WAIT
return sleep_for(ms); // CONVERT TO THE SLEEP_FOR
}
exports.sleep_until = sleep_until;
/**
* Lock multiple mutexes.
*
* @param items Items to lock.
*/
function lock() {
var items = [];
for (var _i = 0; _i < arguments.length; _i++) {
items[_i] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
var promises, items_1, items_1_1, mtx;
var e_1, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
promises = [];
try {
for (items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
mtx = items_1_1.value;
promises.push(mtx.lock());
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
}
finally { if (e_1) throw e_1.error; }
}
return [4 /*yield*/, Promise.all(promises)];
case 1:
_b.sent();
return [2 /*return*/];
}
});
});
}
exports.lock = lock;
/**
* Try lock mutexes.
*
* @param items Items to try lock.
* @return Index of mutex who failed to lock. None of them're failed, then returns `-1`.
*/
function try_lock() {
var items = [];
for (var _i = 0; _i < arguments.length; _i++) {
items[_i] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
var i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
i = 0;
_a.label = 1;
case 1:
if (!(i < items.length)) return [3 /*break*/, 4];
return [4 /*yield*/, items[i].try_lock()];
case 2:
if ((_a.sent()) === false)
return [2 /*return*/, i];
_a.label = 3;
case 3:
++i;
return [3 /*break*/, 1];
case 4: return [2 /*return*/, -1];
}
});
});
}
exports.try_lock = try_lock;
//# sourceMappingURL=global.js.map
-21
View File
@@ -1,21 +0,0 @@
/**
* @packageDocumentation
* @module std
*/
export * from "./Mutex";
export * from "./TimedMutex";
export * from "./SharedMutex";
export * from "./SharedTimedMutex";
export * from "./ConditionVariable";
export * from "./UniqueLock";
export * from "./SharedLock";
export * from "./Semaphore";
export * from "./Latch";
export * from "./Barrier";
export * from "./MutableSingleton";
export * from "./TimedSingleton";
export * from "./VariadicMutableSingleton";
export * from "./VariadicTimedSingleton";
export * from "./VariadicSingleton";
export * from "./Singleton";
export * from "./global";
-40
View File
@@ -1,40 +0,0 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
//================================================================
/**
* @packageDocumentation
* @module std
*/
//================================================================
__exportStar(require("./Mutex"), exports);
__exportStar(require("./TimedMutex"), exports);
__exportStar(require("./SharedMutex"), exports);
__exportStar(require("./SharedTimedMutex"), exports);
__exportStar(require("./ConditionVariable"), exports);
__exportStar(require("./UniqueLock"), exports);
__exportStar(require("./SharedLock"), exports);
__exportStar(require("./Semaphore"), exports);
__exportStar(require("./Latch"), exports);
__exportStar(require("./Barrier"), exports);
__exportStar(require("./MutableSingleton"), exports);
__exportStar(require("./TimedSingleton"), exports);
__exportStar(require("./VariadicMutableSingleton"), exports);
__exportStar(require("./VariadicTimedSingleton"), exports);
__exportStar(require("./VariadicSingleton"), exports);
__exportStar(require("./Singleton"), exports);
__exportStar(require("./global"), exports);
//# sourceMappingURL=index.js.map