Skip to content

Commit fc8f666

Browse files
committed
[hash] Work around v5 implementation
1 parent 48da231 commit fc8f666

File tree

6 files changed

+120
-68
lines changed

6 files changed

+120
-68
lines changed

src/@types/common/docs.js

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -333,22 +333,20 @@
333333

334334
/**
335335
* The getTablesHash function returns a hash for the tabular part of a Store,
336-
* based on each Table and a top-level tabular HLC.
336+
* based on each Table Id and hash.
337337
* @param tableHashes An object containing each Table Id and its hash.
338-
* @param tablesHlc The top-level HLC of the tabular part of the Store.
339338
* @returns A hash of the Tables.
340339
* @example
341340
* This example gets the hash of the tabular part of a Store.
342341
* ```js
343342
* import {getTablesHash} from 'tinybase';
344343
*
345344
* const tableHashes = {
346-
* pets: 2544679909, // hash of its contents
345+
* pets: 4262151841, // hash of its contents
347346
* };
348-
* const tablesHlc = '03E3B------mmxrx';
349347
*
350-
* console.log(getTablesHash(tableHashes, tablesHlc));
351-
* // -> 1835775460
348+
* console.log(getTablesHash(tableHashes));
349+
* // -> 278115833
352350
* ```
353351
* @category Hash
354352
* @since v6.2.0
@@ -367,10 +365,10 @@
367365
* import {getTableInTablesHash} from 'tinybase';
368366
*
369367
* const tableId = 'pets';
370-
* const tableHash = 2544679909; // hash of its contents
368+
* const tableHash = 4262151841; // hash of its contents
371369
*
372370
* console.log(getTableInTablesHash(tableId, tableHash));
373-
* // -> 2778789628
371+
* // -> 278115833
374372
* ```
375373
* @category Hash
376374
* @since v6.2.0
@@ -379,22 +377,20 @@
379377

380378
/**
381379
* The getTableHash function returns a hash for a single Table in a Store, based
382-
* on each Row and the HLC of the Table.
380+
* on each Row Id and hash.
383381
* @param rowHashes An object containing each Row Id and its hash.
384-
* @param tableHlc The HLC of the Table.
385382
* @returns A hash of the Table.
386383
* @example
387384
* This example gets the hash of a Table.
388385
* ```js
389386
* import {getTableHash} from 'tinybase';
390387
*
391388
* const rowHashes = {
392-
* fido: 703486916, // hash of its contents
389+
* fido: 1810444343, // hash of its contents
393390
* };
394-
* const tableHlc = '03E3B------mmxrx';
395391
*
396-
* console.log(getTableHash(rowHashes, tableHlc));
397-
* // -> 2544679909
392+
* console.log(getTableHash(rowHashes));
393+
* // -> 4262151841
398394
* ```
399395
* @category Hash
400396
* @since v6.2.0
@@ -413,10 +409,10 @@
413409
* import {getRowInTableHash} from 'tinybase';
414410
*
415411
* const rowId = 'fido';
416-
* const rowHash = 703486916; // hash of its contents
412+
* const rowHash = 1810444343; // hash of its contents
417413
*
418414
* console.log(getRowInTableHash(rowId, rowHash));
419-
* // -> 1600649469
415+
* // -> 4262151841
420416
* ```
421417
* @category Hash
422418
* @since v6.2.0
@@ -425,9 +421,8 @@
425421

426422
/**
427423
* The getRowHash function returns a hash for a single Row in a Table, based on
428-
* each Cell and the HLC of the Row.
424+
* each Cell Id and hash.
429425
* @param cellHashes An object containing each Cell Id and its hash.
430-
* @param rowHlc The HLC of the Row.
431426
* @returns A hash of the Row.
432427
* @example
433428
* This example gets the hash of a Row.
@@ -437,10 +432,9 @@
437432
* const cellHashes = {
438433
* 'species': 3002200796, // hash of 'dog' and '03E3B------mmxrx'
439434
* };
440-
* const rowHlc = '03E3B------mmxrx';
441435
*
442-
* console.log(getRowHash(cellHashes, rowHlc));
443-
* // -> 703486916
436+
* console.log(getRowHash(cellHashes));
437+
* // -> 1810444343
444438
* ```
445439
* @category Hash
446440
* @since v6.2.0
@@ -493,9 +487,8 @@
493487

494488
/**
495489
* The getValuesHash function returns a hash for a Values object, based on each
496-
* value and the HLC of the Values.
490+
* Value Id and hash.
497491
* @param valueHashes An object containing each Value Id and its hash.
498-
* @param valuesHlc The HLC of the Values.
499492
* @returns A hash of the Values.
500493
* @example
501494
* This example gets the hash of a Values object.
@@ -505,10 +498,9 @@
505498
* const valueHashes = {
506499
* meaningOfLife: 312420374, // hash of 42 and '03E3B------mmxrx'
507500
* };
508-
* const valuesHlc = '03E3B------mmxrx';
509501
*
510-
* console.log(getValuesHash(valueHashes, valuesHlc));
511-
* // -> 3680840875
502+
* console.log(getValuesHash(valueHashes));
503+
* // -> 4229195646
512504
* ```
513505
* @category Hash
514506
* @since v6.2.0

src/@types/common/index.d.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,19 @@ export function getHash(string: string): Hash;
5959
export function addOrRemoveHash(hash1: Hash, hash2: Hash): Hash;
6060

6161
/// getTablesHash
62-
export function getTablesHash(
63-
tableHashes: {[tableId: Id]: Hash},
64-
tablesHlc: Hlc,
65-
): Hash;
62+
export function getTablesHash(tableHashes: {[tableId: Id]: Hash}): Hash;
6663

6764
/// getTableInTablesHash
6865
export function getTableInTablesHash(tableId: Id, tableHash: Hash): Hash;
6966

7067
/// getTableHash
71-
export function getTableHash(
72-
rowHashes: {[rowId: Id]: Hash},
73-
tableHlc: Hlc,
74-
): Hash;
68+
export function getTableHash(rowHashes: {[rowId: Id]: Hash}): Hash;
7569

7670
/// getRowInTableHash
7771
export function getRowInTableHash(rowId: Id, rowHash: Hash): Hash;
7872

7973
/// getRowHash
80-
export function getRowHash(cellHashes: {[cellId: Id]: Hash}, rowHlc: Hlc): Hash;
74+
export function getRowHash(cellHashes: {[cellId: Id]: Hash}): Hash;
8175

8276
/// getCellInRowHash
8377
export function getCellInRowHash(cellId: Id, cellHash: Hash): Hash;
@@ -86,10 +80,7 @@ export function getCellInRowHash(cellId: Id, cellHash: Hash): Hash;
8680
export function getCellHash(cell: CellOrUndefined, cellHlc: Hlc): Hash;
8781

8882
/// getValuesHash
89-
export function getValuesHash(
90-
valueHashes: {[valueId: Id]: Hash},
91-
valuesHlc: Hlc,
92-
): Hash;
83+
export function getValuesHash(valueHashes: {[valueId: Id]: Hash}): Hash;
9384

9485
/// getValueInValuesHash
9586
export function getValueInValuesHash(valueId: Id, valueHash: Hash): Hash;

src/@types/common/with-schemas/index.d.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -73,21 +73,15 @@ export function addOrRemoveHash(hash1: Hash, hash2: Hash): Hash;
7373
/// getTablesHash
7474
export function getTablesHash<
7575
Schema extends OptionalTablesSchema = NoTablesSchema,
76-
>(
77-
tableHashes: {[TableId in TableIdFromSchema<Schema>]: Hash},
78-
tablesHlc: Hlc,
79-
): Hash;
76+
>(tableHashes: {[TableId in TableIdFromSchema<Schema>]: Hash}): Hash;
8077

8178
/// getTableInTablesHash
8279
export function getTableInTablesHash<
8380
Schema extends OptionalTablesSchema = NoTablesSchema,
8481
>(tableId: TableIdFromSchema<Schema>, tableHash: Hash): Hash;
8582

8683
/// getTableHash
87-
export function getTableHash(
88-
rowHashes: {[rowId: Id]: Hash},
89-
tableHlc: Hlc,
90-
): Hash;
84+
export function getTableHash(rowHashes: {[rowId: Id]: Hash}): Hash;
9185

9286
/// getRowInTableHash
9387
export function getRowInTableHash(rowId: Id, rowHash: Hash): Hash;
@@ -96,10 +90,7 @@ export function getRowInTableHash(rowId: Id, rowHash: Hash): Hash;
9690
export function getRowHash<
9791
Schema extends OptionalTablesSchema = NoTablesSchema,
9892
TableId extends TableIdFromSchema<Schema> = Id,
99-
>(
100-
cellHashes: {[CellId in CellIdFromSchema<Schema, TableId>]?: Hash},
101-
rowHlc: Hlc,
102-
): Hash;
93+
>(cellHashes: {[CellId in CellIdFromSchema<Schema, TableId>]?: Hash}): Hash;
10394

10495
/// getCellInRowHash
10596
export function getCellInRowHash<
@@ -117,10 +108,7 @@ export function getCellHash<
117108
/// getValuesHash
118109
export function getValuesHash<
119110
Schema extends OptionalValuesSchema = NoValuesSchema,
120-
>(
121-
valueHashes: {[ValueId in ValueIdFromSchema<Schema>]?: Hash},
122-
valuesHlc: Hlc,
123-
): Hash;
111+
>(valueHashes: {[ValueId in ValueIdFromSchema<Schema>]?: Hash}): Hash;
124112

125113
/// getValueInValuesHash
126114
export function getValueInValuesHash<

src/common/hash.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {arrayForEach, arrayReduce} from './array.ts';
1717
import {jsonStringWithMap} from './json.ts';
1818
import {objEntries} from './obj.ts';
1919
import {GLOBAL} from './other.ts';
20-
import {EMPTY_STRING} from './strings.ts';
2120

2221
const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
2322

@@ -37,15 +36,18 @@ export const addOrRemoveHash: typeof addOrRemoveHashDecl = (
3736
hash2: Hash,
3837
): Hash => (hash1 ^ hash2) >>> 0;
3938

40-
export const getValuesHash: typeof getValuesHashDecl = (
41-
valueHashes: {[valueId: Id]: Hash},
42-
valuesHlc: Hlc,
43-
): Hash =>
39+
export const getValuesHash: typeof getValuesHashDecl = (valueHashes: {
40+
[valueId: Id]: Hash;
41+
}): Hash =>
4442
arrayReduce(
4543
objEntries(valueHashes),
4644
(valuesHash, [valueId, valueHash]) =>
47-
addOrRemoveHash(valuesHash, getValueInValuesHash(valueId, valueHash)),
48-
getHash(valuesHlc),
45+
addOrRemoveHash(
46+
valuesHash,
47+
getValueInValuesHash(valueId, valueHash) ^
48+
getValueInValuesHash(valueId, 0), // legacy v5; remove in v7
49+
),
50+
0, // legacy v5; valuesHlc in v7?
4951
);
5052

5153
export const getValueInValuesHash: typeof getValueHashInValuesDecl = (
@@ -56,6 +58,7 @@ export const getValueInValuesHash: typeof getValueHashInValuesDecl = (
5658
export const getValueHash: typeof getValueHashDecl = (
5759
value: ValueOrUndefined,
5860
valueHlc: Hlc,
61+
// legacy v5; jsonStringWithUndefined in v7
5962
): Hash => getHash(jsonStringWithMap(value ?? null) + ':' + valueHlc);
6063

6164
export const getCellHash: typeof getCellHashDecl = getValueHash;
@@ -68,7 +71,15 @@ export const getRowHash: typeof getRowHashDecl = getValuesHash;
6871
export const getRowInTableHash: typeof getRowHashInTableDecl =
6972
getValueInValuesHash;
7073

71-
export const getTableHash: typeof getTableHashDecl = getValuesHash;
74+
export const getTableHash: typeof getTableHashDecl = (rowHashes: {
75+
[rowId: Id]: Hash;
76+
}): Hash => // alias to getValuesHash in v7
77+
arrayReduce(
78+
objEntries(rowHashes),
79+
(valuesHash, [rowId, rowHash]) =>
80+
addOrRemoveHash(valuesHash, getValueInValuesHash(rowId, rowHash)),
81+
0, // legacy v5; rowHlc in v7?
82+
);
7283

7384
export const getTableInTablesHash: typeof getTableHashInTablesDecl =
7485
getValueInValuesHash;
Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,76 @@
1-
import {getHlcFunctions} from 'tinybase';
1+
import {
2+
addOrRemoveHash,
3+
getCellHash,
4+
getCellInRowHash,
5+
getHash,
6+
getHlcFunctions,
7+
getRowHash,
8+
getRowInTableHash,
9+
getTableHash,
10+
getTableInTablesHash,
11+
getTablesHash,
12+
getValueHash,
13+
getValueInValuesHash,
14+
getValuesHash,
15+
} from 'tinybase';
16+
import {getTimeFunctions} from '../../common/mergeable.ts';
17+
const [reset, getNow] = getTimeFunctions();
18+
19+
beforeEach(() => {
20+
reset();
21+
});
222

323
test('getHlcFunctions', () => {
4-
const result = getHlcFunctions();
5-
expect(result.length).toEqual(7);
24+
const [
25+
getNextHlc,
26+
seenHlc,
27+
encodeHlc,
28+
decodeHlc,
29+
getLastLogicalTime,
30+
getLastCounter,
31+
getClientId,
32+
] = getHlcFunctions('s1', getNow);
33+
expect(getNextHlc()).toEqual('Nn1JUF-----7JQY8');
34+
expect(getNextHlc()).toEqual('Nn1JUF----07JQY8');
35+
expect(getLastLogicalTime()).toEqual(1704067200000);
36+
37+
expect(encodeHlc(1704067201000, 2, 's2')).toEqual('Nn1JUUc---14JQFF');
38+
expect(decodeHlc('Nn1JUUc---14JQFF')).toEqual([1704067201000, 2, '4JQFF']);
39+
40+
seenHlc('Nn1JUUc---14JQFF');
41+
expect(getLastLogicalTime()).toEqual(1704067201000);
42+
expect(getLastCounter()).toEqual(2);
43+
expect(getClientId()).toEqual('7JQY8');
44+
});
45+
46+
describe('hash functions', () => {
47+
test('getHash', () => {
48+
expect(getHash('Hello, world!')).toEqual(3985698964);
49+
expect(getHash('Hello, world?')).toEqual(3549480870);
50+
});
51+
52+
test('addOrRemoveHash', () => {
53+
const hash1 = 123456789;
54+
const hash2 = 987654321;
55+
expect(addOrRemoveHash(hash1, hash2)).toEqual(1032168868);
56+
expect(addOrRemoveHash(1032168868, hash1)).toEqual(987654321);
57+
expect(addOrRemoveHash(1032168868, hash2)).toEqual(123456789);
58+
});
59+
60+
test('collection hash functions', () => {
61+
// Hashes must match 'Create, with uniqueId' test for MergeableStore
62+
// [{t1: {r1: {c1: 1}}}, {v1: 1}];
63+
expect(getCellHash(1, 'Nn1JUF-----7JQY8')).toEqual(1003668370);
64+
expect(getCellHash(undefined, 'Nn1JUF-----7JQY8')).toEqual(3052999146);
65+
expect(getCellInRowHash('c1', 1003668370)).toEqual(1869781647);
66+
expect(getRowHash({c1: 1003668370})).toEqual(550994372);
67+
expect(getRowInTableHash('r1', 550994372)).toEqual(1072852846);
68+
expect(getTableHash({r1: 550994372})).toEqual(1072852846);
69+
expect(getTableInTablesHash('t1', 1072852846)).toEqual(1771939739);
70+
expect(getTablesHash({t1: 1072852846})).toEqual(1771939739);
71+
72+
expect(getValueHash(1, 'Nn1JUF----07JQY8')).toEqual(1130939691);
73+
expect(getValueInValuesHash('v1', 1130939691)).toEqual(3884056078);
74+
expect(getValuesHash({v1: 1130939691})).toEqual(3877632732);
75+
});
676
});

test/unit/core/store/mergeable-store.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ test('Protocol basics', () => {
103103
test('Create, with uniqueId', () => {
104104
const store = createMergeableStore('s1', getNow);
105105
expect(store.getJson()).toEqual(JSON.stringify([{}, {}]));
106-
store.setCell('t1', 'r1', 'c1', 1);
106+
store.setCell('t1', 'r1', 'c1', 1).setValue('v1', 1);
107107
expect(store.getMergeableContent()).toEqual([
108108
[
109109
{
@@ -116,7 +116,7 @@ test('Create, with uniqueId', () => {
116116
'',
117117
1771939739,
118118
],
119-
[{}, '', 0],
119+
[{v1: [1, 'Nn1JUF----07JQY8', 1130939691]}, '', 3877632732],
120120
]);
121121
});
122122

0 commit comments

Comments
 (0)