mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2024-12-23 11:35:04 +01:00
adjust SortKey to have fragmentKey instead of gapKey
with FragmentIndex to compare fragment keys
This commit is contained in:
parent
8670ab6331
commit
d90411a6dd
@ -1,5 +1,10 @@
|
|||||||
- DONE: write FragmentIndex
|
- DONE: write FragmentIndex
|
||||||
- adapt SortKey
|
- adapt SortKey ... naming! :
|
||||||
|
- FragmentIndex (index as in db index)
|
||||||
|
- compare(fragmentKeyA, fragmentKeyB)
|
||||||
|
- SortKey
|
||||||
|
- FragmentKey
|
||||||
|
- EventKey (we don't use id here because we already have event_id in the event)
|
||||||
- write fragmentStore
|
- write fragmentStore
|
||||||
- adapt timelineStore
|
- adapt timelineStore
|
||||||
- adapt persister
|
- adapt persister
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import SortKey from "../storage/sortkey.js";
|
import SortKey from "./timeline/SortKey.js";
|
||||||
import FragmentIndex from "./timeline/FragmentIndex.js";
|
import FragmentIndex from "./timeline/FragmentIndex.js";
|
||||||
|
|
||||||
function gapEntriesAreEqual(a, b) {
|
function gapEntriesAreEqual(a, b) {
|
||||||
@ -31,6 +31,7 @@ export default class RoomPersister {
|
|||||||
constructor({roomId, storage}) {
|
constructor({roomId, storage}) {
|
||||||
this._roomId = roomId;
|
this._roomId = roomId;
|
||||||
this._storage = storage;
|
this._storage = storage;
|
||||||
|
// TODO: load fragmentIndex?
|
||||||
this._lastSortKey = new SortKey();
|
this._lastSortKey = new SortKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +39,7 @@ export default class RoomPersister {
|
|||||||
//fetch key here instead?
|
//fetch key here instead?
|
||||||
const [lastEvent] = await txn.roomTimeline.lastEvents(this._roomId, 1);
|
const [lastEvent] = await txn.roomTimeline.lastEvents(this._roomId, 1);
|
||||||
if (lastEvent) {
|
if (lastEvent) {
|
||||||
|
// TODO: load fragmentIndex?
|
||||||
this._lastSortKey = new SortKey(lastEvent.sortKey);
|
this._lastSortKey = new SortKey(lastEvent.sortKey);
|
||||||
console.log("room persister load", this._roomId, this._lastSortKey.toString());
|
console.log("room persister load", this._roomId, this._lastSortKey.toString());
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
class Fragment {
|
|
||||||
constructor(previousId, nextId) {
|
|
||||||
this.previousId = previousId;
|
|
||||||
this.nextId = nextId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
lookups will be far more frequent than changing fragment order,
|
lookups will be far more frequent than changing fragment order,
|
||||||
so data structure should be optimized for fast lookup
|
so data structure should be optimized for fast lookup
|
||||||
@ -93,7 +86,7 @@ class Island {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
compareIds(idA, idB) {
|
compare(idA, idB) {
|
||||||
const sortIndexA = this._idToSortIndex.get(idA);
|
const sortIndexA = this._idToSortIndex.get(idA);
|
||||||
if (sortIndexA === undefined) {
|
if (sortIndexA === undefined) {
|
||||||
throw new Error(`first id ${idA} isn't part of this island`);
|
throw new Error(`first id ${idA} isn't part of this island`);
|
||||||
@ -126,7 +119,7 @@ export default class FragmentIndex {
|
|||||||
return island;
|
return island;
|
||||||
}
|
}
|
||||||
|
|
||||||
compareIds(idA, idB) {
|
compare(idA, idB) {
|
||||||
if (idA === idB) {
|
if (idA === idB) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -135,7 +128,7 @@ export default class FragmentIndex {
|
|||||||
if (islandA !== islandB) {
|
if (islandA !== islandB) {
|
||||||
throw new Error(`${idA} and ${idB} are on different islands, can't tell order`);
|
throw new Error(`${idA} and ${idB} are on different islands, can't tell order`);
|
||||||
}
|
}
|
||||||
return islandA.compareIds(idA, idB);
|
return islandA.compare(idA, idB);
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuild(fragments) {
|
rebuild(fragments) {
|
||||||
@ -166,6 +159,7 @@ export default class FragmentIndex {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#ifdef TESTS
|
||||||
export function tests() {
|
export function tests() {
|
||||||
return {
|
return {
|
||||||
test_1_island_3_fragments(assert) {
|
test_1_island_3_fragments(assert) {
|
||||||
@ -174,24 +168,24 @@ export function tests() {
|
|||||||
{id: 1, nextId: 2},
|
{id: 1, nextId: 2},
|
||||||
{id: 2, nextId: 3, previousId: 1},
|
{id: 2, nextId: 3, previousId: 1},
|
||||||
]);
|
]);
|
||||||
assert(index.compareIds(1, 2) < 0);
|
assert(index.compare(1, 2) < 0);
|
||||||
assert(index.compareIds(2, 1) > 0);
|
assert(index.compare(2, 1) > 0);
|
||||||
|
|
||||||
assert(index.compareIds(1, 3) < 0);
|
assert(index.compare(1, 3) < 0);
|
||||||
assert(index.compareIds(3, 1) > 0);
|
assert(index.compare(3, 1) > 0);
|
||||||
|
|
||||||
assert(index.compareIds(2, 3) < 0);
|
assert(index.compare(2, 3) < 0);
|
||||||
assert(index.compareIds(3, 2) > 0);
|
assert(index.compare(3, 2) > 0);
|
||||||
|
|
||||||
assert.equal(index.compareIds(1, 1), 0);
|
assert.equal(index.compare(1, 1), 0);
|
||||||
},
|
},
|
||||||
test_2_island_dont_compare(assert) {
|
test_2_island_dont_compare(assert) {
|
||||||
const index = new FragmentIndex([
|
const index = new FragmentIndex([
|
||||||
{id: 1},
|
{id: 1},
|
||||||
{id: 2},
|
{id: 2},
|
||||||
]);
|
]);
|
||||||
assert.throws(() => index.compareIds(1, 2));
|
assert.throws(() => index.compare(1, 2));
|
||||||
assert.throws(() => index.compareIds(2, 1));
|
assert.throws(() => index.compare(2, 1));
|
||||||
},
|
},
|
||||||
test_2_island_compare_internally(assert) {
|
test_2_island_compare_internally(assert) {
|
||||||
const index = new FragmentIndex([
|
const index = new FragmentIndex([
|
||||||
@ -202,16 +196,16 @@ export function tests() {
|
|||||||
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert(index.compareIds(1, 2) < 0);
|
assert(index.compare(1, 2) < 0);
|
||||||
assert(index.compareIds(11, 12) < 0);
|
assert(index.compare(11, 12) < 0);
|
||||||
|
|
||||||
assert.throws(() => index.compareIds(1, 11));
|
assert.throws(() => index.compare(1, 11));
|
||||||
assert.throws(() => index.compareIds(12, 2));
|
assert.throws(() => index.compare(12, 2));
|
||||||
},
|
},
|
||||||
test_unknown_id(assert) {
|
test_unknown_id(assert) {
|
||||||
const index = new FragmentIndex([{id: 1}]);
|
const index = new FragmentIndex([{id: 1}]);
|
||||||
assert.throws(() => index.compareIds(1, 2));
|
assert.throws(() => index.compare(1, 2));
|
||||||
assert.throws(() => index.compareIds(2, 1));
|
assert.throws(() => index.compare(2, 1));
|
||||||
},
|
},
|
||||||
test_rebuild_flushes_old_state(assert) {
|
test_rebuild_flushes_old_state(assert) {
|
||||||
const index = new FragmentIndex([
|
const index = new FragmentIndex([
|
||||||
@ -223,8 +217,9 @@ export function tests() {
|
|||||||
{id: 12, previousId: 11},
|
{id: 12, previousId: 11},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert.throws(() => index.compareIds(1, 2));
|
assert.throws(() => index.compare(1, 2));
|
||||||
assert(index.compareIds(11, 12) < 0);
|
assert(index.compare(11, 12) < 0);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//#endif
|
||||||
|
197
src/matrix/room/timeline/SortKey.js
Normal file
197
src/matrix/room/timeline/SortKey.js
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
const MIN_INT32 = -2147483648;
|
||||||
|
const MID_INT32 = 0;
|
||||||
|
const MAX_INT32 = 2147483647;
|
||||||
|
|
||||||
|
const MIN_UINT32 = 0;
|
||||||
|
const MID_UINT32 = 2147483647;
|
||||||
|
const MAX_UINT32 = 4294967295;
|
||||||
|
|
||||||
|
const MIN = MIN_UINT32;
|
||||||
|
const MID = MID_UINT32;
|
||||||
|
const MAX = MAX_UINT32;
|
||||||
|
|
||||||
|
export default class SortKey {
|
||||||
|
constructor(fragmentIndex, buffer) {
|
||||||
|
if (buffer) {
|
||||||
|
this._keys = new DataView(buffer);
|
||||||
|
} else {
|
||||||
|
this._keys = new DataView(new ArrayBuffer(8));
|
||||||
|
// start default key right at the middle fragment key, min event key
|
||||||
|
// so we have the same amount of key address space either way
|
||||||
|
this.fragmentKey = MID;
|
||||||
|
this.eventKey = MIN;
|
||||||
|
}
|
||||||
|
this._fragmentIndex = fragmentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
get fragmentKey() {
|
||||||
|
return this._keys.getUint32(0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
set fragmentKey(value) {
|
||||||
|
return this._keys.setUint32(0, value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
get eventKey() {
|
||||||
|
return this._keys.getUint32(4, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
set eventKey(value) {
|
||||||
|
return this._keys.setUint32(4, value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
get buffer() {
|
||||||
|
return this._keys.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextFragmentKey() {
|
||||||
|
const k = new SortKey(this._fragmentIndex);
|
||||||
|
k.fragmentKey = this.fragmentKey + 1;
|
||||||
|
k.eventKey = MIN;
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextKey() {
|
||||||
|
const k = new SortKey(this._fragmentIndex);
|
||||||
|
k.fragmentKey = this.fragmentKey;
|
||||||
|
k.eventKey = this.eventKey + 1;
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
previousKey() {
|
||||||
|
const k = new SortKey(this._fragmentIndex);
|
||||||
|
k.fragmentKey = this.fragmentKey;
|
||||||
|
k.eventKey = this.eventKey - 1;
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
clone() {
|
||||||
|
const k = new SortKey();
|
||||||
|
k.fragmentKey = this.fragmentKey;
|
||||||
|
k.eventKey = this.eventKey;
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get maxKey() {
|
||||||
|
const maxKey = new SortKey(null);
|
||||||
|
maxKey.fragmentKey = MAX;
|
||||||
|
maxKey.eventKey = MAX;
|
||||||
|
return maxKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get minKey() {
|
||||||
|
const minKey = new SortKey(null);
|
||||||
|
minKey.fragmentKey = MIN;
|
||||||
|
minKey.eventKey = MIN;
|
||||||
|
return minKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
compare(otherKey) {
|
||||||
|
const fragmentDiff = this.fragmentKey - otherKey.fragmentKey;
|
||||||
|
if (fragmentDiff === 0) {
|
||||||
|
return this.eventKey - otherKey.eventKey;
|
||||||
|
} else {
|
||||||
|
// minKey and maxKey might not have fragmentIndex, so short-circuit this first ...
|
||||||
|
if (this.fragmentKey === MIN || otherKey.fragmentKey === MAX) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (this.fragmentKey === MAX || otherKey.fragmentKey === MIN) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// ... then delegate to fragmentIndex.
|
||||||
|
// This might throw if the relation of two fragments is unknown.
|
||||||
|
return this._fragmentIndex.compare(this.fragmentKey, otherKey.fragmentKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return `[${this.fragmentKey}/${this.eventKey}]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#ifdef TESTS
|
||||||
|
export function tests() {
|
||||||
|
const fragmentIndex = {compare: (a, b) => a - b};
|
||||||
|
|
||||||
|
return {
|
||||||
|
test_default_key(assert) {
|
||||||
|
const k = new SortKey(fragmentIndex);
|
||||||
|
assert.equal(k.fragmentKey, MID);
|
||||||
|
assert.equal(k.eventKey, MIN);
|
||||||
|
},
|
||||||
|
|
||||||
|
test_inc(assert) {
|
||||||
|
const a = new SortKey(fragmentIndex);
|
||||||
|
const b = a.nextKey();
|
||||||
|
assert.equal(a.fragmentKey, b.fragmentKey);
|
||||||
|
assert.equal(a.eventKey + 1, b.eventKey);
|
||||||
|
const c = b.previousKey();
|
||||||
|
assert.equal(b.fragmentKey, c.fragmentKey);
|
||||||
|
assert.equal(c.eventKey + 1, b.eventKey);
|
||||||
|
assert.equal(a.eventKey, c.eventKey);
|
||||||
|
},
|
||||||
|
|
||||||
|
test_min_key(assert) {
|
||||||
|
const minKey = SortKey.minKey;
|
||||||
|
const k = new SortKey(fragmentIndex);
|
||||||
|
assert(minKey.fragmentKey <= k.fragmentKey);
|
||||||
|
assert(minKey.eventKey <= k.eventKey);
|
||||||
|
assert(k.compare(minKey) > 0);
|
||||||
|
assert(minKey.compare(k) < 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
test_max_key(assert) {
|
||||||
|
const maxKey = SortKey.maxKey;
|
||||||
|
const k = new SortKey(fragmentIndex);
|
||||||
|
assert(maxKey.fragmentKey >= k.fragmentKey);
|
||||||
|
assert(maxKey.eventKey >= k.eventKey);
|
||||||
|
assert(k.compare(maxKey) < 0);
|
||||||
|
assert(maxKey.compare(k) > 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
test_immutable(assert) {
|
||||||
|
const a = new SortKey(fragmentIndex);
|
||||||
|
const fragmentKey = a.fragmentKey;
|
||||||
|
const eventKey = a.eventKey;
|
||||||
|
a.nextFragmentKey();
|
||||||
|
assert.equal(a.fragmentKey, fragmentKey);
|
||||||
|
assert.equal(a.eventKey, eventKey);
|
||||||
|
},
|
||||||
|
|
||||||
|
test_cmp_fragmentkey_first(assert) {
|
||||||
|
const a = new SortKey(fragmentIndex);
|
||||||
|
const b = new SortKey(fragmentIndex);
|
||||||
|
a.fragmentKey = 2;
|
||||||
|
a.eventKey = 1;
|
||||||
|
b.fragmentKey = 1;
|
||||||
|
b.eventKey = 100000;
|
||||||
|
assert(a.compare(b) > 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
test_cmp_eventkey_second(assert) {
|
||||||
|
const a = new SortKey(fragmentIndex);
|
||||||
|
const b = new SortKey(fragmentIndex);
|
||||||
|
a.fragmentKey = 1;
|
||||||
|
a.eventKey = 100000;
|
||||||
|
b.fragmentKey = 1;
|
||||||
|
b.eventKey = 2;
|
||||||
|
assert(a.compare(b) > 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
test_cmp_max_larger_than_min(assert) {
|
||||||
|
assert(SortKey.minKey.compare(SortKey.maxKey) < 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
test_cmp_fragmentkey_first_large(assert) {
|
||||||
|
const a = new SortKey(fragmentIndex);
|
||||||
|
const b = new SortKey(fragmentIndex);
|
||||||
|
a.fragmentKey = MAX;
|
||||||
|
a.eventKey = MIN;
|
||||||
|
b.fragmentKey = MIN;
|
||||||
|
b.eventKey = MAX;
|
||||||
|
assert(b < a);
|
||||||
|
assert(a > b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//#endif
|
@ -1,4 +1,4 @@
|
|||||||
import SortKey from "../../sortkey.js";
|
import SortKey from "../../../room/timeline/SortKey.js";
|
||||||
|
|
||||||
class Range {
|
class Range {
|
||||||
constructor(only, lower, upper, lowerOpen, upperOpen) {
|
constructor(only, lower, upper, lowerOpen, upperOpen) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import SortKey from "../sortkey.js";
|
import SortKey from "../../room/timeline/SortKey.js";
|
||||||
import sortedIndex from "../../../utils/sortedIndex.js";
|
import sortedIndex from "../../../utils/sortedIndex.js";
|
||||||
import Store from "./Store";
|
import Store from "./Store.js";
|
||||||
|
|
||||||
function compareKeys(key, entry) {
|
function compareKeys(key, entry) {
|
||||||
if (key.roomId === entry.roomId) {
|
if (key.roomId === entry.roomId) {
|
||||||
|
@ -1,181 +0,0 @@
|
|||||||
const MIN_INT32 = -2147483648;
|
|
||||||
const MID_INT32 = 0;
|
|
||||||
const MAX_INT32 = 2147483647;
|
|
||||||
|
|
||||||
const MIN_UINT32 = 0;
|
|
||||||
const MID_UINT32 = 2147483647;
|
|
||||||
const MAX_UINT32 = 4294967295;
|
|
||||||
|
|
||||||
const MIN = MIN_UINT32;
|
|
||||||
const MID = MID_UINT32;
|
|
||||||
const MAX = MAX_UINT32;
|
|
||||||
|
|
||||||
export default class SortKey {
|
|
||||||
constructor(buffer) {
|
|
||||||
if (buffer) {
|
|
||||||
this._keys = new DataView(buffer);
|
|
||||||
} else {
|
|
||||||
this._keys = new DataView(new ArrayBuffer(8));
|
|
||||||
// start default key right at the middle gap key, min event key
|
|
||||||
// so we have the same amount of key address space either way
|
|
||||||
this.gapKey = MID;
|
|
||||||
this.eventKey = MIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get gapKey() {
|
|
||||||
return this._keys.getUint32(0, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
set gapKey(value) {
|
|
||||||
return this._keys.setUint32(0, value, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
get eventKey() {
|
|
||||||
return this._keys.getUint32(4, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
set eventKey(value) {
|
|
||||||
return this._keys.setUint32(4, value, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
get buffer() {
|
|
||||||
return this._keys.buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
nextKeyWithGap() {
|
|
||||||
const k = new SortKey();
|
|
||||||
k.gapKey = this.gapKey + 1;
|
|
||||||
k.eventKey = MIN;
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
|
|
||||||
nextKey() {
|
|
||||||
const k = new SortKey();
|
|
||||||
k.gapKey = this.gapKey;
|
|
||||||
k.eventKey = this.eventKey + 1;
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
|
|
||||||
previousKey() {
|
|
||||||
const k = new SortKey();
|
|
||||||
k.gapKey = this.gapKey;
|
|
||||||
k.eventKey = this.eventKey - 1;
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
|
|
||||||
clone() {
|
|
||||||
const k = new SortKey();
|
|
||||||
k.gapKey = this.gapKey;
|
|
||||||
k.eventKey = this.eventKey;
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get maxKey() {
|
|
||||||
const maxKey = new SortKey();
|
|
||||||
maxKey.gapKey = MAX;
|
|
||||||
maxKey.eventKey = MAX;
|
|
||||||
return maxKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get minKey() {
|
|
||||||
const minKey = new SortKey();
|
|
||||||
minKey.gapKey = MIN;
|
|
||||||
minKey.eventKey = MIN;
|
|
||||||
return minKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
compare(otherKey) {
|
|
||||||
const gapDiff = this.gapKey - otherKey.gapKey;
|
|
||||||
if (gapDiff === 0) {
|
|
||||||
return this.eventKey - otherKey.eventKey;
|
|
||||||
} else {
|
|
||||||
return gapDiff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toString() {
|
|
||||||
return `[${this.gapKey}/${this.eventKey}]`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//#ifdef TESTS
|
|
||||||
export function tests() {
|
|
||||||
return {
|
|
||||||
test_default_key(assert) {
|
|
||||||
const k = new SortKey();
|
|
||||||
assert.equal(k.gapKey, MID);
|
|
||||||
assert.equal(k.eventKey, MIN);
|
|
||||||
},
|
|
||||||
|
|
||||||
test_inc(assert) {
|
|
||||||
const a = new SortKey();
|
|
||||||
const b = a.nextKey();
|
|
||||||
assert.equal(a.gapKey, b.gapKey);
|
|
||||||
assert.equal(a.eventKey + 1, b.eventKey);
|
|
||||||
const c = b.previousKey();
|
|
||||||
assert.equal(b.gapKey, c.gapKey);
|
|
||||||
assert.equal(c.eventKey + 1, b.eventKey);
|
|
||||||
assert.equal(a.eventKey, c.eventKey);
|
|
||||||
},
|
|
||||||
|
|
||||||
test_min_key(assert) {
|
|
||||||
const minKey = SortKey.minKey;
|
|
||||||
const k = new SortKey();
|
|
||||||
assert(minKey.gapKey <= k.gapKey);
|
|
||||||
assert(minKey.eventKey <= k.eventKey);
|
|
||||||
},
|
|
||||||
|
|
||||||
test_max_key(assert) {
|
|
||||||
const maxKey = SortKey.maxKey;
|
|
||||||
const k = new SortKey();
|
|
||||||
assert(maxKey.gapKey >= k.gapKey);
|
|
||||||
assert(maxKey.eventKey >= k.eventKey);
|
|
||||||
},
|
|
||||||
|
|
||||||
test_immutable(assert) {
|
|
||||||
const a = new SortKey();
|
|
||||||
const gapKey = a.gapKey;
|
|
||||||
const eventKey = a.eventKey;
|
|
||||||
a.nextKeyWithGap();
|
|
||||||
assert.equal(a.gapKey, gapKey);
|
|
||||||
assert.equal(a.eventKey, eventKey);
|
|
||||||
},
|
|
||||||
|
|
||||||
test_cmp_gapkey_first(assert) {
|
|
||||||
const a = new SortKey();
|
|
||||||
const b = new SortKey();
|
|
||||||
a.gapKey = 2;
|
|
||||||
a.eventKey = 1;
|
|
||||||
b.gapKey = 1;
|
|
||||||
b.eventKey = 100000;
|
|
||||||
assert(a.compare(b) > 0);
|
|
||||||
},
|
|
||||||
|
|
||||||
test_cmp_eventkey_second(assert) {
|
|
||||||
const a = new SortKey();
|
|
||||||
const b = new SortKey();
|
|
||||||
a.gapKey = 1;
|
|
||||||
a.eventKey = 100000;
|
|
||||||
b.gapKey = 1;
|
|
||||||
b.eventKey = 2;
|
|
||||||
assert(a.compare(b) > 0);
|
|
||||||
},
|
|
||||||
|
|
||||||
test_cmp_max_larger_than_min(assert) {
|
|
||||||
assert(SortKey.minKey.compare(SortKey.maxKey) < 0);
|
|
||||||
},
|
|
||||||
|
|
||||||
test_cmp_gapkey_first_large(assert) {
|
|
||||||
const a = new SortKey();
|
|
||||||
const b = new SortKey();
|
|
||||||
a.gapKey = MAX;
|
|
||||||
a.eventKey = MIN;
|
|
||||||
b.gapKey = MIN;
|
|
||||||
b.eventKey = MAX;
|
|
||||||
assert(b < a);
|
|
||||||
assert(a > b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//#endif
|
|
Loading…
Reference in New Issue
Block a user