make compare rely less on fragment index

also indenting
This commit is contained in:
Bruno Windels 2019-05-11 09:51:27 +02:00
parent 99c8816bf9
commit d6ae313bbd

View file

@ -11,80 +11,80 @@ const MID = MID_UINT32;
const MAX = MAX_UINT32; const MAX = MAX_UINT32;
export default class SortKey { export default class SortKey {
constructor(fragmentIdComparer, buffer) { constructor(fragmentIdComparer, buffer) {
if (buffer) { if (buffer) {
this._keys = new DataView(buffer); this._keys = new DataView(buffer);
} else { } else {
this._keys = new DataView(new ArrayBuffer(8)); this._keys = new DataView(new ArrayBuffer(8));
// start default key right at the middle fragment key, min event key // start default key right at the middle fragment key, min event key
// so we have the same amount of key address space either way // so we have the same amount of key address space either way
this.fragmentId = MID; this.fragmentId = MID;
this.eventIndex = MIN; this.eventIndex = MID;
} }
this._fragmentIdComparer = fragmentIdComparer; this._fragmentIdComparer = fragmentIdComparer;
} }
get fragmentId() { get fragmentId() {
return this._keys.getUint32(0, false); return this._keys.getUint32(0, false);
} }
set fragmentId(value) { set fragmentId(value) {
return this._keys.setUint32(0, value, false); return this._keys.setUint32(0, value, false);
} }
get eventIndex() { get eventIndex() {
return this._keys.getUint32(4, false); return this._keys.getUint32(4, false);
} }
set eventIndex(value) { set eventIndex(value) {
return this._keys.setUint32(4, value, false); return this._keys.setUint32(4, value, false);
} }
get buffer() { get buffer() {
return this._keys.buffer; return this._keys.buffer;
} }
nextFragmentKey() { nextFragmentKey() {
const k = new SortKey(this._fragmentIdComparer); const k = new SortKey(this._fragmentIdComparer);
k.fragmentId = this.fragmentId + 1; k.fragmentId = this.fragmentId + 1;
k.eventIndex = MIN; k.eventIndex = MIN;
return k; return k;
} }
nextKey() { nextKey() {
const k = new SortKey(this._fragmentIdComparer); const k = new SortKey(this._fragmentIdComparer);
k.fragmentId = this.fragmentId; k.fragmentId = this.fragmentId;
k.eventIndex = this.eventIndex + 1; k.eventIndex = this.eventIndex + 1;
return k; return k;
} }
previousKey() { previousKey() {
const k = new SortKey(this._fragmentIdComparer); const k = new SortKey(this._fragmentIdComparer);
k.fragmentId = this.fragmentId; k.fragmentId = this.fragmentId;
k.eventIndex = this.eventIndex - 1; k.eventIndex = this.eventIndex - 1;
return k; return k;
} }
clone() { clone() {
const k = new SortKey(); const k = new SortKey();
k.fragmentId = this.fragmentId; k.fragmentId = this.fragmentId;
k.eventIndex = this.eventIndex; k.eventIndex = this.eventIndex;
return k; return k;
} }
static get maxKey() { static get maxKey() {
const maxKey = new SortKey(null); const maxKey = new SortKey(null);
maxKey.fragmentId = MAX; maxKey.fragmentId = MAX;
maxKey.eventIndex = MAX; maxKey.eventIndex = MAX;
return maxKey; return maxKey;
} }
static get minKey() { static get minKey() {
const minKey = new SortKey(null); const minKey = new SortKey(null);
minKey.fragmentId = MIN; minKey.fragmentId = MIN;
minKey.eventIndex = MIN; minKey.eventIndex = MIN;
return minKey; return minKey;
} }
compare(otherKey) { compare(otherKey) {
const fragmentDiff = this.fragmentId - otherKey.fragmentId; const fragmentDiff = this.fragmentId - otherKey.fragmentId;
@ -92,10 +92,10 @@ export default class SortKey {
return this.eventIndex - otherKey.eventIndex; return this.eventIndex - otherKey.eventIndex;
} else { } else {
// minKey and maxKey might not have fragmentIdComparer, so short-circuit this first ... // minKey and maxKey might not have fragmentIdComparer, so short-circuit this first ...
if (this.fragmentId === MIN || otherKey.fragmentId === MAX) { if ((this.fragmentId === MIN && otherKey.fragmentId !== MIN) || (this.fragmentId !== MAX && otherKey.fragmentId === MAX)) {
return -1; return -1;
} }
if (this.fragmentId === MAX || otherKey.fragmentId === MIN) { if ((this.fragmentId === MAX && otherKey.fragmentId !== MAX) || (this.fragmentId !== MIN && otherKey.fragmentId === MIN)) {
return 1; return 1;
} }
// ... then delegate to fragmentIdComparer. // ... then delegate to fragmentIdComparer.
@ -104,94 +104,116 @@ export default class SortKey {
} }
} }
toString() { toString() {
return `[${this.fragmentId}/${this.eventIndex}]`; return `[${this.fragmentId}/${this.eventIndex}]`;
} }
} }
//#ifdef TESTS //#ifdef TESTS
export function tests() { export function tests() {
const fragmentIdComparer = {compare: (a, b) => a - b}; const fragmentIdComparer = {compare: (a, b) => a - b};
return { return {
test_default_key(assert) { test_no_fragment_index(assert) {
const k = new SortKey(fragmentIdComparer); const min = SortKey.minKey;
assert.equal(k.fragmentId, MID); const max = SortKey.maxKey;
assert.equal(k.eventIndex, MIN); const a = new SortKey();
}, a.eventIndex = 1;
a.fragmentId = 1;
test_inc(assert) { assert(min.compare(min) === 0);
const a = new SortKey(fragmentIdComparer); assert(max.compare(max) === 0);
const b = a.nextKey(); assert(a.compare(a) === 0);
assert.equal(a.fragmentId, b.fragmentId);
assert.equal(a.eventIndex + 1, b.eventIndex);
const c = b.previousKey();
assert.equal(b.fragmentId, c.fragmentId);
assert.equal(c.eventIndex + 1, b.eventIndex);
assert.equal(a.eventIndex, c.eventIndex);
},
test_min_key(assert) { assert(min.compare(max) < 0);
const minKey = SortKey.minKey; assert(max.compare(min) > 0);
const k = new SortKey(fragmentIdComparer);
assert(minKey.fragmentId <= k.fragmentId); assert(min.compare(a) < 0);
assert(minKey.eventIndex <= k.eventIndex); assert(a.compare(min) > 0);
assert(max.compare(a) > 0);
assert(a.compare(max) < 0);
},
test_default_key(assert) {
const k = new SortKey(fragmentIdComparer);
assert.equal(k.fragmentId, MID);
assert.equal(k.eventIndex, MID);
},
test_inc(assert) {
const a = new SortKey(fragmentIdComparer);
const b = a.nextKey();
assert.equal(a.fragmentId, b.fragmentId);
assert.equal(a.eventIndex + 1, b.eventIndex);
const c = b.previousKey();
assert.equal(b.fragmentId, c.fragmentId);
assert.equal(c.eventIndex + 1, b.eventIndex);
assert.equal(a.eventIndex, c.eventIndex);
},
test_min_key(assert) {
const minKey = SortKey.minKey;
const k = new SortKey(fragmentIdComparer);
assert(minKey.fragmentId <= k.fragmentId);
assert(minKey.eventIndex <= k.eventIndex);
assert(k.compare(minKey) > 0); assert(k.compare(minKey) > 0);
assert(minKey.compare(k) < 0); assert(minKey.compare(k) < 0);
}, },
test_max_key(assert) { test_max_key(assert) {
const maxKey = SortKey.maxKey; const maxKey = SortKey.maxKey;
const k = new SortKey(fragmentIdComparer); const k = new SortKey(fragmentIdComparer);
assert(maxKey.fragmentId >= k.fragmentId); assert(maxKey.fragmentId >= k.fragmentId);
assert(maxKey.eventIndex >= k.eventIndex); assert(maxKey.eventIndex >= k.eventIndex);
assert(k.compare(maxKey) < 0); assert(k.compare(maxKey) < 0);
assert(maxKey.compare(k) > 0); assert(maxKey.compare(k) > 0);
}, },
test_immutable(assert) { test_immutable(assert) {
const a = new SortKey(fragmentIdComparer); const a = new SortKey(fragmentIdComparer);
const fragmentId = a.fragmentId; const fragmentId = a.fragmentId;
const eventIndex = a.eventIndex; const eventIndex = a.eventIndex;
a.nextFragmentKey(); a.nextFragmentKey();
assert.equal(a.fragmentId, fragmentId); assert.equal(a.fragmentId, fragmentId);
assert.equal(a.eventIndex, eventIndex); assert.equal(a.eventIndex, eventIndex);
}, },
test_cmp_fragmentid_first(assert) { test_cmp_fragmentid_first(assert) {
const a = new SortKey(fragmentIdComparer); const a = new SortKey(fragmentIdComparer);
const b = new SortKey(fragmentIdComparer); const b = new SortKey(fragmentIdComparer);
a.fragmentId = 2; a.fragmentId = 2;
a.eventIndex = 1; a.eventIndex = 1;
b.fragmentId = 1; b.fragmentId = 1;
b.eventIndex = 100000; b.eventIndex = 100000;
assert(a.compare(b) > 0); assert(a.compare(b) > 0);
}, },
test_cmp_eventindex_second(assert) { test_cmp_eventindex_second(assert) {
const a = new SortKey(fragmentIdComparer); const a = new SortKey(fragmentIdComparer);
const b = new SortKey(fragmentIdComparer); const b = new SortKey(fragmentIdComparer);
a.fragmentId = 1; a.fragmentId = 1;
a.eventIndex = 100000; a.eventIndex = 100000;
b.fragmentId = 1; b.fragmentId = 1;
b.eventIndex = 2; b.eventIndex = 2;
assert(a.compare(b) > 0); assert(a.compare(b) > 0);
}, assert(b.compare(a) < 0);
},
test_cmp_max_larger_than_min(assert) { test_cmp_max_larger_than_min(assert) {
assert(SortKey.minKey.compare(SortKey.maxKey) < 0); assert(SortKey.minKey.compare(SortKey.maxKey) < 0);
}, },
test_cmp_fragmentid_first_large(assert) { test_cmp_fragmentid_first_large(assert) {
const a = new SortKey(fragmentIdComparer); const a = new SortKey(fragmentIdComparer);
const b = new SortKey(fragmentIdComparer); const b = new SortKey(fragmentIdComparer);
a.fragmentId = MAX; a.fragmentId = MAX;
a.eventIndex = MIN; a.eventIndex = MIN;
b.fragmentId = MIN; b.fragmentId = MIN;
b.eventIndex = MAX; b.eventIndex = MAX;
assert(b < a); assert(b < a);
assert(a > b); assert(a > b);
} }
}; };
} }
//#endif //#endif