Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save usrlocalben/cece7f167197f6876e6a09582e4fdb86 to your computer and use it in GitHub Desktop.
Save usrlocalben/cece7f167197f6876e6a09582e4fdb86 to your computer and use it in GitHub Desktop.
/*
* idea: subscribe to websocket log
* but get prior history via HTTP.
* merge history and maintain sequence.
* upsert fns close over a Vue ref.
*/
const ref = x => ({value: x}); // mock Vue
let items = ref([]);
const lower_bound = (arr, item, cmp) => {
/* c++ std::lower_bound equivalent,
* but w/ three-way comparison fn */
let begin = 0, end = arr.length;
while (begin < end) {
let mid = (begin + end) >>> 1;
if (cmp(arr[mid], item) < 0) {
begin = mid + 1; }
else {
end = mid; } }
return begin; };
const asc = (a, b) => {
/* three-way compare arr[0] */
if (a == undefined) return -1;
let a0 = a[0], b0 = b[0];
if (a0 < b0) return -1;
else if (a0 > b0) return 1;
return 0; };
const upsert_one = (it) => {
let arr = items.value;
if (asc(arr[arr.length-1], it) < 0) {
// most-likely: append to end
arr.push(it); }
else {
let idx = lower_bound(arr, it, asc);
arr.splice(idx, asc(arr[idx], it)===0 ? 1 : 0, it); }
items.value = arr; };
const upsert_base = (pack) => {
/* upsert a sequence of items into
* the map according to index */
let arr = items.value;
for (let i=0; i<pack.length; i++) {
let it = [i, pack[i]];
let idx = lower_bound(arr, it, asc);
arr.splice(idx, asc(arr[idx], it)===0 ? 1 : 0, it); }
items.value = arr; };
let foo = [2,3,1,5,6,6,6,6,0,5,1,3,1,5,6,0];
// connect websocket first
upsert_one([7, foo[7]]); // new event
upsert_one([8, foo[8]]); // "
upsert_one([9, foo[9]]); // "
// get history via HTTP
upsert_base(foo.slice(0, 10));
// websocket continues over time
for (let i=10; i<foo.length; i++) {
upsert_one([i, foo[i]]); }
// verify sequence
let good = true;
for (let i=0; i<foo.length; i++) {
good = good && items.value[i][1] == foo[i]; }
console.log(`length ${items.value.length === foo.length ? 'OK' : 'ERROR'}`);
console.log(`data ${good ? 'OK' : 'ERROR'}`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment