From fa4f2789b163badb7fc6327a15c05c511336f799 Mon Sep 17 00:00:00 2001 From: Momtchil Momtchev Date: Sat, 22 Aug 2020 12:09:51 +0200 Subject: [PATCH] release 1.2.0 --- docs/global.html | 2209 +++++++++++++++++++++++++++++++++++++- docs/index.html | 8 +- docs/index.js.html | 15 +- docs/module.exports.html | 314 ++++++ package-lock.json | 2 +- package.json | 2 +- 6 files changed, 2532 insertions(+), 18 deletions(-) create mode 100644 docs/module.exports.html diff --git a/docs/global.html b/docs/global.html index 2912187..f5778a4 100644 --- a/docs/global.html +++ b/docs/global.html @@ -94,7 +94,2206 @@

+

Members

+ + +

length

+ + + + +
+ Number of elements present +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + +

size

+ + + + +
+ Maximum number of elements allowed +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + +

Methods

+ + + + + + + +

clear() → {void}

+ + + + + + +
+ Clear the SharedMap +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + + + + + + +

delete(key, optopt) → {void}

+ + + + + + +
+ Delete an element, fully thread-safe, acquires an exlusive lock and it is very expensive +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
key + + +string + + + + + + + + + +
opt + + +SharedMapOptions + + + + + + <optional>
+ + + + + +
options, { lockExclusive: true } if manually calling lockExlusive
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + + + + + + +

get(key, optopt) → {string|undefined}

+ + + + + + +
+ Get an element, fully thread-safe, multiple get/set can execute in parallel +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
key + + +string + + + + + + + + + +
opt + + +SharedMapOptions + + + + + + <optional>
+ + + + + +
options, { lockWrite: true } if manually calling lockWrite
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +string +| + +undefined + + +
+
+ + + + + + + + + + + + + +

has(key, optopt) → {boolean}

+ + + + + + +
+ Find an element, fully thread-safe, identical to get(key) !== undefined +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
key + + +string + + + + + + + + + +
opt + + +SharedMapOptions + + + + + + <optional>
+ + + + + +
options, { lockWrite: true } if manually calling lockWrite
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + + + + +

(generator) keys(optopt) → {Iterable}

+ + + + + + +
+ A generator that can be used to iterate over the keys, thread-safe but allows +additions and deletions during the iteration +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
opt + + +SharedMapOptions + + + + + + <optional>
+ + + + + +
options, { lockWrite: true } if manually calling lockWrite
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Iterable + + +
+
+ + + + + + + + + + + + + +

lockExclusive() → {void}

+ + + + + + +
+ Acquire an exclusive lock, +All operations that need it, automatically acquire it, +Use only if you need to block all other threads from accessing the map; +The thread holding the lock can then call map.set(k, v, {lockHeld: true}) +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + + + + + + +

lockWrite() → {void}

+ + + + + + +
+ Acquire a write lock, +All operations that need it, automatically acquire it, +Use only if you need to block all other threads from writing to the map, +The thread holding the lock can then call map.set(k, v, {lockHeld: true}) +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + +
Example
+ +
myMap.lockWrite();
+for (let k of myMap.keys({lockWrite: true}))
+  myMap.set(k,
+    myMap.get(k, {lockWrite: true}).toUpperCase(),
+    {lockWrite: true});
+myMap.unlockWrite();
+ + + + + + + + + +

map(cb, thisArgopt) → {Array}

+ + + + + + +
+ A thread-safe map(). Doesn't block additions or deletions +between two calls of the callback, +all map operations are guaranteed atomic, +map.get(index)=currentValue is guaranteed while the callback runs, +You shall not manipulate the map in the callback, use an explicitly-locked +keys() in this case (look at the example for lockWrite) +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
cb + + +mapCallback + + + + + + + + + + callback
thisArg + + +* + + + + + + <optional>
+ + + + + +
callback will have its this set to thisArg
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Array + + +
+
+ + + + + + + + + + + + + +

reduce(cb, initialValue) → {*}

+ + + + + + +
+ A thread-safe reduce(). Doesn't block additions or deletions +between two calls of the callback, +map.get(key)=currentValue is guaranteed while the callback runs, +You shall not manipulate the map in the callback, use an explicitly-locked +keys() in this case (look at the example for lockWrite) +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
cb + + +reduceCallback + + + + callback
initialValue + + +* + + + + initial value of the accumulator
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +* + + +
+
+ + + + + + + + + + + + + +

set(key, value, optopt) → {void}

+ + + + + + +
+ Add/replace an element, fully thread-safe, multiple get/set can execute in parallel +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
key + + +string + + + + + + + + + +
value + + +string +| + +number + + + + + + + + + +
opt + + +SharedMapOptions + + + + + + <optional>
+ + + + + +
options, { lockWrite: true } if manually calling lockWrite
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Throws:
+ + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + + + + + + +

unlockExclusive() → {void}

+ + + + + + +
+ Release the exclusive lock +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + + + + + + +

unlockWrite() → {void}

+ + + + + + +
+ Release the write lock +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + @@ -246,7 +2445,7 @@
Parameters:
Source:
@@ -448,7 +2647,7 @@
Parameters:
Source:
@@ -605,7 +2804,7 @@
Properties:
Source:
@@ -635,13 +2834,13 @@
Properties:

diff --git a/docs/index.html b/docs/index.html index a7b6ba8..98374f0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -66,8 +66,8 @@

Introduction

As the language matures, driven by a remarkably well implemented engine (V8) and the unique promise of unifying back-end, front-end and desktop application development, real multi-threading for CPU-bound tasks is becoming an absolute necessity. In a true JS spirit, a feature after feature is added, some projects implementing it, others boycotting it, leaving it to the crowd to eventually decide what is worth supporting and what is not. As much as this can appear appalling to computer language experts, it is in a quite a way reminiscent of how the Linux kernel imposed itself vs the tech giants 20 years ago, and this is how JS is today on its way to total dominance as the leading general-purpose language.

The current situation with SharedArrayBuffer is a perfect example of this JS spirit. In the hope that at some point in the near future Firefox will re-enable it by default, and Safari will implement it, SharedMap is proposed as a working solution for computationally-heavy back-end programs executing in Node.js.

-

SharedMap is browser-compatible in theory, but on the front-end side, when one of the major browsers is completely missing (Safari), and another one requires the user to go through a security warning to enable an obscure feature (Firefox), its usefulness will be severely limited. For this reason I haven't even bothered to include an ES Modules interface, but you are free to try it in your Chrome/Edge-exclusive project.

-

SharedMap was motivated by igc-xc-score, a linear optimization solver for scoring paragliding flights. When I started it, I initially tried Python because of its flawless multi-threading and then I slowly realized that the single-threaded V8 implementation was faster then the 4-way multi-threaded Python3 (and PyPy) implementation. Love it or hate it, JS is here to stay for the years to come.

+

SharedMap is browser-compatible in theory, but on the front-end side, when one of the major browsers is completely missing (Safari), and another one requires the user to go through a security warning to enable an obscure feature (Firefox), its usefulness will be severely limited. An ES Module interface is provided and also TS definitions courtesy of @takase1121, so feel free to try it in your Chrome/Edge-exclusive project.

+

SharedMap was motivated by igc-xc-score, a linear optimization solver for scoring paragliding flights. When I started it, I initially tried Python because of its flawless multi-threading and then I slowly realized that the single-threaded V8 implementation was faster than the 4-way multi-threaded Python3 (and PyPy) implementation. Love it or hate it, JS is here to stay for the years to come.

About

Because of the severe limitations that SharedArrayBuffer imposes, SharedMap supports only numbers and strings and uses fixed memory allocation. It uses synchronous locking, implemented on top of the Atomics interface.

The HashMap is a coalesced HashMap and has almost no performance drop up to 95% fill ratio and it is still usable up to 99.99%. @@ -172,13 +172,13 @@

License


diff --git a/docs/index.js.html b/docs/index.js.html index 92edf0e..c74c08a 100644 --- a/docs/index.js.html +++ b/docs/index.js.html @@ -113,7 +113,7 @@

Source: index.js

* @author Momtchil Momtchev <momtchil@momtchev.com> * @see http://github.com/mmomtchev/SharedMap */ -class SharedMap { +export default class SharedMap { /** * Creates a new SharedMap * @param {number} maxSize - Maximum number of entries @@ -372,7 +372,7 @@

Source: index.js

__printMap() { for (let i = 0; i < this.meta[META.maxSize]; i++) console.log(this._decodeBucket(i, 0)); - process.exit(1); + if (typeof process !== 'undefined') process.exit(1); } /** @@ -407,8 +407,10 @@

Source: index.js

this.stats.collisions++; /* Replacing existing key */ if (this._match(key, pos)) { - for (let i = 0; i < value.length; i++) + let i; + for (i = 0; i < value.length; i++) this.valuesData[pos * this.meta[META.objSize] + i] = value.charCodeAt(i); + this.valuesData[pos * this.meta[META.objSize] + i] = 0; exclusive || this._unlockLine(slidingLock); return; } @@ -774,8 +776,7 @@

Source: index.js

this.unlockExclusive(); } } - -module.exports = SharedMap; + @@ -785,13 +786,13 @@

Source: index.js


diff --git a/docs/module.exports.html b/docs/module.exports.html new file mode 100644 index 0000000..de7b9ea --- /dev/null +++ b/docs/module.exports.html @@ -0,0 +1,314 @@ + + + + + JSDoc: Class: exports + + + + + + + + + + +
+ +

Class: exports

+ + + + + + +
+ +
+ +

exports(maxSize, keySize, objSize) → {SharedMap}

+ +
SharedMap + +zero-dependency +high-performance +unordered +Vanilla JS implementation of SharedMap, +a synchronous multi-threading capable, +fine-grain-locked with deadlock recovery, +static memory allocated, +coalesced-chaining HashMap, +backed by SharedArrayBuffer +that supports deleting +and is capable of auto-defragmenting itself on delete unless almost full +compatible with both Node.js and SharedArrayBuffer-enabled browsers
+ + +
+ +
+
+ + + + +

Constructor

+ + + +

new exports(maxSize, keySize, objSize) → {SharedMap}

+ + + + + + +
+ Creates a new SharedMap +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
maxSize + + +number + + + + Maximum number of entries
keySize + + +number + + + + Maximum length of keys in UTF-16 codepoints
objSize + + +number + + + + Maximum length of values in UTF-16 codepoints
+ + + + + + +
+ + + + + + + + + + + + + + + + + + +
Author:
+
+ +
+ + + + + + + + + +
Source:
+
+ + + + + +
See:
+
+ +
+ + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +SharedMap + + +
+
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index defd710..07e01f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sharedmap", - "version": "1.2.0-git", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e1bedf7..15604bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sharedmap", - "version": "1.2.0-git", + "version": "1.2.0", "description": "Multithreading-compatible SharedMap in vanilla JS", "main": "index.umd.js", "module": "index.es.js",