<A extends PrimaryKey.PrimaryKey>(self: HashRing<A>, count: number):
| Array<A>
| undefinedComputes a balanced shard distribution across the nodes in the ring.
When to use
Use to precompute ownership for a fixed number of shard indexes across the current ring members.
export const const getShards: <
A extends PrimaryKey.PrimaryKey
>(
self: HashRing<A>,
count: number
) => Array<A> | undefined
Computes a balanced shard distribution across the nodes in the ring.
When to use
Use to precompute ownership for a fixed number of shard indexes across the
current ring members.
getShards = <function (type parameter) A in <A extends PrimaryKey.PrimaryKey>(self: HashRing<A>, count: number): Array<A> | undefinedA extends import PrimaryKeyPrimaryKey.PrimaryKey>(self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self: interface HashRing<A extends PrimaryKey.PrimaryKey>A weighted consistent-hashing ring for assigning inputs to nodes with stable
remapping as nodes are added or removed.
When to use
Use to maintain a mutable weighted hash ring for routing keys or shards to
nodes identified by PrimaryKey.
Details
Nodes are identified by their PrimaryKey value and can be iterated from the
ring.
HashRing<function (type parameter) A in <A extends PrimaryKey.PrimaryKey>(self: HashRing<A>, count: number): Array<A> | undefinedA>, count: numbercount: number): interface Array<T>Array<function (type parameter) A in <A extends PrimaryKey.PrimaryKey>(self: HashRing<A>, count: number): Array<A> | undefinedA> | undefined => {
if (self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.HashRing<A extends PrimaryKey.PrimaryKey>.ring: [hash: number, node: string][]ring.Array<[hash: number, node: string]>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.
length === 0) {
return var undefinedundefined
}
const const shards: A[]shards = new var Array: ArrayConstructor
new <A>(arrayLength: number) => A[] (+2 overloads)
Array<function (type parameter) A in <A extends PrimaryKey.PrimaryKey>(self: HashRing<A>, count: number): Array<A> | undefinedA>(count: numbercount)
// for tracking how many shards have been allocated to each node
const const allocations: Map<string, number>allocations = new var Map: MapConstructor
new <string, number>(iterable?: Iterable<readonly [string, number]> | null | undefined) => Map<string, number> (+3 overloads)
Map<string, number>()
// for tracking which shards still need to be allocated
const const remaining: Set<number>remaining = new var Set: SetConstructor
new <number>(iterable?: Iterable<number> | null | undefined) => Set<number> (+1 overload)
Set<number>()
// for tracking which nodes have reached the max allocation
const const exclude: Set<string>exclude = new var Set: SetConstructor
new <string>(iterable?: Iterable<string> | null | undefined) => Set<string> (+1 overload)
Set<string>()
// First pass - allocate the closest nodes, skipping nodes that have reached
// max
const const distances: [
shard: number,
node: string,
distance: number
][]
distances = new var Array: ArrayConstructor
new <[shard: number, node: string, distance: number]>(arrayLength: number) => [shard: number, node: string, distance: number][] (+2 overloads)
Array<[numbershard: number, stringnode: string, numberdistance: number]>(count: numbercount)
for (let let shard: numbershard = 0; let shard: numbershard < count: numbercount; let shard: numbershard++) {
const const hash: numberhash = (const shardHashes: number[]shardHashes[let shard: numbershard] ??= import HashHash.string(`shard-${let shard: numbershard}`))
const [const index: numberindex, const distance: numberdistance] = function getIndexForInput<
A extends PrimaryKey.PrimaryKey
>(
self: HashRing<A>,
hash: number,
exclude?: ReadonlySet<string> | undefined
): readonly [index: number, distance: number]
getIndexForInput(self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self, const hash: numberhash)
const const node: stringnode = self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.HashRing<A extends PrimaryKey.PrimaryKey>.ring: [hash: number, node: string][]ring[const index: numberindex][1]!
const distances: [
shard: number,
node: string,
distance: number
][]
distances[let shard: numbershard] = [let shard: numbershard, const node: stringnode, const distance: numberdistance]
const remaining: Set<number>remaining.Set<number>.add(value: number): Set<number>Appends a new element with a specified value to the end of the Set.
add(let shard: numbershard)
}
const distances: [
shard: number,
node: string,
distance: number
][]
distances.Array<[shard: number, node: string, distance: number]>.sort(compareFn?: ((a: [shard: number, node: string, distance: number], b: [shard: number, node: string, distance: number]) => number) | undefined): [shard: number, node: string, distance: number][]Sorts an array in place.
This method mutates the array and returns a reference to the same array.
sort((a: [
shard: number,
node: string,
distance: number
]
(parameter) a: {
0: number;
1: string;
2: number;
length: 3;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
pop: () => string | number | undefined;
push: (...items: Array<string | number>) => number;
concat: { (...items: Array<ConcatArray<string | number>>): Array<string | number>; (...items: Array<string | number | ConcatArray<string | number>>): Array<string | number> };
join: (separator?: string) => string;
reverse: () => Array<string | number>;
shift: () => string | number | undefined;
slice: (start?: number, end?: number) => Array<string | number>;
sort: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => [shard: number, node: string, distance: number];
splice: { (start: number, deleteCount?: number): Array<string | number>; (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number> };
unshift: (...items: Array<string | number>) => number;
indexOf: (searchElement: string | number, fromIndex?: number) => number;
lastIndexOf: (searchElement: string | number, fromIndex?: number) => number;
every: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): this is S[]; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any):…;
some: (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: string | number, index: number, array: Array<string | number>) => void, thisArg?: any) => void;
map: (callbackfn: (value: string | number, index: number, array: Array<string | number>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): Array<S>; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any): Ar…;
reduce: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: Array<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: string | …;
reduceRight: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: Array<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: string | …;
find: { (predicate: (value: string | number, index: number, obj: Array<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, obj: Array<string | number>) => unknown, thisArg?: any): s…;
findIndex: (predicate: (value: string | number, index: number, obj: Array<string | number>) => unknown, thisArg?: any) => number;
fill: (value: string | number, start?: number, end?: number) => [shard: number, node: string, distance: number];
copyWithin: (target: number, start: number, end?: number) => [shard: number, node: string, distance: number];
entries: () => ArrayIterator<[number, string | number]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<string | number>;
includes: (searchElement: string | number, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: string | number, index: number, array: Array<string | number>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => string | number | undefined;
findLast: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any…;
findLastIndex: (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any) => number;
toReversed: () => Array<string | number>;
toSorted: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => Array<string | number>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number>; (start: number, deleteCount?: number): Array<string | number> };
with: (index: number, value: string | number) => Array<string | number>;
}
a, b: [
shard: number,
node: string,
distance: number
]
(parameter) b: {
0: number;
1: string;
2: number;
length: 3;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
pop: () => string | number | undefined;
push: (...items: Array<string | number>) => number;
concat: { (...items: Array<ConcatArray<string | number>>): Array<string | number>; (...items: Array<string | number | ConcatArray<string | number>>): Array<string | number> };
join: (separator?: string) => string;
reverse: () => Array<string | number>;
shift: () => string | number | undefined;
slice: (start?: number, end?: number) => Array<string | number>;
sort: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => [shard: number, node: string, distance: number];
splice: { (start: number, deleteCount?: number): Array<string | number>; (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number> };
unshift: (...items: Array<string | number>) => number;
indexOf: (searchElement: string | number, fromIndex?: number) => number;
lastIndexOf: (searchElement: string | number, fromIndex?: number) => number;
every: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): this is S[]; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any):…;
some: (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: string | number, index: number, array: Array<string | number>) => void, thisArg?: any) => void;
map: (callbackfn: (value: string | number, index: number, array: Array<string | number>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): Array<S>; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any): Ar…;
reduce: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: Array<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: string | …;
reduceRight: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: Array<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: string | …;
find: { (predicate: (value: string | number, index: number, obj: Array<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, obj: Array<string | number>) => unknown, thisArg?: any): s…;
findIndex: (predicate: (value: string | number, index: number, obj: Array<string | number>) => unknown, thisArg?: any) => number;
fill: (value: string | number, start?: number, end?: number) => [shard: number, node: string, distance: number];
copyWithin: (target: number, start: number, end?: number) => [shard: number, node: string, distance: number];
entries: () => ArrayIterator<[number, string | number]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<string | number>;
includes: (searchElement: string | number, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: string | number, index: number, array: Array<string | number>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => string | number | undefined;
findLast: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any…;
findLastIndex: (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any) => number;
toReversed: () => Array<string | number>;
toSorted: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => Array<string | number>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number>; (start: number, deleteCount?: number): Array<string | number> };
with: (index: number, value: string | number) => Array<string | number>;
}
b) => a: [
shard: number,
node: string,
distance: number
]
(parameter) a: {
0: number;
1: string;
2: number;
length: 3;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
pop: () => string | number | undefined;
push: (...items: Array<string | number>) => number;
concat: { (...items: Array<ConcatArray<string | number>>): Array<string | number>; (...items: Array<string | number | ConcatArray<string | number>>): Array<string | number> };
join: (separator?: string) => string;
reverse: () => Array<string | number>;
shift: () => string | number | undefined;
slice: (start?: number, end?: number) => Array<string | number>;
sort: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => [shard: number, node: string, distance: number];
splice: { (start: number, deleteCount?: number): Array<string | number>; (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number> };
unshift: (...items: Array<string | number>) => number;
indexOf: (searchElement: string | number, fromIndex?: number) => number;
lastIndexOf: (searchElement: string | number, fromIndex?: number) => number;
every: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): this is S[]; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any):…;
some: (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: string | number, index: number, array: Array<string | number>) => void, thisArg?: any) => void;
map: (callbackfn: (value: string | number, index: number, array: Array<string | number>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): Array<S>; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any): Ar…;
reduce: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: Array<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: string | …;
reduceRight: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: Array<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: string | …;
find: { (predicate: (value: string | number, index: number, obj: Array<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, obj: Array<string | number>) => unknown, thisArg?: any): s…;
findIndex: (predicate: (value: string | number, index: number, obj: Array<string | number>) => unknown, thisArg?: any) => number;
fill: (value: string | number, start?: number, end?: number) => [shard: number, node: string, distance: number];
copyWithin: (target: number, start: number, end?: number) => [shard: number, node: string, distance: number];
entries: () => ArrayIterator<[number, string | number]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<string | number>;
includes: (searchElement: string | number, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: string | number, index: number, array: Array<string | number>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => string | number | undefined;
findLast: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any…;
findLastIndex: (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any) => number;
toReversed: () => Array<string | number>;
toSorted: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => Array<string | number>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number>; (start: number, deleteCount?: number): Array<string | number> };
with: (index: number, value: string | number) => Array<string | number>;
}
a[2] - b: [
shard: number,
node: string,
distance: number
]
(parameter) b: {
0: number;
1: string;
2: number;
length: 3;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
pop: () => string | number | undefined;
push: (...items: Array<string | number>) => number;
concat: { (...items: Array<ConcatArray<string | number>>): Array<string | number>; (...items: Array<string | number | ConcatArray<string | number>>): Array<string | number> };
join: (separator?: string) => string;
reverse: () => Array<string | number>;
shift: () => string | number | undefined;
slice: (start?: number, end?: number) => Array<string | number>;
sort: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => [shard: number, node: string, distance: number];
splice: { (start: number, deleteCount?: number): Array<string | number>; (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number> };
unshift: (...items: Array<string | number>) => number;
indexOf: (searchElement: string | number, fromIndex?: number) => number;
lastIndexOf: (searchElement: string | number, fromIndex?: number) => number;
every: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): this is S[]; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any):…;
some: (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: string | number, index: number, array: Array<string | number>) => void, thisArg?: any) => void;
map: (callbackfn: (value: string | number, index: number, array: Array<string | number>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): Array<S>; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any): Ar…;
reduce: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: Array<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: string | …;
reduceRight: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: Array<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: string | …;
find: { (predicate: (value: string | number, index: number, obj: Array<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, obj: Array<string | number>) => unknown, thisArg?: any): s…;
findIndex: (predicate: (value: string | number, index: number, obj: Array<string | number>) => unknown, thisArg?: any) => number;
fill: (value: string | number, start?: number, end?: number) => [shard: number, node: string, distance: number];
copyWithin: (target: number, start: number, end?: number) => [shard: number, node: string, distance: number];
entries: () => ArrayIterator<[number, string | number]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<string | number>;
includes: (searchElement: string | number, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: string | number, index: number, array: Array<string | number>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => string | number | undefined;
findLast: { (predicate: (value: string | number, index: number, array: Array<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any…;
findLastIndex: (predicate: (value: string | number, index: number, array: Array<string | number>) => unknown, thisArg?: any) => number;
toReversed: () => Array<string | number>;
toSorted: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => Array<string | number>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number>; (start: number, deleteCount?: number): Array<string | number> };
with: (index: number, value: string | number) => Array<string | number>;
}
b[2])
for (let let i: numberi = 0; let i: numberi < count: numbercount; let i: numberi++) {
const [const shard: numbershard, const node: stringnode] = const distances: [
shard: number,
node: string,
distance: number
][]
distances[let i: numberi]
if (const exclude: Set<string>exclude.Set<string>.has(value: string): booleanhas(const node: stringnode)) continue
const [const value: A extends PrimaryKey.PrimaryKeyvalue, const weight: numberweight] = self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.HashRing<A>.nodes: Map<string, [node: A, weight: number]>nodes.Map<string, [node: A, weight: number]>.get(key: string): [node: A, weight: number] | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const node: stringnode)!
const shards: A[]shards[const shard: numbershard] = const value: A extends PrimaryKey.PrimaryKeyvalue
const remaining: Set<number>remaining.Set<number>.delete(value: number): booleanRemoves a specified value from the Set.
delete(const shard: numbershard)
const const nodeCount: numbernodeCount = (const allocations: Map<string, number>allocations.Map<string, number>.get(key: string): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const node: stringnode) ?? 0) + 1
const allocations: Map<string, number>allocations.Map<string, number>.set(key: string, value: number): Map<string, number>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const node: stringnode, const nodeCount: numbernodeCount)
const const maxPerNode: numbermaxPerNode = var Math: MathAn intrinsic object that provides basic mathematics functionality and constants.
Math.Math.max(...values: number[]): numberReturns the larger of a set of supplied numeric expressions.
max(1, var Math: MathAn intrinsic object that provides basic mathematics functionality and constants.
Math.Math.floor(x: number): numberReturns the greatest integer less than or equal to its numeric argument.
floor(count: numbercount * (const weight: numberweight / self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.HashRing<A extends PrimaryKey.PrimaryKey>.totalWeightCache: numbertotalWeightCache)))
if (const nodeCount: numbernodeCount >= const maxPerNode: numbermaxPerNode) {
const exclude: Set<string>exclude.Set<string>.add(value: string): Set<string>Appends a new element with a specified value to the end of the Set.
add(const node: stringnode)
}
}
// Second pass - allocate any remaining shards, skipping nodes that have
// reached max
let let allAtMax: booleanallAtMax = const exclude: Set<string>exclude.Set<T>.size: numbersize === self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.HashRing<A>.nodes: Map<string, [node: A, weight: number]>nodes.Map<K, V>.size: numbersize
const remaining: Set<number>remaining.Set<number>.forEach(callbackfn: (value: number, value2: number, set: Set<number>) => void, thisArg?: any): voidExecutes a provided function once per each value in the Set object, in insertion order.
forEach((shard: numbershard) => {
const const index: numberindex = function getIndexForInput<
A extends PrimaryKey.PrimaryKey
>(
self: HashRing<A>,
hash: number,
exclude?: ReadonlySet<string> | undefined
): readonly [index: number, distance: number]
getIndexForInput(self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self, const shardHashes: number[]shardHashes[shard: numbershard], let allAtMax: booleanallAtMax ? var undefinedundefined : const exclude: Set<string>exclude)[0]
const const node: stringnode = self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.HashRing<A extends PrimaryKey.PrimaryKey>.ring: [hash: number, node: string][]ring[const index: numberindex][1]
const [const value: A extends PrimaryKey.PrimaryKeyvalue, const weight: numberweight] = self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.HashRing<A>.nodes: Map<string, [node: A, weight: number]>nodes.Map<string, [node: A, weight: number]>.get(key: string): [node: A, weight: number] | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const node: stringnode)!
const shards: A[]shards[shard: numbershard] = const value: A extends PrimaryKey.PrimaryKeyvalue
if (let allAtMax: booleanallAtMax) return
const const nodeCount: numbernodeCount = (const allocations: Map<string, number>allocations.Map<string, number>.get(key: string): number | undefinedReturns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
get(const node: stringnode) ?? 0) + 1
const allocations: Map<string, number>allocations.Map<string, number>.set(key: string, value: number): Map<string, number>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(const node: stringnode, const nodeCount: numbernodeCount)
const const maxPerNode: numbermaxPerNode = var Math: MathAn intrinsic object that provides basic mathematics functionality and constants.
Math.Math.max(...values: number[]): numberReturns the larger of a set of supplied numeric expressions.
max(1, var Math: MathAn intrinsic object that provides basic mathematics functionality and constants.
Math.Math.floor(x: number): numberReturns the greatest integer less than or equal to its numeric argument.
floor(count: numbercount * (const weight: numberweight / self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.HashRing<A extends PrimaryKey.PrimaryKey>.totalWeightCache: numbertotalWeightCache)))
if (const nodeCount: numbernodeCount >= const maxPerNode: numbermaxPerNode) {
const exclude: Set<string>exclude.Set<string>.add(value: string): Set<string>Appends a new element with a specified value to the end of the Set.
add(const node: stringnode)
if (const exclude: Set<string>exclude.Set<T>.size: numbersize === self: HashRing<A>(parameter) self: {
baseWeight: number;
totalWeightCache: number;
nodes: Map<string, [node: A, weight: number]>;
ring: Array<[hash: number, node: string]>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
self.HashRing<A>.nodes: Map<string, [node: A, weight: number]>nodes.Map<K, V>.size: numbersize) {
let allAtMax: booleanallAtMax = true
}
}
})
return const shards: A[]shards
}