diff --git a/src/matrix/storage/sortkey.js b/src/matrix/storage/sortkey.js index 58cd3e78..25e45ce6 100644 --- a/src/matrix/storage/sortkey.js +++ b/src/matrix/storage/sortkey.js @@ -1,29 +1,42 @@ 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 Int32Array(buffer, 2); + this._keys = new DataView(buffer); } else { - this._keys = new Int32Array(2); + 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[0]; + return this._keys.getUint32(0, false); } set gapKey(value) { - this._keys[0] = value; + return this._keys.setUint32(0, value, false); } get eventKey() { - return this._keys[1]; + return this._keys.getUint32(4, false); } set eventKey(value) { - this._keys[1] = value; + return this._keys.setUint32(4, value, false); } get buffer() { @@ -33,7 +46,7 @@ export default class SortKey { nextKeyWithGap() { const k = new SortKey(); k.gapKey = this.gapKey + 1; - k.eventKey = 0; + k.eventKey = MIN; return k; } @@ -60,15 +73,15 @@ export default class SortKey { static get maxKey() { const maxKey = new SortKey(); - maxKey.gapKey = MAX_INT32; - maxKey.eventKey = MAX_INT32; + maxKey.gapKey = MAX; + maxKey.eventKey = MAX; return maxKey; } static get minKey() { const minKey = new SortKey(); - minKey.gapKey = MIN_INT32; - minKey.eventKey = MIN_INT32; + minKey.gapKey = MIN; + minKey.eventKey = MIN; return minKey; } @@ -82,8 +95,8 @@ export function tests() { return { test_default_key(assert) { const k = new SortKey(); - assert.equal(k.gapKey, 0); - assert.equal(k.eventKey, 0); + assert.equal(k.gapKey, MID); + assert.equal(k.eventKey, MIN); }, test_inc(assert) { @@ -100,24 +113,61 @@ export function tests() { test_min_key(assert) { const minKey = SortKey.minKey; const k = new SortKey(); - assert(minKey.gapKey < k.gapKey); - assert(minKey.eventKey < k.eventKey); + 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); + assert(maxKey.gapKey >= k.gapKey); + assert(maxKey.eventKey >= k.eventKey); }, test_immutable(assert) { const a = new SortKey(); const gapKey = a.gapKey; - const eventKey = 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(b < a); + assert(a > b); + }, + + 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(b.buffer < a.buffer); + assert(a.buffer > b.buffer); + }, + + test_cmp_max_larger_than_min(assert) { + assert(SortKey.minKey < SortKey.maxKey); + }, + + 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); } }; }