@genome-spy/core 0.71.0 → 0.72.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/index.es.js +3081 -2990
- package/dist/bundle/index.js +150 -143
- package/dist/bundle/parquetRead-BnAGCa4_.js +1663 -0
- package/dist/src/data/formats/parquet.d.ts +12 -0
- package/dist/src/data/formats/parquet.d.ts.map +1 -0
- package/dist/src/data/formats/parquet.js +29 -0
- package/dist/src/data/formats/parquetRead.d.ts +18 -0
- package/dist/src/data/formats/parquetRead.d.ts.map +1 -0
- package/dist/src/data/formats/parquetRead.js +326 -0
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +8 -3
- package/dist/src/encoder/encoder.d.ts +2 -2
- package/dist/src/fonts/bmFontManager.d.ts +1 -1
- package/dist/src/genome/genome.d.ts +1 -1
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +2 -0
- package/dist/src/gl/hashTable.d.ts +78 -0
- package/dist/src/gl/hashTable.d.ts.map +1 -0
- package/dist/src/gl/hashTable.js +164 -0
- package/dist/src/gl/includes/common.glsl.js +1 -1
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +12 -6
- package/dist/src/marks/mark.d.ts +1 -1
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +2 -3
- package/dist/src/utils/radixSort.d.ts.map +1 -1
- package/dist/src/utils/radixSort.js +26 -1
- package/dist/src/view/facetView.d.ts +1 -1
- package/dist/src/view/unitView.d.ts +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/** Sentinel key that marks an empty hash slot. */
|
|
2
|
+
export const HASH_EMPTY_KEY = 0xffff_ffff;
|
|
3
|
+
|
|
4
|
+
/** Default maximum load factor for table sizing. */
|
|
5
|
+
export const DEFAULT_MAX_LOAD_FACTOR = 0.6;
|
|
6
|
+
|
|
7
|
+
const MAX_U32 = 0xffff_ffff;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Build-time options for sizing the hash table.
|
|
11
|
+
*
|
|
12
|
+
* @typedef {object} HashTableBuildOptions
|
|
13
|
+
* @property {number} [capacity] Power-of-two table size override.
|
|
14
|
+
* @property {number} [maxLoadFactor] Maximum load factor before resizing.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Packed table payload ready for WebGL texture upload.
|
|
19
|
+
*
|
|
20
|
+
* @typedef {object} HashTableBuildResult
|
|
21
|
+
* @property {Uint32Array} table Hash table slots that contain keys.
|
|
22
|
+
* @property {number} capacity Table capacity (number of slots).
|
|
23
|
+
* @property {number} size Number of stored keys.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 32-bit integer hash for u32 keys. Keep in sync with GLSL hash32.
|
|
28
|
+
*
|
|
29
|
+
* @param {number} value
|
|
30
|
+
* @returns {number}
|
|
31
|
+
*/
|
|
32
|
+
export function hash32(value) {
|
|
33
|
+
let v = value >>> 0;
|
|
34
|
+
v ^= v >>> 16;
|
|
35
|
+
v = Math.imul(v, 0x7feb352d);
|
|
36
|
+
v ^= v >>> 15;
|
|
37
|
+
v = Math.imul(v, 0x846ca68b);
|
|
38
|
+
v ^= v >>> 16;
|
|
39
|
+
return v >>> 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Build a hash table for set membership checks.
|
|
44
|
+
*
|
|
45
|
+
* @param {Iterable<number>} keys
|
|
46
|
+
* @param {HashTableBuildOptions} [options]
|
|
47
|
+
* @returns {HashTableBuildResult}
|
|
48
|
+
*/
|
|
49
|
+
export function buildHashTableSet(keys, options = {}) {
|
|
50
|
+
const normalized = Array.from(keys, (key) => normalizeU32(key, "key"));
|
|
51
|
+
const size = normalized.length;
|
|
52
|
+
const maxLoadFactor = options.maxLoadFactor ?? DEFAULT_MAX_LOAD_FACTOR;
|
|
53
|
+
if (!(maxLoadFactor > 0 && maxLoadFactor < 1)) {
|
|
54
|
+
throw new Error("maxLoadFactor must be between 0 and 1.");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const capacity =
|
|
58
|
+
options.capacity ?? nextPow2(Math.ceil(size / maxLoadFactor));
|
|
59
|
+
if (!Number.isSafeInteger(capacity) || capacity < 1) {
|
|
60
|
+
throw new Error("capacity must be a positive power of two.");
|
|
61
|
+
}
|
|
62
|
+
if ((capacity & (capacity - 1)) !== 0) {
|
|
63
|
+
throw new Error("capacity must be a power of two.");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const table = new Uint32Array(capacity);
|
|
67
|
+
table.fill(HASH_EMPTY_KEY);
|
|
68
|
+
|
|
69
|
+
const mask = capacity - 1;
|
|
70
|
+
for (const key of normalized) {
|
|
71
|
+
if (key === HASH_EMPTY_KEY) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
"Hash table keys must not equal the empty sentinel (0xffffffff)."
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
let index = hash32(key) & mask;
|
|
77
|
+
let inserted = false;
|
|
78
|
+
|
|
79
|
+
for (let probe = 0; probe < capacity; probe += 1) {
|
|
80
|
+
const existingKey = table[index];
|
|
81
|
+
if (existingKey === HASH_EMPTY_KEY || existingKey === key) {
|
|
82
|
+
table[index] = key;
|
|
83
|
+
inserted = true;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
index = (index + 1) & mask;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!inserted) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
"Hash table insertion failed. Increase capacity or lower load factor."
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return { table, capacity, size };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Computes a 2D texture layout for a power-of-two hash table capacity.
|
|
101
|
+
*
|
|
102
|
+
* The returned dimensions satisfy `width * height === capacity`.
|
|
103
|
+
*
|
|
104
|
+
* @param {number} capacity
|
|
105
|
+
* @param {number} maxTextureSize
|
|
106
|
+
* @returns {{ width: number, height: number }}
|
|
107
|
+
*/
|
|
108
|
+
export function computeHashTextureDimensions(capacity, maxTextureSize) {
|
|
109
|
+
if (!Number.isSafeInteger(capacity) || capacity < 1) {
|
|
110
|
+
throw new Error("capacity must be a positive integer.");
|
|
111
|
+
}
|
|
112
|
+
if ((capacity & (capacity - 1)) !== 0) {
|
|
113
|
+
throw new Error("capacity must be a power of two.");
|
|
114
|
+
}
|
|
115
|
+
if (!Number.isSafeInteger(maxTextureSize) || maxTextureSize < 1) {
|
|
116
|
+
throw new Error("maxTextureSize must be a positive integer.");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const maxSlots = maxTextureSize * maxTextureSize;
|
|
120
|
+
if (capacity > maxSlots) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
"Selection hash table exceeds maximum texture capacity."
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const maxPow2Width = 1 << Math.floor(Math.log2(maxTextureSize));
|
|
127
|
+
const width = Math.min(capacity, maxPow2Width);
|
|
128
|
+
const height = capacity / width;
|
|
129
|
+
|
|
130
|
+
if (height > maxTextureSize) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
"Selection hash table dimensions exceed maximum texture size."
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { width, height };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @param {number} value
|
|
141
|
+
* @param {string} label
|
|
142
|
+
* @returns {number}
|
|
143
|
+
*/
|
|
144
|
+
function normalizeU32(value, label) {
|
|
145
|
+
if (!Number.isSafeInteger(value) || value < 0 || value > MAX_U32) {
|
|
146
|
+
throw new Error(label + " must be a non-negative u32.");
|
|
147
|
+
}
|
|
148
|
+
return value >>> 0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @param {number} value
|
|
153
|
+
* @returns {number}
|
|
154
|
+
*/
|
|
155
|
+
function nextPow2(value) {
|
|
156
|
+
let v = Math.max(1, value);
|
|
157
|
+
v -= 1;
|
|
158
|
+
v |= v >>> 1;
|
|
159
|
+
v |= v >>> 2;
|
|
160
|
+
v |= v >>> 4;
|
|
161
|
+
v |= v >>> 8;
|
|
162
|
+
v |= v >>> 16;
|
|
163
|
+
return v + 1;
|
|
164
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "#define PI 3.141593\nuniform View{mediump vec2 uViewOffset;mediump vec2 uViewScale;mediump vec2 uViewportSize;lowp float uDevicePixelRatio;lowp float uViewOpacity;bool uPickingEnabled;};/***Maps a coordinate on the unit scale to a normalized device coordinate.*(0,0)is at the bottom left corner.*/vec4 unitToNdc(vec2 coord){return vec4((coord*uViewScale+uViewOffset)*2.0-1.0,0.0,1.0);}vec4 unitToNdc(float x,float y){return unitToNdc(vec2(x,y));}vec4 pixelsToNdc(vec2 coord){return unitToNdc(coord/uViewportSize);}vec4 pixelsToNdc(float x,float y){return pixelsToNdc(vec2(x,y));}float linearstep(float edge0,float edge1,float x){return clamp((x-edge0)/(edge1-edge0),0.0,1.0);}bool
|
|
1
|
+
const shader = "#define PI 3.141593\nuniform View{mediump vec2 uViewOffset;mediump vec2 uViewScale;mediump vec2 uViewportSize;lowp float uDevicePixelRatio;lowp float uViewOpacity;bool uPickingEnabled;};/***Maps a coordinate on the unit scale to a normalized device coordinate.*(0,0)is at the bottom left corner.*/vec4 unitToNdc(vec2 coord){return vec4((coord*uViewScale+uViewOffset)*2.0-1.0,0.0,1.0);}vec4 unitToNdc(float x,float y){return unitToNdc(vec2(x,y));}vec4 pixelsToNdc(vec2 coord){return unitToNdc(coord/uViewportSize);}vec4 pixelsToNdc(float x,float y){return pixelsToNdc(vec2(x,y));}float linearstep(float edge0,float edge1,float x){return clamp((x-edge0)/(edge1-edge0),0.0,1.0);}const highp uint HASH_EMPTY_KEY=0xffffffffu;highp uint hash32(highp uint key){highp uint v=key;v ^=v>>16u;v*=0x7feb352du;v ^=v>>15u;v*=0x846ca68bu;v ^=v>>16u;return v;}bool isEmptyHashTexture(highp usampler2D s){ivec2 texSize=textureSize(s,0);return texSize.x==1&&texSize.y==1&&texelFetch(s,ivec2(0,0),0).r==HASH_EMPTY_KEY;}bool hashContainsTexture(highp usampler2D s,highp uint value){ivec2 texSize=textureSize(s,0);highp uint width=uint(texSize.x);highp uint size=width*uint(texSize.y);highp uint mask=size-1u;highp uint index=hash32(value)&mask;for(highp uint probe=0u;probe<size;probe+=1u){ivec2 coord=ivec2(int(index % width),int(index/width));highp uint entry=texelFetch(s,coord,0).r;if(entry==value){return true;}if(entry==HASH_EMPTY_KEY){return false;}index=(index+1u)&mask;}return false;}/***Calculates a gamma for antialiasing opacity based on the color.*/float getGammaForColor(vec3 rgb){return mix(1.25,0.75,smoothstep(0.0,1.0,dot(rgb,vec3(0.299,0.587,0.114))));}/***Specialized linearstep for doing antialiasing*/float distanceToRatio(float d){return clamp(d*uDevicePixelRatio+0.5,0.0,1.0);}vec4 distanceToColor(float d,vec4 fill,vec4 stroke,vec4 background,float halfStrokeWidth){if(halfStrokeWidth>0.0){float sd=abs(d)-halfStrokeWidth;return mix(stroke,d<=0.0 ? fill : background,distanceToRatio(sd));}else{return mix(background,fill,distanceToRatio(-d));}}";
|
|
2
2
|
export default shader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"AA+ZA;;;;GAIG;AACH,kCAJW,sBAAsB,gBACtB,WAAW,kBACX,WAAW;;;;;;EA8CrB;AAED;;;;;GAKG;AACH,0CALW,qBAAqB,WACrB,IAAI,CAAC,OAAO,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,OAC7C,MAAM,EAAE,GAAG,eAAe,YAC1B,YAAY,gBAYtB;AAED;;;;;;GAMG;AACH,qCALW,sBAAsB,mBACtB,OAAO,SAAS,EAAE,eAAe,KACjC,MAAM,KACN,MAAM,2BAWhB;AAED;;;;;GAKG;AACH,yCAJW,sBAAsB,mBACtB,OAAO,SAAS,EAAE,eAAe,SACjC,MAAM,UA4BhB;AApfD;IACI;;;;;;;OAOG;IACH,uBANW,WAAW,eACX,MAAM;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,2BAGrC,sBAAsB,EAsFhC;IAnFG,wBAA2B;IAC3B;;;MAKO;IAEP,uCAAuC;IACvC,cADW,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CACN;IAE7B,6EAA6E;IAC7E,eADW,OAAO,CAAC,OAAO,qBAAqB,EAAE,SAAS,EAAE,YAAY,CAAC,CACvC;IAElC;;OAEG;IACH,mBAFU,OAAO,CAAC,OAAO,4BAA4B,EAAE,mBAAmB,EAAE,YAAY,CAAC,CAEnD;IA8CtC,0BAAoB;IACpB,2BAAY;IAGZ,oDAAoD;IACpD,2BADW,OAAO,SAAS,EAAE,iBAAiB,EAAE,CAQ/C;IACD,sDAGC;IAML,uBAGC;IAFG;;;MAAmC;IAIvC;;;;;OAKG;IACH,oBAHW,MAAM,QACN,MAAM,GAAG,MAAM,EAAE,eA2B3B;IAED,iBAcC;IAED,iBAEC;IAED;;;;OAIG;IACH,oCAFW;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;;;MAS3C;IAED;;;OAGG;IACH;;;MAuBC;IAED;;;;;;;;;OASG;IACH,+BAHW,OAAO,8BAA8B,EAAE,OAAO,WAC9C,OAAO,QA2GjB;IAED;;OAEG;IACH,kCAFW,OAAO,4BAA4B,EAAE,mBAAmB,0BAiClE;CACJ"}
|
|
@@ -27,6 +27,10 @@ import {
|
|
|
27
27
|
isDiscreteChannel,
|
|
28
28
|
} from "../encoder/encoder.js";
|
|
29
29
|
import { isMultiPointSelection } from "../selection/selection.js";
|
|
30
|
+
import {
|
|
31
|
+
buildHashTableSet,
|
|
32
|
+
computeHashTextureDimensions,
|
|
33
|
+
} from "./hashTable.js";
|
|
30
34
|
|
|
31
35
|
export default class WebGLHelper {
|
|
32
36
|
/**
|
|
@@ -351,9 +355,11 @@ export default class WebGLHelper {
|
|
|
351
355
|
);
|
|
352
356
|
}
|
|
353
357
|
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
358
|
+
const { table, capacity } = buildHashTableSet(selection.data.keys());
|
|
359
|
+
const { width, height } = computeHashTextureDimensions(
|
|
360
|
+
capacity,
|
|
361
|
+
this.gl.getParameter(this.gl.MAX_TEXTURE_SIZE)
|
|
362
|
+
);
|
|
357
363
|
|
|
358
364
|
const existingTexture = this.selectionTextures.get(selection);
|
|
359
365
|
|
|
@@ -365,10 +371,10 @@ export default class WebGLHelper {
|
|
|
365
371
|
minMag: gl.NEAREST,
|
|
366
372
|
format: gl.RED_INTEGER,
|
|
367
373
|
internalFormat: gl.R32UI,
|
|
368
|
-
|
|
369
|
-
|
|
374
|
+
width,
|
|
375
|
+
height,
|
|
370
376
|
},
|
|
371
|
-
|
|
377
|
+
table,
|
|
372
378
|
update ? existingTexture : false
|
|
373
379
|
);
|
|
374
380
|
|
package/dist/src/marks/mark.d.ts
CHANGED
|
@@ -137,7 +137,7 @@ export default class Mark<P extends import("../spec/mark.js").MarkProps = import
|
|
|
137
137
|
*/
|
|
138
138
|
get encoding(): import("../spec/channel.js").Encoding;
|
|
139
139
|
getContext(): import("../types/viewContext.js").default;
|
|
140
|
-
getType(): "link" | "
|
|
140
|
+
getType(): "link" | "point" | "text" | "rect" | "rule";
|
|
141
141
|
initializeData(): void;
|
|
142
142
|
/**
|
|
143
143
|
* Initialize encoders that encode fields of the data (or constants) to
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"AA6DA,mCAAoC,sBAAsB,CAAC;AAC3D,mCAAoC,sBAAsB,CAAC;AAE3D,uCAAwC,oBAAoB,CAAC;AAE7D;;;;;;;;;;;;;GAaG;AAEH;;GAEG;AACH,0BAF0B,CAAC,SAAd,mCAAW;IAkBpB;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EA4G/C;IAzGG,oFAAwB;IAExB,8EAA8E;IAC9E,UADW,OAAO,CAAC,MAAM,uCAAU,OAAO,qBAAqB,EAAE,OAAO,CAAC,CAAC,CACjD;IAIzB;;;OAGG;IACH,sBAHU,OAAO,SAAS,EAAE,UAAU,GAAG;QAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE,CAG5C;IAE3B;;;;;;;OAOG;IACH,2BAHU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAGG;IAEhC;;;OAGG;IACH,uBAHU,OAAO,SAAS,EAAE,WAAW,CAGX;IAE5B;;;OAGG;IACH,2BAHU,OAAO,SAAS,EAAE,eAAe,CAGX;IAEhC;;;OAGG;IACH,2BAHU,OAAO,SAAS,EAAE,gBAAgB,CAGZ;IAEhC;;;;;OAKG;IACH,2BAHU,OAAO,SAAS,EAAE,gBAAgB,CAGZ;IAEhC;;;;;OAKG;IACH,uCAA+B;IAE/B;;;;;OAKG;IACH,4BAA6B;IAE7B,kFAAkF;IAClF,UADW,QAAQ,CAAC,GAAG,CAAC,CACM;IAG9B,qBAqBE;IAEF;;;;;;OAMG;IACH,qBAHU,CAAC,CAQV;IAGL;;;OAGG;IACH,0CAHW,OAAO,CAAC,CAAC,CAAC,QAQpB;IAED,sBAEC;IAED;;;OAGG;IACH,0BAFa,WAAW,CAIvB;IAED;;;;;OAKG;IACH,2BAHa,OAAO,oBAAoB,EAAE,OAAO,EAAE,CAMlD;IAED;;OAEG;IACH,wBAFa,sCAAS,CAarB;IAED;;OAEG;IACH,4DAcC;IAED;;;;;OAKG;IACH,oGAEC;IAED;;;;;;OAMG;IACH,oDAHW,CAAC,MAAM,CAAC,CAAC,EAAE,QAqCrB;IAED;;;;OAIG;IACH,sDAiDC;IAED,wDAEC;IAED,uDAEC;IAED,uBAEC;IAED;;;OAGG;IACH,2BAEC;IAED;;OAEG;IACH,oCAEC;IAED;;OAEG;IACH,2BAEC;IAED,sEAeC;IAED;;;;;;OAMG;IAEH,6CANW,MAAM,kBACN,MAAM,iBACN,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
|
package/dist/src/marks/mark.js
CHANGED
|
@@ -528,8 +528,7 @@ export default class Mark {
|
|
|
528
528
|
}
|
|
529
529
|
} else if (isMultiPointSelection(selection)) {
|
|
530
530
|
// We need a texture for each multi-selection parameter.
|
|
531
|
-
// The texture
|
|
532
|
-
// in ascending order, which allows for binary search.
|
|
531
|
+
// The texture stores an open-addressing hash table of selected uniqueIds.
|
|
533
532
|
if (!selectionParameterUniforms.has(param)) {
|
|
534
533
|
selectionParameterUniforms.set(param, "multi");
|
|
535
534
|
|
|
@@ -560,7 +559,7 @@ export default class Mark {
|
|
|
560
559
|
const texName = SELECTION_TEXTURE_PREFIX + param;
|
|
561
560
|
scaleCode.push(
|
|
562
561
|
`bool ${SELECTION_CHECKER_PREFIX}${param}(bool empty) {\n` +
|
|
563
|
-
` return
|
|
562
|
+
` return hashContainsTexture(${texName}, ${uniqueIdAttr}) || (empty && isEmptyHashTexture(${texName}));\n` +
|
|
564
563
|
`}`
|
|
565
564
|
);
|
|
566
565
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radixSort.d.ts","sourceRoot":"","sources":["../../../src/utils/radixSort.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"radixSort.d.ts","sourceRoot":"","sources":["../../../src/utils/radixSort.js"],"names":[],"mappings":"AAiBA;;GAEG;AACH,uCAFW,MAAM,EAAE,YA8DlB;AAeD;;GAEG;AACH,8CAFW,MAAM,EAAE,YA0DlB"}
|
|
@@ -3,12 +3,29 @@ const MAX_INTEGER_DIGIT = getDigits([MAX_INTEGER]);
|
|
|
3
3
|
|
|
4
4
|
// TODO: Optimize more! Some ideas: https://travisdowns.github.io/blog/2019/05/22/sorting.html
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @param {number[]} arr An array of unsigned integers
|
|
8
|
+
*/
|
|
9
|
+
function checkIfSorted(arr) {
|
|
10
|
+
for (let i = 1; i < arr.length; i++) {
|
|
11
|
+
if (arr[i] < arr[i - 1]) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
|
|
6
18
|
/**
|
|
7
19
|
* @param {number[]} arr An array of unsigned integers
|
|
8
20
|
*/
|
|
9
21
|
export default function radixSort(arr) {
|
|
10
22
|
const maxDigits = getDigits(arr);
|
|
11
23
|
|
|
24
|
+
// Early exit if already sorted
|
|
25
|
+
if (checkIfSorted(arr)) {
|
|
26
|
+
return arr;
|
|
27
|
+
}
|
|
28
|
+
|
|
12
29
|
let buffer = new Array(arr.length);
|
|
13
30
|
let bufferPtr = buffer;
|
|
14
31
|
const counts = new Array(16);
|
|
@@ -69,7 +86,9 @@ export default function radixSort(arr) {
|
|
|
69
86
|
function getDigits(arr) {
|
|
70
87
|
let max = 0;
|
|
71
88
|
for (let i = 0, n = arr.length; i < n; i++) {
|
|
72
|
-
|
|
89
|
+
if (arr[i] > max) {
|
|
90
|
+
max = arr[i];
|
|
91
|
+
}
|
|
73
92
|
}
|
|
74
93
|
return Math.floor(Math.log2(max) / 4) + 1;
|
|
75
94
|
}
|
|
@@ -80,6 +99,12 @@ function getDigits(arr) {
|
|
|
80
99
|
export function radixSortIntoLookupArray(arr) {
|
|
81
100
|
const maxDigits = getDigits(arr);
|
|
82
101
|
let indexes = Array.from({ length: arr.length }, (_, i) => i);
|
|
102
|
+
|
|
103
|
+
// Early exit if already sorted
|
|
104
|
+
if (checkIfSorted(arr)) {
|
|
105
|
+
return indexes;
|
|
106
|
+
}
|
|
107
|
+
|
|
83
108
|
let buffer = new Array(arr.length);
|
|
84
109
|
const counts = new Array(16);
|
|
85
110
|
|
|
@@ -48,7 +48,7 @@ export default class FacetView extends ContainerView<import("../spec/view.js").C
|
|
|
48
48
|
getAccessor(channel: "row" | "column"): any;
|
|
49
49
|
updateFacets(): void;
|
|
50
50
|
updateLabels(): void;
|
|
51
|
-
getFacetGroups():
|
|
51
|
+
getFacetGroups(): number[] | boolean[] | string[];
|
|
52
52
|
/**
|
|
53
53
|
* @param {import("./renderingContext/viewRenderingContext.js").default} context
|
|
54
54
|
* @param {import("./layout/rectangle.js").default} coords
|
|
@@ -21,7 +21,7 @@ export default class UnitView<TSpec extends import("../spec/view.js").UnitSpec =
|
|
|
21
21
|
constructor(spec: TSpec, context: import("../types/viewContext.js").default, layoutParent: import("./containerView.js").default, dataParent: import("./view.js").default, name: string, options?: import("./view.js").ViewOptions);
|
|
22
22
|
/** @type {import("../marks/mark.js").default} */
|
|
23
23
|
mark: import("../marks/mark.js").default;
|
|
24
|
-
getMarkType(): "link" | "
|
|
24
|
+
getMarkType(): "link" | "point" | "text" | "rect" | "rule";
|
|
25
25
|
/**
|
|
26
26
|
* Pulls scales and axes up in the view hierarcy according to the resolution rules, using dataParents.
|
|
27
27
|
* TODO: legends
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"contributors": [],
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.72.0",
|
|
11
11
|
"jsdelivr": "dist/bundle/index.js",
|
|
12
12
|
"unpkg": "dist/bundle/index.js",
|
|
13
13
|
"browser": "dist/bundle/index.js",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"flatqueue": "^3.0.0",
|
|
57
57
|
"generic-filehandle2": "^2.0.14",
|
|
58
58
|
"gff-nostream": "^2.0.0",
|
|
59
|
+
"hyparquet": "^1.25.0",
|
|
59
60
|
"internmap": "^2.0.3",
|
|
60
61
|
"lit": "^3.3.0",
|
|
61
62
|
"twgl.js": "^4.19.1",
|
|
@@ -67,5 +68,5 @@
|
|
|
67
68
|
"devDependencies": {
|
|
68
69
|
"@types/long": "^4.0.1"
|
|
69
70
|
},
|
|
70
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "504e1d0f7c45c2324bb6b0ff7b9230829d60518e"
|
|
71
72
|
}
|