manzt / zarrita.js

A JavaScript toolkit for working with chunked, compressed, n-dimensional arrays
https://zarrita.dev
MIT License
39 stars 5 forks source link

Version counters #109

Closed keller-mark closed 11 months ago

keller-mark commented 11 months ago

I'm not sure if this is the best way to implement this (and especially the typings), but the general idea is that the root of the store can (optionally) maintain two counters: v2_count and v3_count, which represent the number of times the store has successfully opened v2 vs. v3 metadata. Then, we can use these counters to determine which version to prioritize in the subsequent open() calls.

The goal is to avoid extra v3 zarr.json network requests and console errors when requesting v2 data, but without restricting by using open.v2 or open.v3. This is particularly important in higlass-zarr-datafetchers https://github.com/higlass/higlass-zarr-datafetchers/tree/keller-mark-patch-1 where many requests are being made on zoom/pan interactions.

Screenshot 2023-09-23 at 11 33 05 AM
manzt commented 11 months ago

I really like the idea, but in terms of implementation I'm not sure it's something that should live on the store. I think this might be a nice use case for a WeakMap, where we could keep context so long as the store lives in memory.

// open.ts
function create_version_counter() {
  let version_counts = new WeakMap<Readable, { v2: number, v3: number}>();
  function get_counts(store: Readable) {
    let counts = version_counts.get(store) ?? { v2: 0, v3: 0 };
    version_counts.set(store, counts);
    return counts;
  }
  return {
    increment(store: Readable, version: "v2" | "v3") {
      get_counts(store)[version] += 1;
    },
    version_max(store: Readable): "v2" | "v3" {
      let counts = get_counts(store);
      return counts.v3 > counts.v2 ? "v3" :  "v2";
    }
  }
}
let VERSION_COUNTER = create_version_counter();
keller-mark commented 11 months ago

Ah that is much nicer! I have re-implemented using your code snippet