Skip to content

Commit

Permalink
Implement identification primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
belochub committed Dec 17, 2018
1 parent 007aba9 commit 969a81f
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 6 deletions.
122 changes: 122 additions & 0 deletions lib/identification.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
'use strict';

const { Uint64, sequence } = require('@metarhia/common');
const { StorageProvider } = require('./provider');

class RemoteServer extends StorageProvider {
constructor({
host,
ports,
}, providerOptions) {
super(providerOptions);
this.host = host;
this.ports = ports;
if (this.ports.length > 1) {
this.ports = sequence(this.ports, 0);
}
this.pool = [];
}
}

const getTreeDepth = (node, depth = 0) => {
if (node[0] && node[1]) {
return Math.max(
getTreeDepth(node[0], depth + 1),
getTreeDepth(node[1], depth + 1)
);
}
return depth;
};

const arrayifyTree = node => {
if (node[0] && node[1]) {
return [arrayifyTree(node[0]), arrayifyTree(node[1])];
} else {
return node;
}
};

const buildIndex = (tree, depth, serverIds) => {
const result = new Array(Math.pow(2, depth));

const parseTree = (index, depth, node) => {
const isLeaf = !node[0] || !node[1];
if (isLeaf) {
const serverSuffix = new Uint64(index)
.shiftLeft(SYSTEM_BITMASK_SIZE)
.or(serverIds.systemSuffix);
const serverBitmask = new Uint64(1)
.shiftLeft(depth)
.dec()
.shiftLeft(SYSTEM_BITMASK_SIZE)
.or(SYSTEM_BITMASK);

result[index] = new RemoteServer(node, Object.assign({}, serverIds, {
serverSuffix,
serverBitmask,
}));
for (let i = 1 << depth; i < result.length; i <<= 1) {
result[index | i] = result[index];
}
return;
}
parseTree(index, depth + 1, node[0]);
parseTree(index + (1 << depth), depth + 1, node[1]);
};
parseTree(0, 0, tree);

return result;
};

const SYSTEM_BITMASK_SIZE = 24;
const SYSTEM_BITMASK = new Uint64(1).shiftLeft(SYSTEM_BITMASK_SIZE).dec();

class ServerTree {
constructor(tree, systemId) {
this.tree = arrayifyTree(tree);
this.depth = getTreeDepth(this.tree);
this.serverBitmask = new Uint64(1).shiftLeft(this.depth).dec();
this.treeIndex = buildIndex(this.tree, this.depth, {
systemSuffix: new Uint64(systemId),
systemBitmask: new Uint64(SYSTEM_BITMASK),
});
}

findServer(id) {
return this.treeIndex[
Uint64.shiftRight(id, SYSTEM_BITMASK_SIZE)
.and(this.serverBitmask).toUint32()
];
}

toJSON() {
return this.tree;
}
}

class SystemList {
constructor(systems) {
this.systems = {};
for (const id in systems) {
this.systems[id] = new ServerTree(systems[id], new Uint64(id));
}
}

findServer(id) {
const serverTree = this.systems[Uint64.and(SYSTEM_BITMASK).toUint32()];
if (!serverTree) {
return null;
}
return serverTree.findServer(id);
}

toJSON() {
return this.systems;
}
}

module.exports = {
RemoteServer,
ServerTree,
SystemList,
};
7 changes: 1 addition & 6 deletions lib/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ const { GSError, codes: errorCodes } = require('./errors');
const { createRemoteProviderJstpApi } =
require('./remote.provider.jstp.api.js');

const SYSTEM_BITMASK_SIZE = 24;

// Abstract Storage Provider
class StorageProvider {
// Create StorageProvider
Expand Down Expand Up @@ -225,7 +223,4 @@ class StorageProvider {
}
}

module.exports = {
StorageProvider,
SYSTEM_BITMASK_SIZE,
};
module.exports = { StorageProvider };

0 comments on commit 969a81f

Please sign in to comment.