@delali/narsil 0.3.1-next.69 → 0.3.1-next.71
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/{capabilities-B1wz2Zl0.d.ts → capabilities-Dt-7B4Wz.d.ts} +2 -2
- package/dist/{chunk-DD5X23E6.mjs → chunk-2STVUTNA.mjs} +1 -1
- package/dist/chunk-3JGWULDF.mjs +256 -0
- package/dist/{chunk-6TGZG2TV.mjs → chunk-653BNMAF.mjs} +190 -58
- package/dist/{chunk-YA52AC2V.mjs → chunk-FVLQ63B7.mjs} +203 -9
- package/dist/{chunk-5JLSTECC.mjs → chunk-GIVAGD3Q.mjs} +1 -1
- package/dist/{chunk-AV4IJKD2.mjs → chunk-HWQLTLNG.mjs} +18 -1
- package/dist/{chunk-6IT3MH5M.mjs → chunk-IOR2K26O.mjs} +178 -238
- package/dist/{chunk-4VU5TWCR.mjs → chunk-LMO5TJUS.mjs} +40 -35
- package/dist/{chunk-BEWOA4VV.mjs → chunk-M76V3OGJ.mjs} +508 -401
- package/dist/{chunk-YMZCMH5M.mjs → chunk-OI42GWLR.mjs} +17 -1
- package/dist/{chunk-2BDG2IWP.mjs → chunk-P4DSQ6M4.mjs} +16 -6
- package/dist/{chunk-THYRHHO2.mjs → chunk-YJDQ7NLA.mjs} +1 -1
- package/dist/{client-xVrOCYTW.d.ts → client-COek5GXK.d.ts} +3 -3
- package/dist/client.d.ts +8 -8
- package/dist/{config-CEeSV_Xo.d.ts → config-Dfanyqqt.d.ts} +2 -2
- package/dist/{config-CSvCVtB7.d.ts → config-rBpbgTw8.d.ts} +2 -2
- package/dist/direct-executor-GYJEKNV5.mjs +12 -0
- package/dist/distribution/coordinator/etcd.d.ts +2 -2
- package/dist/distribution/coordinator/etcd.mjs +1 -1
- package/dist/distribution/coordinator/in-memory.d.ts +2 -2
- package/dist/distribution/coordinator/in-memory.mjs +1 -1
- package/dist/distribution.d.ts +8 -8
- package/dist/distribution.mjs +109 -69
- package/dist/{engine-77ErLy8P.d.ts → engine-igk0aMpQ.d.ts} +109 -60
- package/dist/index.browser.mjs +1167 -749
- package/dist/index.d.ts +7 -7
- package/dist/index.mjs +10 -10
- package/dist/invalidation/filesystem.mjs +1 -1
- package/dist/{memory-CKF-9WLP.d.ts → memory-C7UMCMH3.d.ts} +35 -17
- package/dist/persistence/durability/checkpoint-worker.d.ts +2 -1
- package/dist/persistence/durability/checkpoint-worker.mjs +10 -10
- package/dist/react.d.ts +277 -182
- package/dist/react.mjs +189 -45
- package/dist/{schema-d5Afu03A.d.ts → schema-Bgzr4g7b.d.ts} +62 -10
- package/dist/server.d.ts +10 -10
- package/dist/server.mjs +11 -7
- package/dist/{tasks-BEiNxDRs.d.ts → tasks-BZt_zes6.d.ts} +3 -1
- package/dist/{thread-FLP45EUD.mjs → thread-JEVAYETR.mjs} +6 -6
- package/dist/{types-DAK7mnUZ.d.ts → types-gOUqhs2F.d.ts} +1 -1
- package/dist/vector/search-worker.d.ts +1 -1
- package/dist/vector/search-worker.mjs +2 -2
- package/dist/workers/entry.mjs +3 -3
- package/package.json +7 -7
- package/dist/chunk-VTPLKNWI.mjs +0 -135
- package/dist/direct-executor-3ZYXSGFX.mjs +0 -12
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { detectRuntime } from './chunk-
|
|
2
|
-
import { cloneProjected, everyValueFacetConfig, mergeFacets, computeFacets, tokenizeOptions, getNestedValue, visitTokens, countsWithoutScores, fanOutMatchCount, fanOutQuery, sanitizeGlobalStats,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { SCRATCH_SLOTS_PER_THREAD_POOL, osqRecordBytes, openSharedVectorField, osqBitsOf, createVectorStore, DISK_STORAGE_BLOCK_BYTES, createOsqQuantizer, magnitude, createHNSWIndex, nativeStoreScratchBytes, createOrdinalFilter, isTombstoned, addToOrdinalFilter, ordinalFilterValues, nativeScoresOf, toScore, removeFromOrdinalFilter, euclideanDistance, dotProduct, cosineSimilarityWithMagnitudes, ordinalFilterHas, requireWholeNeighbourLists, STORE_CALIBRATION_GENERATION, entryForOrd, toDistance, sharedMemoryAvailable, GRAPH_BUILD_CHUNKS_IN_FLIGHT_PER_WORKER, GRAPH_BUILD_DISPATCH_CHUNK, releaseLocksHeldBy, VECTOR_SEARCH_TIMEOUT_MS, VECTOR_SEARCH_LOAD_TIMEOUT_MS, VECTOR_INSERT_TIMEOUT_MS, VECTOR_SCRATCH_SLOTS } from './chunk-THYRHHO2.mjs';
|
|
1
|
+
import { getLanguage, detectRuntime } from './chunk-HWQLTLNG.mjs';
|
|
2
|
+
import { cloneProjected, everyValueFacetConfig, mergeFacets, computeFacets, tokenizeOptions, getNestedValue, visitTokens, countsWithoutScores, fanOutMatchCount, fanOutQuery, sanitizeGlobalStats, textFieldsChanged, projectionKeepsField, setNestedValue, fnv1a, bitsetHas, createBitSet, kWayMerge, fuzzyPrefixOf, boundedLevenshtein, getFlatSchema, bitsetSet, tokenize, bitsetFromSet, getAllInternalDocIds, getFieldValueByInternalId, getOrCreateFieldNameIndex, tokenizeIterator, polygonContainment, requireValidOperands, bitsetAnd, bitsetOr, bitsetNot, requirePolygonRing, VINCENTY_CONVERGENCE_THRESHOLD, VINCENTY_MAX_ITERATIONS, DEG_TO_RAD } from './chunk-LMO5TJUS.mjs';
|
|
3
|
+
import { schemaFieldsOf, isWordIndexedBase, validateDocument, validateDocumentStrict, isQuantizationMode, isStorageMode, requireValidFieldTypes, extractVectorFieldsFromSchema, VECTOR_PATTERN, parsedTypeOf, isListBase } from './chunk-653BNMAF.mjs';
|
|
4
|
+
import { SCRATCH_SLOTS_PER_THREAD_POOL, osqRecordBytes, openSharedVectorField, osqBitsOf, createVectorStore, DISK_STORAGE_BLOCK_BYTES, createOsqQuantizer, magnitude, createHNSWIndex, nativeStoreScratchBytes, createOrdinalFilter, isTombstoned, addToOrdinalFilter, ordinalFilterValues, nativeScoresOf, toScore, removeFromOrdinalFilter, euclideanDistance, dotProduct, cosineSimilarityWithMagnitudes, ordinalFilterHas, requireWholeNeighbourLists, STORE_CALIBRATION_GENERATION, entryForOrd, toDistance, sharedMemoryAvailable, GRAPH_BUILD_CHUNKS_IN_FLIGHT_PER_WORKER, GRAPH_BUILD_DISPATCH_CHUNK, releaseLocksHeldBy, VECTOR_SEARCH_TIMEOUT_MS, VECTOR_SEARCH_LOAD_TIMEOUT_MS, VECTOR_INSERT_TIMEOUT_MS, VECTOR_SCRATCH_SLOTS } from './chunk-YJDQ7NLA.mjs';
|
|
6
5
|
import { noteFallback } from './chunk-YNVIUGF5.mjs';
|
|
7
6
|
import { VALID_HNSW_METRICS } from './chunk-IFBKLBGB.mjs';
|
|
8
|
-
import { compareCodePoints, toReducedSortValue, readSortField, compareComparableValues, defaultSortMode, SORT_VALUE_MAX_CODE_POINTS } from './chunk-
|
|
7
|
+
import { compareCodePoints, toReducedSortValue, readSortField, compareComparableValues, defaultSortMode, truncateSortString, SORT_VALUE_MAX_CODE_POINTS } from './chunk-OI42GWLR.mjs';
|
|
9
8
|
import { NarsilError, ErrorCodes } from './chunk-USKFU7J5.mjs';
|
|
10
9
|
import { totalmem } from 'os';
|
|
11
10
|
import { getHeapStatistics } from 'v8';
|
|
@@ -59,20 +58,6 @@ function readHeapStatistics() {
|
|
|
59
58
|
}
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
// src/languages/registry.ts
|
|
63
|
-
var languages = /* @__PURE__ */ new Map();
|
|
64
|
-
languages.set("english", english);
|
|
65
|
-
function registerLanguage(module) {
|
|
66
|
-
languages.set(module.name, module);
|
|
67
|
-
}
|
|
68
|
-
function getLanguage(name) {
|
|
69
|
-
const lang = languages.get(name);
|
|
70
|
-
if (!lang) {
|
|
71
|
-
throw new NarsilError(ErrorCodes.LANGUAGE_NOT_SUPPORTED, `Language "${name}" is not registered`, { language: name });
|
|
72
|
-
}
|
|
73
|
-
return lang;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
61
|
// src/analysis/registry.ts
|
|
77
62
|
var tokenizers = /* @__PURE__ */ new Map();
|
|
78
63
|
var stopWordSets = /* @__PURE__ */ new Map();
|
|
@@ -200,6 +185,9 @@ function metadataToWire(meta) {
|
|
|
200
185
|
...promotion.storage !== void 0 ? { storage: promotion.storage } : {}
|
|
201
186
|
};
|
|
202
187
|
}
|
|
188
|
+
if (meta.patternValueLimit !== void 0) {
|
|
189
|
+
wire.pattern_value_limit = meta.patternValueLimit;
|
|
190
|
+
}
|
|
203
191
|
if (meta.indexUuid !== void 0) {
|
|
204
192
|
wire.index_uuid = meta.indexUuid;
|
|
205
193
|
}
|
|
@@ -321,6 +309,16 @@ function wireToMetadata(raw) {
|
|
|
321
309
|
meta.vectorPromotion = restored;
|
|
322
310
|
}
|
|
323
311
|
}
|
|
312
|
+
if (raw.pattern_value_limit !== void 0) {
|
|
313
|
+
if (!isPositiveInteger(raw.pattern_value_limit)) {
|
|
314
|
+
throw new NarsilError(
|
|
315
|
+
ErrorCodes.CONFIG_INVALID,
|
|
316
|
+
`The pattern value limit in the index metadata is ${String(raw.pattern_value_limit)}, but the limit must be a whole number of code points`,
|
|
317
|
+
{ patternValueLimit: String(raw.pattern_value_limit) }
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
meta.patternValueLimit = raw.pattern_value_limit;
|
|
321
|
+
}
|
|
324
322
|
if (typeof raw.index_uuid === "string" && raw.index_uuid.length > 0) {
|
|
325
323
|
meta.indexUuid = raw.index_uuid;
|
|
326
324
|
}
|
|
@@ -415,6 +413,7 @@ function wireToPartition(raw) {
|
|
|
415
413
|
fieldLengths: doc.field_lengths ?? {}
|
|
416
414
|
};
|
|
417
415
|
}
|
|
416
|
+
requireValidFieldTypes(raw.schema ?? {});
|
|
418
417
|
dropStoredVectorValues(documents, raw.schema ?? {});
|
|
419
418
|
const invertedIndex = {};
|
|
420
419
|
for (const [token, list] of Object.entries(raw.inverted_index ?? {})) {
|
|
@@ -499,6 +498,7 @@ function validateHnswMetric2(value) {
|
|
|
499
498
|
return void 0;
|
|
500
499
|
}
|
|
501
500
|
function storedDocumentsOf(raw) {
|
|
501
|
+
requireValidFieldTypes(raw.schema ?? {});
|
|
502
502
|
const documents = {};
|
|
503
503
|
for (const [docId, doc] of Object.entries(raw.documents ?? {})) {
|
|
504
504
|
documents[docId] = {
|
|
@@ -1894,14 +1894,14 @@ function createNumericIndex() {
|
|
|
1894
1894
|
}
|
|
1895
1895
|
|
|
1896
1896
|
// src/core/partition/indexing.ts
|
|
1897
|
-
function ensureFieldIndex(state, fieldPath,
|
|
1898
|
-
if ((
|
|
1897
|
+
function ensureFieldIndex(state, fieldPath, base) {
|
|
1898
|
+
if ((base === "number" || base === "number[]") && !state.numericIndexes.has(fieldPath)) {
|
|
1899
1899
|
state.numericIndexes.set(fieldPath, createNumericIndex());
|
|
1900
|
-
} else if ((
|
|
1900
|
+
} else if ((base === "boolean" || base === "boolean[]") && !state.booleanIndexes.has(fieldPath)) {
|
|
1901
1901
|
state.booleanIndexes.set(fieldPath, createBooleanIndex());
|
|
1902
|
-
} else if ((
|
|
1902
|
+
} else if ((base === "enum" || base === "enum[]") && !state.enumIndexes.has(fieldPath)) {
|
|
1903
1903
|
state.enumIndexes.set(fieldPath, createEnumIndex());
|
|
1904
|
-
} else if (
|
|
1904
|
+
} else if (base === "geopoint" && !state.geoIndexes.has(fieldPath)) {
|
|
1905
1905
|
state.geoIndexes.set(fieldPath, createGeoIndex());
|
|
1906
1906
|
}
|
|
1907
1907
|
}
|
|
@@ -2027,26 +2027,26 @@ function indexStringArrayField(state, internalId, fieldPath, arr, language, opti
|
|
|
2027
2027
|
applySurfaceCounts(state, surfaceCounts, 1);
|
|
2028
2028
|
tokensByField[fieldPath] = fieldTokenList;
|
|
2029
2029
|
}
|
|
2030
|
-
function indexDocument(state, docId, document,
|
|
2030
|
+
function indexDocument(state, docId, document, fields, language, options) {
|
|
2031
2031
|
const fieldLengths = {};
|
|
2032
2032
|
const tokensByField = {};
|
|
2033
2033
|
const internalId = resolveInternalId(state, docId);
|
|
2034
|
-
for (const
|
|
2034
|
+
for (const { path: fieldPath, base } of fields) {
|
|
2035
2035
|
const value = getNestedValue(document, fieldPath);
|
|
2036
2036
|
if (value === void 0 || value === null) continue;
|
|
2037
|
-
ensureFieldIndex(state, fieldPath,
|
|
2038
|
-
if (
|
|
2037
|
+
ensureFieldIndex(state, fieldPath, base);
|
|
2038
|
+
if (base === "string") {
|
|
2039
2039
|
indexStringField(state, internalId, fieldPath, value, language, options, fieldLengths, tokensByField);
|
|
2040
|
-
} else if (
|
|
2040
|
+
} else if (base === "number") {
|
|
2041
2041
|
getOrCreateNumericIndex(state, fieldPath).insert(internalId, value);
|
|
2042
|
-
} else if (
|
|
2042
|
+
} else if (base === "boolean") {
|
|
2043
2043
|
getOrCreateBooleanIndex(state, fieldPath).insert(internalId, value);
|
|
2044
|
-
} else if (
|
|
2044
|
+
} else if (base === "enum") {
|
|
2045
2045
|
state.enumIndexes.get(fieldPath)?.insert(internalId, value);
|
|
2046
|
-
} else if (
|
|
2046
|
+
} else if (base === "geopoint") {
|
|
2047
2047
|
const geo = value;
|
|
2048
2048
|
state.geoIndexes.get(fieldPath)?.insert(internalId, geo.lat, geo.lon);
|
|
2049
|
-
} else if (
|
|
2049
|
+
} else if (base === "string[]") {
|
|
2050
2050
|
indexStringArrayField(
|
|
2051
2051
|
state,
|
|
2052
2052
|
internalId,
|
|
@@ -2057,13 +2057,13 @@ function indexDocument(state, docId, document, flatSchema, language, options) {
|
|
|
2057
2057
|
fieldLengths,
|
|
2058
2058
|
tokensByField
|
|
2059
2059
|
);
|
|
2060
|
-
} else if (
|
|
2060
|
+
} else if (base === "number[]") {
|
|
2061
2061
|
const numIdx = getOrCreateNumericIndex(state, fieldPath);
|
|
2062
2062
|
for (const num of value) numIdx.insert(internalId, num);
|
|
2063
|
-
} else if (
|
|
2063
|
+
} else if (base === "boolean[]") {
|
|
2064
2064
|
const boolIdx = getOrCreateBooleanIndex(state, fieldPath);
|
|
2065
2065
|
for (const b of value) boolIdx.insert(internalId, b);
|
|
2066
|
-
} else if (
|
|
2066
|
+
} else if (base === "enum[]") {
|
|
2067
2067
|
const enumIdx = state.enumIndexes.get(fieldPath);
|
|
2068
2068
|
if (enumIdx) {
|
|
2069
2069
|
for (const e of value) enumIdx.insert(internalId, e);
|
|
@@ -2072,16 +2072,16 @@ function indexDocument(state, docId, document, flatSchema, language, options) {
|
|
|
2072
2072
|
}
|
|
2073
2073
|
return { fieldLengths, tokensByField };
|
|
2074
2074
|
}
|
|
2075
|
-
function removeFromIndexes(state, docId, storedDoc,
|
|
2075
|
+
function removeFromIndexes(state, docId, storedDoc, schemaFields, language, options) {
|
|
2076
2076
|
const fieldLengths = {};
|
|
2077
2077
|
const tokensByField = {};
|
|
2078
2078
|
const fields = storedDoc.fields;
|
|
2079
2079
|
const internalId = resolveInternalId(state, docId);
|
|
2080
2080
|
const opts = tokenizeOptions(options);
|
|
2081
|
-
for (const
|
|
2081
|
+
for (const { path: fieldPath, base } of schemaFields) {
|
|
2082
2082
|
const value = getNestedValue(fields, fieldPath);
|
|
2083
2083
|
if (value === void 0 || value === null) continue;
|
|
2084
|
-
if (
|
|
2084
|
+
if (base === "string") {
|
|
2085
2085
|
const result = tokenize(value, language, opts);
|
|
2086
2086
|
fieldLengths[fieldPath] = result.tokens.length;
|
|
2087
2087
|
const uniqueTokens = /* @__PURE__ */ new Set();
|
|
@@ -2096,15 +2096,15 @@ function removeFromIndexes(state, docId, storedDoc, flatSchema, language, option
|
|
|
2096
2096
|
for (const token of uniqueTokens) state.invertedIdx.remove(token, internalId);
|
|
2097
2097
|
applySurfaceCounts(state, surfaceCounts, -1);
|
|
2098
2098
|
tokensByField[fieldPath] = fieldTokenList;
|
|
2099
|
-
} else if (
|
|
2099
|
+
} else if (base === "number") {
|
|
2100
2100
|
state.numericIndexes.get(fieldPath)?.remove(internalId, value);
|
|
2101
|
-
} else if (
|
|
2101
|
+
} else if (base === "boolean") {
|
|
2102
2102
|
state.booleanIndexes.get(fieldPath)?.remove(internalId, value);
|
|
2103
|
-
} else if (
|
|
2103
|
+
} else if (base === "enum") {
|
|
2104
2104
|
state.enumIndexes.get(fieldPath)?.remove(internalId, value);
|
|
2105
|
-
} else if (
|
|
2105
|
+
} else if (base === "geopoint") {
|
|
2106
2106
|
state.geoIndexes.get(fieldPath)?.remove(internalId);
|
|
2107
|
-
} else if (
|
|
2107
|
+
} else if (base === "string[]") {
|
|
2108
2108
|
const arr = value;
|
|
2109
2109
|
const uniqueTokens = /* @__PURE__ */ new Set();
|
|
2110
2110
|
const fieldTokenList = [];
|
|
@@ -2122,17 +2122,17 @@ function removeFromIndexes(state, docId, storedDoc, flatSchema, language, option
|
|
|
2122
2122
|
for (const token of uniqueTokens) state.invertedIdx.remove(token, internalId);
|
|
2123
2123
|
applySurfaceCounts(state, surfaceCounts, -1);
|
|
2124
2124
|
tokensByField[fieldPath] = fieldTokenList;
|
|
2125
|
-
} else if (
|
|
2125
|
+
} else if (base === "number[]") {
|
|
2126
2126
|
const numIdx = state.numericIndexes.get(fieldPath);
|
|
2127
2127
|
if (numIdx) {
|
|
2128
2128
|
for (const num of value) numIdx.remove(internalId, num);
|
|
2129
2129
|
}
|
|
2130
|
-
} else if (
|
|
2130
|
+
} else if (base === "boolean[]") {
|
|
2131
2131
|
const boolIdx = state.booleanIndexes.get(fieldPath);
|
|
2132
2132
|
if (boolIdx) {
|
|
2133
2133
|
for (const b of value) boolIdx.remove(internalId, b);
|
|
2134
2134
|
}
|
|
2135
|
-
} else if (
|
|
2135
|
+
} else if (base === "enum[]") {
|
|
2136
2136
|
const enumIdx = state.enumIndexes.get(fieldPath);
|
|
2137
2137
|
if (enumIdx) {
|
|
2138
2138
|
for (const e of value) enumIdx.remove(internalId, e);
|
|
@@ -2150,10 +2150,10 @@ function resolveInternalId2(state, docId) {
|
|
|
2150
2150
|
}
|
|
2151
2151
|
return internalId;
|
|
2152
2152
|
}
|
|
2153
|
-
function updateFieldIndexOnly(state, docId, oldFields, newDoc,
|
|
2153
|
+
function updateFieldIndexOnly(state, docId, oldFields, newDoc, fields) {
|
|
2154
2154
|
const internalId = resolveInternalId2(state, docId);
|
|
2155
|
-
for (const
|
|
2156
|
-
if (
|
|
2155
|
+
for (const { path: fieldPath, base: fieldType } of fields) {
|
|
2156
|
+
if (isWordIndexedBase(fieldType)) continue;
|
|
2157
2157
|
const oldVal = getNestedValue(oldFields, fieldPath);
|
|
2158
2158
|
const newVal = getNestedValue(newDoc, fieldPath);
|
|
2159
2159
|
if (oldVal === newVal) continue;
|
|
@@ -2486,6 +2486,14 @@ function applyGeoPolygonBitset(filter, geoIndex, capacity) {
|
|
|
2486
2486
|
}
|
|
2487
2487
|
|
|
2488
2488
|
// src/filters/evaluator.ts
|
|
2489
|
+
var UNBOUNDED = { lower: null, upper: null };
|
|
2490
|
+
function textBoundsOf(operator, bound) {
|
|
2491
|
+
if (operator === "gt" || operator === "gte") {
|
|
2492
|
+
return { ...UNBOUNDED, lower: bound, lowerInclusive: operator === "gte", upperInclusive: false };
|
|
2493
|
+
}
|
|
2494
|
+
return { ...UNBOUNDED, upper: bound, upperInclusive: operator === "lte", lowerInclusive: false };
|
|
2495
|
+
}
|
|
2496
|
+
var TEXT_RANGE_OPERATORS = ["gt", "gte", "lt", "lte"];
|
|
2489
2497
|
var EXPRESSION_KEYS = new Set(FILTER_EXPRESSION_KEYS);
|
|
2490
2498
|
var OPERATOR_KEYS = new Set(FIELD_FILTER_OPERATORS);
|
|
2491
2499
|
function requireKnownKeys(value, known, describe) {
|
|
@@ -2557,20 +2565,33 @@ function evaluateFieldFilter(fieldPath, filter, context) {
|
|
|
2557
2565
|
if ("ne" in f && f.ne !== void 0) {
|
|
2558
2566
|
bitsets.push(applyNeBitset(f.ne, getAllDocsBitset, capacity, getValue, fieldIndex));
|
|
2559
2567
|
}
|
|
2560
|
-
|
|
2568
|
+
for (const operator of TEXT_RANGE_OPERATORS) {
|
|
2569
|
+
const bound = f[operator];
|
|
2570
|
+
if (typeof bound === "string") bitsets.push(context.textRangeBitset(fieldPath, textBoundsOf(operator, bound)));
|
|
2571
|
+
}
|
|
2572
|
+
if (typeof f.gt === "number") {
|
|
2561
2573
|
bitsets.push(applyGtBitset(f.gt, getAllDocsBitset, capacity, getValue, fieldIndex));
|
|
2562
2574
|
}
|
|
2563
|
-
if (
|
|
2575
|
+
if (typeof f.lt === "number") {
|
|
2564
2576
|
bitsets.push(applyLtBitset(f.lt, getAllDocsBitset, capacity, getValue, fieldIndex));
|
|
2565
2577
|
}
|
|
2566
|
-
if (
|
|
2578
|
+
if (typeof f.gte === "number") {
|
|
2567
2579
|
bitsets.push(applyGteBitset(f.gte, getAllDocsBitset, capacity, getValue, fieldIndex));
|
|
2568
2580
|
}
|
|
2569
|
-
if (
|
|
2581
|
+
if (typeof f.lte === "number") {
|
|
2570
2582
|
bitsets.push(applyLteBitset(f.lte, getAllDocsBitset, capacity, getValue, fieldIndex));
|
|
2571
2583
|
}
|
|
2572
|
-
if (
|
|
2573
|
-
|
|
2584
|
+
if (Array.isArray(f.between)) {
|
|
2585
|
+
const [low, high] = f.between;
|
|
2586
|
+
if (typeof low === "string" && typeof high === "string") {
|
|
2587
|
+
bitsets.push(
|
|
2588
|
+
context.textRangeBitset(fieldPath, { lower: low, lowerInclusive: true, upper: high, upperInclusive: true })
|
|
2589
|
+
);
|
|
2590
|
+
} else {
|
|
2591
|
+
bitsets.push(
|
|
2592
|
+
applyBetweenBitset([low, high], getAllDocsBitset, capacity, getValue, fieldIndex)
|
|
2593
|
+
);
|
|
2594
|
+
}
|
|
2574
2595
|
}
|
|
2575
2596
|
if ("in" in f && f.in !== void 0) {
|
|
2576
2597
|
bitsets.push(applyInBitset(f.in, getAllDocsBitset, capacity, getValue, fieldIndex));
|
|
@@ -2632,240 +2653,6 @@ function resolveGeoIndex(fieldPath, fieldIndex) {
|
|
|
2632
2653
|
return fieldIndex.index;
|
|
2633
2654
|
}
|
|
2634
2655
|
|
|
2635
|
-
// src/core/partition/filters.ts
|
|
2636
|
-
var EMPTY_GEO_INDEX = {
|
|
2637
|
-
radiusQuery: () => /* @__PURE__ */ new Set(),
|
|
2638
|
-
polygonQuery: () => /* @__PURE__ */ new Set()
|
|
2639
|
-
};
|
|
2640
|
-
function buildFilterContext(state, schema) {
|
|
2641
|
-
const flat = getFlatSchema(state, schema);
|
|
2642
|
-
const fieldIndexes = {};
|
|
2643
|
-
const capacity = state.docStore.internalIdCapacity();
|
|
2644
|
-
for (const [fieldPath, fieldType] of Object.entries(flat)) {
|
|
2645
|
-
if (fieldType === "number" || fieldType === "number[]") {
|
|
2646
|
-
const numIdx = state.numericIndexes.get(fieldPath);
|
|
2647
|
-
if (numIdx) {
|
|
2648
|
-
fieldIndexes[fieldPath] = {
|
|
2649
|
-
type: "numeric",
|
|
2650
|
-
index: {
|
|
2651
|
-
eq: (v) => numIdx.queryEq(v),
|
|
2652
|
-
gt: (v) => numIdx.queryGt(v),
|
|
2653
|
-
gte: (v) => numIdx.queryGte(v),
|
|
2654
|
-
lt: (v) => numIdx.queryLt(v),
|
|
2655
|
-
lte: (v) => numIdx.queryLte(v),
|
|
2656
|
-
between: (min, max) => numIdx.queryBetween(min, max),
|
|
2657
|
-
allDocIds: () => numIdx.getAllDocIds(),
|
|
2658
|
-
eqBitset: (v, cap) => numIdx.queryEqBitset(v, cap),
|
|
2659
|
-
gtBitset: (v, cap) => numIdx.queryGtBitset(v, cap),
|
|
2660
|
-
gteBitset: (v, cap) => numIdx.queryGteBitset(v, cap),
|
|
2661
|
-
ltBitset: (v, cap) => numIdx.queryLtBitset(v, cap),
|
|
2662
|
-
lteBitset: (v, cap) => numIdx.queryLteBitset(v, cap),
|
|
2663
|
-
betweenBitset: (min, max, cap) => numIdx.queryBetweenBitset(min, max, cap),
|
|
2664
|
-
allDocIdsBitset: (cap) => numIdx.getAllDocIdsBitset(cap)
|
|
2665
|
-
}
|
|
2666
|
-
};
|
|
2667
|
-
}
|
|
2668
|
-
} else if (fieldType === "boolean" || fieldType === "boolean[]") {
|
|
2669
|
-
const boolIdx = state.booleanIndexes.get(fieldPath);
|
|
2670
|
-
if (boolIdx) {
|
|
2671
|
-
fieldIndexes[fieldPath] = {
|
|
2672
|
-
type: "boolean",
|
|
2673
|
-
index: {
|
|
2674
|
-
getTrue: () => boolIdx.queryEq(true),
|
|
2675
|
-
getFalse: () => boolIdx.queryEq(false),
|
|
2676
|
-
allDocIds: () => boolIdx.getAllDocIds(),
|
|
2677
|
-
getTrueBitset: (cap) => boolIdx.queryEqBitset(true, cap),
|
|
2678
|
-
getFalseBitset: (cap) => boolIdx.queryEqBitset(false, cap),
|
|
2679
|
-
allDocIdsBitset: (cap) => boolIdx.getAllDocIdsBitset(cap)
|
|
2680
|
-
}
|
|
2681
|
-
};
|
|
2682
|
-
}
|
|
2683
|
-
} else if (fieldType === "enum" || fieldType === "enum[]") {
|
|
2684
|
-
const enumIdx = state.enumIndexes.get(fieldPath);
|
|
2685
|
-
if (enumIdx) {
|
|
2686
|
-
fieldIndexes[fieldPath] = {
|
|
2687
|
-
type: "enum",
|
|
2688
|
-
index: {
|
|
2689
|
-
getDocIds: (v) => enumIdx.queryEq(v),
|
|
2690
|
-
allDocIds: () => enumIdx.getAllDocIds(),
|
|
2691
|
-
getDocIdsBitset: (v, cap) => enumIdx.queryEqBitset(v, cap),
|
|
2692
|
-
getDocIdsInBitset: (values, cap) => enumIdx.queryInBitset(values, cap),
|
|
2693
|
-
allDocIdsBitset: (cap) => enumIdx.getAllDocIdsBitset(cap)
|
|
2694
|
-
}
|
|
2695
|
-
};
|
|
2696
|
-
}
|
|
2697
|
-
} else if (fieldType === "geopoint") {
|
|
2698
|
-
const geoIdx = state.geoIndexes.get(fieldPath);
|
|
2699
|
-
fieldIndexes[fieldPath] = {
|
|
2700
|
-
type: "geopoint",
|
|
2701
|
-
index: geoIdx === void 0 ? EMPTY_GEO_INDEX : geoIdx
|
|
2702
|
-
};
|
|
2703
|
-
}
|
|
2704
|
-
}
|
|
2705
|
-
let cachedAllDocIds = null;
|
|
2706
|
-
let cachedAllDocIdsBitset = null;
|
|
2707
|
-
return {
|
|
2708
|
-
fieldTypes: flat,
|
|
2709
|
-
fieldIndexes,
|
|
2710
|
-
getFieldValue: (internalId, fieldPath) => getFieldValueByInternalId(state.docStore, internalId, fieldPath),
|
|
2711
|
-
get allDocIds() {
|
|
2712
|
-
if (!cachedAllDocIds) {
|
|
2713
|
-
cachedAllDocIds = getAllInternalDocIds(state.docStore);
|
|
2714
|
-
}
|
|
2715
|
-
return cachedAllDocIds;
|
|
2716
|
-
},
|
|
2717
|
-
capacity,
|
|
2718
|
-
get allDocIdsBitset() {
|
|
2719
|
-
if (!cachedAllDocIdsBitset) {
|
|
2720
|
-
cachedAllDocIdsBitset = bitsetFromSet(this.allDocIds, capacity);
|
|
2721
|
-
}
|
|
2722
|
-
return cachedAllDocIdsBitset;
|
|
2723
|
-
}
|
|
2724
|
-
};
|
|
2725
|
-
}
|
|
2726
|
-
function applyPartitionFilters(state, filters, schema) {
|
|
2727
|
-
const context = buildFilterContext(state, schema);
|
|
2728
|
-
const resultBitset = evaluateFilters(filters, context);
|
|
2729
|
-
const resolver = state.docStore.resolver();
|
|
2730
|
-
const externalResult = /* @__PURE__ */ new Set();
|
|
2731
|
-
for (let wi = 0; wi < resultBitset.length; wi++) {
|
|
2732
|
-
let word = resultBitset[wi];
|
|
2733
|
-
if (word === 0) continue;
|
|
2734
|
-
const base = wi << 5;
|
|
2735
|
-
while (word !== 0) {
|
|
2736
|
-
const tz = Math.clz32(word & -word) ^ 31;
|
|
2737
|
-
const internalId = base + tz;
|
|
2738
|
-
const externalId = resolver.toExternal(internalId);
|
|
2739
|
-
if (externalId !== void 0) {
|
|
2740
|
-
externalResult.add(externalId);
|
|
2741
|
-
}
|
|
2742
|
-
word &= word - 1;
|
|
2743
|
-
}
|
|
2744
|
-
}
|
|
2745
|
-
return externalResult;
|
|
2746
|
-
}
|
|
2747
|
-
function applyPartitionFiltersBitset(state, filters, schema) {
|
|
2748
|
-
const context = buildFilterContext(state, schema);
|
|
2749
|
-
return evaluateFilters(filters, context);
|
|
2750
|
-
}
|
|
2751
|
-
function partitionFilterMatches(state, filters, schema) {
|
|
2752
|
-
const accepted = applyPartitionFiltersBitset(state, filters, schema);
|
|
2753
|
-
const docStore = state.docStore;
|
|
2754
|
-
const resolver = docStore.resolver();
|
|
2755
|
-
let count = 0;
|
|
2756
|
-
for (let wordIndex = 0; wordIndex < accepted.length; wordIndex++) {
|
|
2757
|
-
let word = accepted[wordIndex];
|
|
2758
|
-
if (word === 0) continue;
|
|
2759
|
-
const base = wordIndex << 5;
|
|
2760
|
-
while (word !== 0) {
|
|
2761
|
-
const trailingZeros = Math.clz32(word & -word) ^ 31;
|
|
2762
|
-
if (resolver.toExternal(base + trailingZeros) !== void 0) count++;
|
|
2763
|
-
word &= word - 1;
|
|
2764
|
-
}
|
|
2765
|
-
}
|
|
2766
|
-
return {
|
|
2767
|
-
count,
|
|
2768
|
-
hasExternal(docId) {
|
|
2769
|
-
const internalId = docStore.getInternalId(docId);
|
|
2770
|
-
return internalId !== void 0 && bitsetHas(accepted, internalId);
|
|
2771
|
-
},
|
|
2772
|
-
hasInternal(internalId) {
|
|
2773
|
-
return bitsetHas(accepted, internalId);
|
|
2774
|
-
}
|
|
2775
|
-
};
|
|
2776
|
-
}
|
|
2777
|
-
|
|
2778
|
-
// src/core/partition/posting-columns.ts
|
|
2779
|
-
function postingColumns(list) {
|
|
2780
|
-
const deletedDocs = list.deletedDocs;
|
|
2781
|
-
return {
|
|
2782
|
-
docIds: list.docIds,
|
|
2783
|
-
termFrequencies: list.termFrequencies,
|
|
2784
|
-
fieldNameIndices: list.fieldNameIndices,
|
|
2785
|
-
deletedDocs,
|
|
2786
|
-
hasDeleted: deletedDocs.size > 0,
|
|
2787
|
-
count: list.length
|
|
2788
|
-
};
|
|
2789
|
-
}
|
|
2790
|
-
|
|
2791
|
-
// src/core/partition/matches.ts
|
|
2792
|
-
function markPostingList(matched, list, fieldNames, fields, filterBitset) {
|
|
2793
|
-
const { docIds, fieldNameIndices, deletedDocs, hasDeleted, count } = postingColumns(list);
|
|
2794
|
-
for (let pi = 0; pi < count; pi++) {
|
|
2795
|
-
const internalId = docIds[pi];
|
|
2796
|
-
if (hasDeleted && deletedDocs.has(internalId)) continue;
|
|
2797
|
-
if (filterBitset && !bitsetHas(filterBitset, internalId)) continue;
|
|
2798
|
-
if (fields && !fields.includes(fieldNames[fieldNameIndices[pi]])) continue;
|
|
2799
|
-
bitsetSet(matched, internalId);
|
|
2800
|
-
}
|
|
2801
|
-
}
|
|
2802
|
-
function searchFulltextMatches(state, params) {
|
|
2803
|
-
const { queryTokens, prefixExpansion, fields, tolerance = 0, prefixLength = 2, exact = false, filterBitset } = params;
|
|
2804
|
-
const fieldNames = state.fieldNameTable.names;
|
|
2805
|
-
const matched = createBitSet(state.docStore.internalIdCapacity());
|
|
2806
|
-
for (const qt of queryTokens) {
|
|
2807
|
-
if (prefixExpansion && qt.token === prefixExpansion.token) {
|
|
2808
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2809
|
-
for (const term of [qt.token, ...prefixExpansion.terms]) {
|
|
2810
|
-
if (seen.has(term)) continue;
|
|
2811
|
-
seen.add(term);
|
|
2812
|
-
const postingList = state.invertedIdx.lookup(term);
|
|
2813
|
-
if (postingList) markPostingList(matched, postingList, fieldNames, fields, filterBitset);
|
|
2814
|
-
}
|
|
2815
|
-
continue;
|
|
2816
|
-
}
|
|
2817
|
-
if (exact || tolerance === 0) {
|
|
2818
|
-
const postingList = state.invertedIdx.lookup(qt.token);
|
|
2819
|
-
if (postingList) markPostingList(matched, postingList, fieldNames, fields, filterBitset);
|
|
2820
|
-
continue;
|
|
2821
|
-
}
|
|
2822
|
-
for (const match of state.invertedIdx.fuzzyLookup(qt.token, tolerance, prefixLength)) {
|
|
2823
|
-
markPostingList(matched, match.postingList, fieldNames, fields, filterBitset);
|
|
2824
|
-
}
|
|
2825
|
-
}
|
|
2826
|
-
const docStore = state.docStore;
|
|
2827
|
-
const resolver = docStore.resolver();
|
|
2828
|
-
let count = 0;
|
|
2829
|
-
for (let wordIndex = 0; wordIndex < matched.length; wordIndex++) {
|
|
2830
|
-
let word = matched[wordIndex];
|
|
2831
|
-
if (word === 0) continue;
|
|
2832
|
-
const base = wordIndex << 5;
|
|
2833
|
-
while (word !== 0) {
|
|
2834
|
-
const trailingZeros = Math.clz32(word & -word) ^ 31;
|
|
2835
|
-
if (resolver.toExternal(base + trailingZeros) !== void 0) count++;
|
|
2836
|
-
word &= word - 1;
|
|
2837
|
-
}
|
|
2838
|
-
}
|
|
2839
|
-
return {
|
|
2840
|
-
count,
|
|
2841
|
-
hasExternal(docId) {
|
|
2842
|
-
const internalId = docStore.getInternalId(docId);
|
|
2843
|
-
return internalId !== void 0 && bitsetHas(matched, internalId);
|
|
2844
|
-
},
|
|
2845
|
-
hasInternal(internalId) {
|
|
2846
|
-
return bitsetHas(matched, internalId);
|
|
2847
|
-
},
|
|
2848
|
-
matchedDocIds() {
|
|
2849
|
-
const external = /* @__PURE__ */ new Set();
|
|
2850
|
-
for (let wordIndex = 0; wordIndex < matched.length; wordIndex++) {
|
|
2851
|
-
let word = matched[wordIndex];
|
|
2852
|
-
if (word === 0) continue;
|
|
2853
|
-
const base = wordIndex << 5;
|
|
2854
|
-
while (word !== 0) {
|
|
2855
|
-
const trailingZeros = Math.clz32(word & -word) ^ 31;
|
|
2856
|
-
const externalId = resolver.toExternal(base + trailingZeros);
|
|
2857
|
-
if (externalId !== void 0) external.add(externalId);
|
|
2858
|
-
word &= word - 1;
|
|
2859
|
-
}
|
|
2860
|
-
}
|
|
2861
|
-
return external;
|
|
2862
|
-
},
|
|
2863
|
-
ordinalBitset() {
|
|
2864
|
-
return matched;
|
|
2865
|
-
}
|
|
2866
|
-
};
|
|
2867
|
-
}
|
|
2868
|
-
|
|
2869
2656
|
// src/core/partition/constants.ts
|
|
2870
2657
|
var TARGET_BLOCK_ENTRIES = 128;
|
|
2871
2658
|
var PRUNING_REJECTION_SLACK = 1e-12;
|
|
@@ -2974,8 +2761,9 @@ function grow(length, wanted) {
|
|
|
2974
2761
|
return next;
|
|
2975
2762
|
}
|
|
2976
2763
|
function kindForFieldType(fieldType) {
|
|
2977
|
-
|
|
2978
|
-
if (
|
|
2764
|
+
const base = parsedTypeOf(fieldType)?.base;
|
|
2765
|
+
if (base === "number") return "number";
|
|
2766
|
+
if (base === "boolean") return "boolean";
|
|
2979
2767
|
return "mixed";
|
|
2980
2768
|
}
|
|
2981
2769
|
function createValueStore(initialKind) {
|
|
@@ -3098,7 +2886,8 @@ function createValueStore(initialKind) {
|
|
|
3098
2886
|
|
|
3099
2887
|
// src/core/partition/sort-columns/index.ts
|
|
3100
2888
|
function mayHoldList(fieldType) {
|
|
3101
|
-
|
|
2889
|
+
const parsed = parsedTypeOf(fieldType);
|
|
2890
|
+
return parsed === void 0 || isListBase(parsed.base);
|
|
3102
2891
|
}
|
|
3103
2892
|
function columnKeyOf(field, fieldType, mode) {
|
|
3104
2893
|
return mayHoldList(fieldType) ? `${mode}:${field}` : `value:${field}`;
|
|
@@ -3234,6 +3023,48 @@ function createSortColumnSet(docStore) {
|
|
|
3234
3023
|
};
|
|
3235
3024
|
}
|
|
3236
3025
|
|
|
3026
|
+
// src/core/partition/sort-columns/range.ts
|
|
3027
|
+
function withinBounds(value, bounds) {
|
|
3028
|
+
if (value === null) return false;
|
|
3029
|
+
if (bounds.lower !== null) {
|
|
3030
|
+
const comparison = compareComparableValues(value, bounds.lower, "asc");
|
|
3031
|
+
if (comparison < 0 || comparison === 0 && !bounds.lowerInclusive) return false;
|
|
3032
|
+
}
|
|
3033
|
+
if (bounds.upper !== null) {
|
|
3034
|
+
const comparison = compareComparableValues(value, bounds.upper, "asc");
|
|
3035
|
+
if (comparison > 0 || comparison === 0 && !bounds.upperInclusive) return false;
|
|
3036
|
+
}
|
|
3037
|
+
return true;
|
|
3038
|
+
}
|
|
3039
|
+
function selectTextRange(column, requested, capacity, isLive2) {
|
|
3040
|
+
const bounds = {
|
|
3041
|
+
...requested,
|
|
3042
|
+
lower: requested.lower === null ? null : truncateSortString(requested.lower),
|
|
3043
|
+
upper: requested.upper === null ? null : truncateSortString(requested.upper)
|
|
3044
|
+
};
|
|
3045
|
+
const order = column.order;
|
|
3046
|
+
const ordered = order.ordered;
|
|
3047
|
+
const result = createBitSet(capacity);
|
|
3048
|
+
let start = 0;
|
|
3049
|
+
if (bounds.lower !== null) {
|
|
3050
|
+
const lowerRank = rankOfValue(order, bounds.lower);
|
|
3051
|
+
start = column.seek(bounds.lowerInclusive ? lowerRank : lowerRank + 1, "asc");
|
|
3052
|
+
}
|
|
3053
|
+
let end = ordered.length;
|
|
3054
|
+
if (bounds.upper !== null) {
|
|
3055
|
+
const upperRank = rankOfValue(order, bounds.upper);
|
|
3056
|
+
end = column.seek(bounds.upperInclusive ? upperRank + 1 : upperRank, "asc");
|
|
3057
|
+
}
|
|
3058
|
+
for (let position = start; position < end; position++) {
|
|
3059
|
+
const internalId = ordered[position];
|
|
3060
|
+
if (!column.isDirty(internalId) && isLive2(internalId)) bitsetSet(result, internalId);
|
|
3061
|
+
}
|
|
3062
|
+
for (const internalId of column.dirtyStream().present) {
|
|
3063
|
+
if (withinBounds(column.valueOf(internalId), bounds)) bitsetSet(result, internalId);
|
|
3064
|
+
}
|
|
3065
|
+
return result;
|
|
3066
|
+
}
|
|
3067
|
+
|
|
3237
3068
|
// src/core/partition/sort-columns/select.ts
|
|
3238
3069
|
function rankOrdersAfter(rank, other, direction) {
|
|
3239
3070
|
if (rank === MISSING_RANK) return other !== MISSING_RANK;
|
|
@@ -3354,85 +3185,326 @@ function createStream(column, direction, anchorRank) {
|
|
|
3354
3185
|
return dirtyId;
|
|
3355
3186
|
}
|
|
3356
3187
|
}
|
|
3357
|
-
return nextMissing();
|
|
3188
|
+
return nextMissing();
|
|
3189
|
+
};
|
|
3190
|
+
}
|
|
3191
|
+
function selectSortedPage(state, request) {
|
|
3192
|
+
const { fields, directions, fieldTypes, modes, limit, anchorKey, anchorId, matches } = request;
|
|
3193
|
+
if (limit <= 0 || fields.length === 0) return [];
|
|
3194
|
+
const set = state.sortColumns;
|
|
3195
|
+
if (set === null) return [];
|
|
3196
|
+
const columns = fields.map(
|
|
3197
|
+
(field, index) => set.column(field, fieldTypes[index], modes[index] ?? defaultSortMode(directions[index] ?? "asc"))
|
|
3198
|
+
);
|
|
3199
|
+
const resolver = state.docStore.resolver();
|
|
3200
|
+
const leading = columns[0];
|
|
3201
|
+
const leadingDirection = directions[0];
|
|
3202
|
+
const anchorRank = anchorKey === null || anchorId === null ? null : rankOfValue(leading.order, anchorKey[0] ?? null);
|
|
3203
|
+
const next = createStream(leading, leadingDirection, anchorRank);
|
|
3204
|
+
const page = [];
|
|
3205
|
+
for (; ; ) {
|
|
3206
|
+
const internalId = next();
|
|
3207
|
+
if (internalId === -1) break;
|
|
3208
|
+
if (matches !== null && !matches.hasInternal(internalId)) continue;
|
|
3209
|
+
const externalId = resolver.toExternal(internalId);
|
|
3210
|
+
if (externalId === void 0) continue;
|
|
3211
|
+
const leadingRank = leading.rankOf(internalId);
|
|
3212
|
+
if (page.length === limit && rankOrdersAfter(leadingRank, page[limit - 1].leadingRank, leadingDirection)) {
|
|
3213
|
+
break;
|
|
3214
|
+
}
|
|
3215
|
+
const key = new Array(columns.length);
|
|
3216
|
+
for (let i = 0; i < columns.length; i++) key[i] = columns[i].valueOf(internalId);
|
|
3217
|
+
const candidate = { internalId, externalId, leadingRank, key };
|
|
3218
|
+
if (anchorKey !== null && anchorId !== null) {
|
|
3219
|
+
if (compareWithAnchor(columns, directions, candidate, anchorKey, anchorId) <= 0) continue;
|
|
3220
|
+
}
|
|
3221
|
+
if (page.length === limit) {
|
|
3222
|
+
if (compareCandidates(columns, directions, candidate, page[limit - 1]) >= 0) continue;
|
|
3223
|
+
page.pop();
|
|
3224
|
+
}
|
|
3225
|
+
insertOrdered(page, candidate, columns, directions);
|
|
3226
|
+
}
|
|
3227
|
+
return page.map((entry) => ({ id: entry.externalId, key: entry.key }));
|
|
3228
|
+
}
|
|
3229
|
+
|
|
3230
|
+
// src/core/partition/sorting.ts
|
|
3231
|
+
function ensureColumns(state) {
|
|
3232
|
+
if (state.sortColumns === null) {
|
|
3233
|
+
state.sortColumns = createSortColumnSet(state.docStore);
|
|
3234
|
+
}
|
|
3235
|
+
return state.sortColumns;
|
|
3236
|
+
}
|
|
3237
|
+
function textRangeBitsetOf(state, fieldPath, fieldType, bounds, capacity) {
|
|
3238
|
+
const column = ensureColumns(state).column(fieldPath, fieldType, "min");
|
|
3239
|
+
const resolver = state.docStore.resolver();
|
|
3240
|
+
return selectTextRange(column, bounds, capacity, (internalId) => resolver.toExternal(internalId) !== void 0);
|
|
3241
|
+
}
|
|
3242
|
+
function sortedPageOf(state, request) {
|
|
3243
|
+
ensureColumns(state);
|
|
3244
|
+
return selectSortedPage(state, request);
|
|
3245
|
+
}
|
|
3246
|
+
function sortValuesOf(state, docId, fields, fieldTypes, modes) {
|
|
3247
|
+
const set = state.sortColumns;
|
|
3248
|
+
const internalId = state.docStore.getInternalId(docId);
|
|
3249
|
+
const stored = state.docStore.get(docId);
|
|
3250
|
+
const key = new Array(fields.length);
|
|
3251
|
+
for (let i = 0; i < fields.length; i++) {
|
|
3252
|
+
const mode = modes[i] ?? "min";
|
|
3253
|
+
if (set !== null && internalId !== void 0 && set.holds(fields[i], fieldTypes[i], mode)) {
|
|
3254
|
+
key[i] = set.column(fields[i], fieldTypes[i], mode).valueOf(internalId);
|
|
3255
|
+
continue;
|
|
3256
|
+
}
|
|
3257
|
+
key[i] = stored === void 0 ? null : toReducedSortValue(readSortField(stored.fields, fields[i]), mode);
|
|
3258
|
+
}
|
|
3259
|
+
return key;
|
|
3260
|
+
}
|
|
3261
|
+
function recordSortValues(state, internalId, document) {
|
|
3262
|
+
state.sortColumns?.record(internalId, document);
|
|
3263
|
+
}
|
|
3264
|
+
function forgetSortValues(state, internalId) {
|
|
3265
|
+
if (internalId === void 0) return;
|
|
3266
|
+
state.sortColumns?.forget(internalId);
|
|
3267
|
+
}
|
|
3268
|
+
function refreshSortColumns(state) {
|
|
3269
|
+
state.sortColumns?.refresh();
|
|
3270
|
+
}
|
|
3271
|
+
function sortColumnBytes(state) {
|
|
3272
|
+
return state.sortColumns === null ? 0 : state.sortColumns.estimateBytes();
|
|
3273
|
+
}
|
|
3274
|
+
|
|
3275
|
+
// src/core/partition/filters.ts
|
|
3276
|
+
var EMPTY_GEO_INDEX = {
|
|
3277
|
+
radiusQuery: () => /* @__PURE__ */ new Set(),
|
|
3278
|
+
polygonQuery: () => /* @__PURE__ */ new Set()
|
|
3279
|
+
};
|
|
3280
|
+
function buildFilterContext(state, schema) {
|
|
3281
|
+
const flat = getFlatSchema(state, schema);
|
|
3282
|
+
const fieldIndexes = {};
|
|
3283
|
+
const capacity = state.docStore.internalIdCapacity();
|
|
3284
|
+
for (const { path: fieldPath, base: fieldType } of schemaFieldsOf(schema)) {
|
|
3285
|
+
if (fieldType === "number" || fieldType === "number[]") {
|
|
3286
|
+
const numIdx = state.numericIndexes.get(fieldPath);
|
|
3287
|
+
if (numIdx) {
|
|
3288
|
+
fieldIndexes[fieldPath] = {
|
|
3289
|
+
type: "numeric",
|
|
3290
|
+
index: {
|
|
3291
|
+
eq: (v) => numIdx.queryEq(v),
|
|
3292
|
+
gt: (v) => numIdx.queryGt(v),
|
|
3293
|
+
gte: (v) => numIdx.queryGte(v),
|
|
3294
|
+
lt: (v) => numIdx.queryLt(v),
|
|
3295
|
+
lte: (v) => numIdx.queryLte(v),
|
|
3296
|
+
between: (min, max) => numIdx.queryBetween(min, max),
|
|
3297
|
+
allDocIds: () => numIdx.getAllDocIds(),
|
|
3298
|
+
eqBitset: (v, cap) => numIdx.queryEqBitset(v, cap),
|
|
3299
|
+
gtBitset: (v, cap) => numIdx.queryGtBitset(v, cap),
|
|
3300
|
+
gteBitset: (v, cap) => numIdx.queryGteBitset(v, cap),
|
|
3301
|
+
ltBitset: (v, cap) => numIdx.queryLtBitset(v, cap),
|
|
3302
|
+
lteBitset: (v, cap) => numIdx.queryLteBitset(v, cap),
|
|
3303
|
+
betweenBitset: (min, max, cap) => numIdx.queryBetweenBitset(min, max, cap),
|
|
3304
|
+
allDocIdsBitset: (cap) => numIdx.getAllDocIdsBitset(cap)
|
|
3305
|
+
}
|
|
3306
|
+
};
|
|
3307
|
+
}
|
|
3308
|
+
} else if (fieldType === "boolean" || fieldType === "boolean[]") {
|
|
3309
|
+
const boolIdx = state.booleanIndexes.get(fieldPath);
|
|
3310
|
+
if (boolIdx) {
|
|
3311
|
+
fieldIndexes[fieldPath] = {
|
|
3312
|
+
type: "boolean",
|
|
3313
|
+
index: {
|
|
3314
|
+
getTrue: () => boolIdx.queryEq(true),
|
|
3315
|
+
getFalse: () => boolIdx.queryEq(false),
|
|
3316
|
+
allDocIds: () => boolIdx.getAllDocIds(),
|
|
3317
|
+
getTrueBitset: (cap) => boolIdx.queryEqBitset(true, cap),
|
|
3318
|
+
getFalseBitset: (cap) => boolIdx.queryEqBitset(false, cap),
|
|
3319
|
+
allDocIdsBitset: (cap) => boolIdx.getAllDocIdsBitset(cap)
|
|
3320
|
+
}
|
|
3321
|
+
};
|
|
3322
|
+
}
|
|
3323
|
+
} else if (fieldType === "enum" || fieldType === "enum[]") {
|
|
3324
|
+
const enumIdx = state.enumIndexes.get(fieldPath);
|
|
3325
|
+
if (enumIdx) {
|
|
3326
|
+
fieldIndexes[fieldPath] = {
|
|
3327
|
+
type: "enum",
|
|
3328
|
+
index: {
|
|
3329
|
+
getDocIds: (v) => enumIdx.queryEq(v),
|
|
3330
|
+
allDocIds: () => enumIdx.getAllDocIds(),
|
|
3331
|
+
getDocIdsBitset: (v, cap) => enumIdx.queryEqBitset(v, cap),
|
|
3332
|
+
getDocIdsInBitset: (values, cap) => enumIdx.queryInBitset(values, cap),
|
|
3333
|
+
allDocIdsBitset: (cap) => enumIdx.getAllDocIdsBitset(cap)
|
|
3334
|
+
}
|
|
3335
|
+
};
|
|
3336
|
+
}
|
|
3337
|
+
} else if (fieldType === "geopoint") {
|
|
3338
|
+
const geoIdx = state.geoIndexes.get(fieldPath);
|
|
3339
|
+
fieldIndexes[fieldPath] = {
|
|
3340
|
+
type: "geopoint",
|
|
3341
|
+
index: geoIdx === void 0 ? EMPTY_GEO_INDEX : geoIdx
|
|
3342
|
+
};
|
|
3343
|
+
}
|
|
3344
|
+
}
|
|
3345
|
+
let cachedAllDocIds = null;
|
|
3346
|
+
let cachedAllDocIdsBitset = null;
|
|
3347
|
+
return {
|
|
3348
|
+
fieldTypes: flat,
|
|
3349
|
+
fieldIndexes,
|
|
3350
|
+
getFieldValue: (internalId, fieldPath) => getFieldValueByInternalId(state.docStore, internalId, fieldPath),
|
|
3351
|
+
textRangeBitset: (fieldPath, bounds) => textRangeBitsetOf(state, fieldPath, flat[fieldPath], bounds, capacity),
|
|
3352
|
+
get allDocIds() {
|
|
3353
|
+
if (!cachedAllDocIds) {
|
|
3354
|
+
cachedAllDocIds = getAllInternalDocIds(state.docStore);
|
|
3355
|
+
}
|
|
3356
|
+
return cachedAllDocIds;
|
|
3357
|
+
},
|
|
3358
|
+
capacity,
|
|
3359
|
+
get allDocIdsBitset() {
|
|
3360
|
+
if (!cachedAllDocIdsBitset) {
|
|
3361
|
+
cachedAllDocIdsBitset = bitsetFromSet(this.allDocIds, capacity);
|
|
3362
|
+
}
|
|
3363
|
+
return cachedAllDocIdsBitset;
|
|
3364
|
+
}
|
|
3358
3365
|
};
|
|
3359
3366
|
}
|
|
3360
|
-
function
|
|
3361
|
-
const
|
|
3362
|
-
|
|
3363
|
-
const set = state.sortColumns;
|
|
3364
|
-
if (set === null) return [];
|
|
3365
|
-
const columns = fields.map(
|
|
3366
|
-
(field, index) => set.column(field, fieldTypes[index], modes[index] ?? defaultSortMode(directions[index] ?? "asc"))
|
|
3367
|
-
);
|
|
3367
|
+
function applyPartitionFilters(state, filters, schema) {
|
|
3368
|
+
const context = buildFilterContext(state, schema);
|
|
3369
|
+
const resultBitset = evaluateFilters(filters, context);
|
|
3368
3370
|
const resolver = state.docStore.resolver();
|
|
3369
|
-
const
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
break;
|
|
3383
|
-
}
|
|
3384
|
-
const key = new Array(columns.length);
|
|
3385
|
-
for (let i = 0; i < columns.length; i++) key[i] = columns[i].valueOf(internalId);
|
|
3386
|
-
const candidate = { internalId, externalId, leadingRank, key };
|
|
3387
|
-
if (anchorKey !== null && anchorId !== null) {
|
|
3388
|
-
if (compareWithAnchor(columns, directions, candidate, anchorKey, anchorId) <= 0) continue;
|
|
3371
|
+
const externalResult = /* @__PURE__ */ new Set();
|
|
3372
|
+
for (let wi = 0; wi < resultBitset.length; wi++) {
|
|
3373
|
+
let word = resultBitset[wi];
|
|
3374
|
+
if (word === 0) continue;
|
|
3375
|
+
const base = wi << 5;
|
|
3376
|
+
while (word !== 0) {
|
|
3377
|
+
const tz = Math.clz32(word & -word) ^ 31;
|
|
3378
|
+
const internalId = base + tz;
|
|
3379
|
+
const externalId = resolver.toExternal(internalId);
|
|
3380
|
+
if (externalId !== void 0) {
|
|
3381
|
+
externalResult.add(externalId);
|
|
3382
|
+
}
|
|
3383
|
+
word &= word - 1;
|
|
3389
3384
|
}
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3385
|
+
}
|
|
3386
|
+
return externalResult;
|
|
3387
|
+
}
|
|
3388
|
+
function applyPartitionFiltersBitset(state, filters, schema) {
|
|
3389
|
+
const context = buildFilterContext(state, schema);
|
|
3390
|
+
return evaluateFilters(filters, context);
|
|
3391
|
+
}
|
|
3392
|
+
function partitionFilterMatches(state, filters, schema) {
|
|
3393
|
+
const accepted = applyPartitionFiltersBitset(state, filters, schema);
|
|
3394
|
+
const docStore = state.docStore;
|
|
3395
|
+
const resolver = docStore.resolver();
|
|
3396
|
+
let count = 0;
|
|
3397
|
+
for (let wordIndex = 0; wordIndex < accepted.length; wordIndex++) {
|
|
3398
|
+
let word = accepted[wordIndex];
|
|
3399
|
+
if (word === 0) continue;
|
|
3400
|
+
const base = wordIndex << 5;
|
|
3401
|
+
while (word !== 0) {
|
|
3402
|
+
const trailingZeros = Math.clz32(word & -word) ^ 31;
|
|
3403
|
+
if (resolver.toExternal(base + trailingZeros) !== void 0) count++;
|
|
3404
|
+
word &= word - 1;
|
|
3393
3405
|
}
|
|
3394
|
-
insertOrdered(page, candidate, columns, directions);
|
|
3395
3406
|
}
|
|
3396
|
-
return
|
|
3407
|
+
return {
|
|
3408
|
+
count,
|
|
3409
|
+
hasExternal(docId) {
|
|
3410
|
+
const internalId = docStore.getInternalId(docId);
|
|
3411
|
+
return internalId !== void 0 && bitsetHas(accepted, internalId);
|
|
3412
|
+
},
|
|
3413
|
+
hasInternal(internalId) {
|
|
3414
|
+
return bitsetHas(accepted, internalId);
|
|
3415
|
+
}
|
|
3416
|
+
};
|
|
3397
3417
|
}
|
|
3398
3418
|
|
|
3399
|
-
// src/core/partition/
|
|
3400
|
-
function
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3419
|
+
// src/core/partition/posting-columns.ts
|
|
3420
|
+
function postingColumns(list) {
|
|
3421
|
+
const deletedDocs = list.deletedDocs;
|
|
3422
|
+
return {
|
|
3423
|
+
docIds: list.docIds,
|
|
3424
|
+
termFrequencies: list.termFrequencies,
|
|
3425
|
+
fieldNameIndices: list.fieldNameIndices,
|
|
3426
|
+
deletedDocs,
|
|
3427
|
+
hasDeleted: deletedDocs.size > 0,
|
|
3428
|
+
count: list.length
|
|
3429
|
+
};
|
|
3404
3430
|
}
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3431
|
+
|
|
3432
|
+
// src/core/partition/matches.ts
|
|
3433
|
+
function markPostingList(matched, list, fieldNames, fields, filterBitset) {
|
|
3434
|
+
const { docIds, fieldNameIndices, deletedDocs, hasDeleted, count } = postingColumns(list);
|
|
3435
|
+
for (let pi = 0; pi < count; pi++) {
|
|
3436
|
+
const internalId = docIds[pi];
|
|
3437
|
+
if (hasDeleted && deletedDocs.has(internalId)) continue;
|
|
3438
|
+
if (filterBitset && !bitsetHas(filterBitset, internalId)) continue;
|
|
3439
|
+
if (fields && !fields.includes(fieldNames[fieldNameIndices[pi]])) continue;
|
|
3440
|
+
bitsetSet(matched, internalId);
|
|
3441
|
+
}
|
|
3408
3442
|
}
|
|
3409
|
-
function
|
|
3410
|
-
const
|
|
3411
|
-
const
|
|
3412
|
-
const
|
|
3413
|
-
const
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3443
|
+
function searchFulltextMatches(state, params) {
|
|
3444
|
+
const { queryTokens, prefixExpansion, fields, tolerance = 0, prefixLength = 2, exact = false, filterBitset } = params;
|
|
3445
|
+
const fieldNames = state.fieldNameTable.names;
|
|
3446
|
+
const matched = createBitSet(state.docStore.internalIdCapacity());
|
|
3447
|
+
for (const qt of queryTokens) {
|
|
3448
|
+
if (prefixExpansion && qt.token === prefixExpansion.token) {
|
|
3449
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3450
|
+
for (const term of [qt.token, ...prefixExpansion.terms]) {
|
|
3451
|
+
if (seen.has(term)) continue;
|
|
3452
|
+
seen.add(term);
|
|
3453
|
+
const postingList = state.invertedIdx.lookup(term);
|
|
3454
|
+
if (postingList) markPostingList(matched, postingList, fieldNames, fields, filterBitset);
|
|
3455
|
+
}
|
|
3418
3456
|
continue;
|
|
3419
3457
|
}
|
|
3420
|
-
|
|
3458
|
+
if (exact || tolerance === 0) {
|
|
3459
|
+
const postingList = state.invertedIdx.lookup(qt.token);
|
|
3460
|
+
if (postingList) markPostingList(matched, postingList, fieldNames, fields, filterBitset);
|
|
3461
|
+
continue;
|
|
3462
|
+
}
|
|
3463
|
+
for (const match of state.invertedIdx.fuzzyLookup(qt.token, tolerance, prefixLength)) {
|
|
3464
|
+
markPostingList(matched, match.postingList, fieldNames, fields, filterBitset);
|
|
3465
|
+
}
|
|
3421
3466
|
}
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
}
|
|
3434
|
-
|
|
3435
|
-
return
|
|
3467
|
+
const docStore = state.docStore;
|
|
3468
|
+
const resolver = docStore.resolver();
|
|
3469
|
+
let count = 0;
|
|
3470
|
+
for (let wordIndex = 0; wordIndex < matched.length; wordIndex++) {
|
|
3471
|
+
let word = matched[wordIndex];
|
|
3472
|
+
if (word === 0) continue;
|
|
3473
|
+
const base = wordIndex << 5;
|
|
3474
|
+
while (word !== 0) {
|
|
3475
|
+
const trailingZeros = Math.clz32(word & -word) ^ 31;
|
|
3476
|
+
if (resolver.toExternal(base + trailingZeros) !== void 0) count++;
|
|
3477
|
+
word &= word - 1;
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
return {
|
|
3481
|
+
count,
|
|
3482
|
+
hasExternal(docId) {
|
|
3483
|
+
const internalId = docStore.getInternalId(docId);
|
|
3484
|
+
return internalId !== void 0 && bitsetHas(matched, internalId);
|
|
3485
|
+
},
|
|
3486
|
+
hasInternal(internalId) {
|
|
3487
|
+
return bitsetHas(matched, internalId);
|
|
3488
|
+
},
|
|
3489
|
+
matchedDocIds() {
|
|
3490
|
+
const external = /* @__PURE__ */ new Set();
|
|
3491
|
+
for (let wordIndex = 0; wordIndex < matched.length; wordIndex++) {
|
|
3492
|
+
let word = matched[wordIndex];
|
|
3493
|
+
if (word === 0) continue;
|
|
3494
|
+
const base = wordIndex << 5;
|
|
3495
|
+
while (word !== 0) {
|
|
3496
|
+
const trailingZeros = Math.clz32(word & -word) ^ 31;
|
|
3497
|
+
const externalId = resolver.toExternal(base + trailingZeros);
|
|
3498
|
+
if (externalId !== void 0) external.add(externalId);
|
|
3499
|
+
word &= word - 1;
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
return external;
|
|
3503
|
+
},
|
|
3504
|
+
ordinalBitset() {
|
|
3505
|
+
return matched;
|
|
3506
|
+
}
|
|
3507
|
+
};
|
|
3436
3508
|
}
|
|
3437
3509
|
|
|
3438
3510
|
// src/core/partition/memory.ts
|
|
@@ -3607,11 +3679,11 @@ var EMPTY_STATS = {
|
|
|
3607
3679
|
averageFieldLengths: {},
|
|
3608
3680
|
docFrequencies: {}
|
|
3609
3681
|
};
|
|
3610
|
-
function textFieldsOf(
|
|
3611
|
-
return
|
|
3682
|
+
function textFieldsOf(fields) {
|
|
3683
|
+
return fields.filter((field) => isWordIndexedBase(field.base));
|
|
3612
3684
|
}
|
|
3613
3685
|
function rebuildTextIndex(state, schema, language, options) {
|
|
3614
|
-
const textFields = textFieldsOf(
|
|
3686
|
+
const textFields = textFieldsOf(schemaFieldsOf(schema));
|
|
3615
3687
|
state.invertedIdx.clear();
|
|
3616
3688
|
state.surfaceRegistry.clear();
|
|
3617
3689
|
state.stats.deserialize(EMPTY_STATS);
|
|
@@ -3623,10 +3695,10 @@ function rebuildTextIndex(state, schema, language, options) {
|
|
|
3623
3695
|
const fields = stored.fields;
|
|
3624
3696
|
const fieldLengths = {};
|
|
3625
3697
|
const tokensByField = {};
|
|
3626
|
-
for (const
|
|
3698
|
+
for (const { path: fieldPath, base } of textFields) {
|
|
3627
3699
|
const value = getNestedValue(fields, fieldPath);
|
|
3628
3700
|
if (value === void 0 || value === null) continue;
|
|
3629
|
-
if (
|
|
3701
|
+
if (base === "string") {
|
|
3630
3702
|
indexStringField(
|
|
3631
3703
|
state,
|
|
3632
3704
|
internalId,
|
|
@@ -5303,18 +5375,17 @@ function createPartitionIndex(partitionId, trackPositions = true) {
|
|
|
5303
5375
|
);
|
|
5304
5376
|
}
|
|
5305
5377
|
if (options?.validate !== false) {
|
|
5306
|
-
validateDocument(document, schema);
|
|
5378
|
+
validateDocument(document, schema, options?.patternValueLimit);
|
|
5307
5379
|
if (options?.strict) {
|
|
5308
5380
|
validateDocumentStrict(document, schema);
|
|
5309
5381
|
}
|
|
5310
5382
|
}
|
|
5311
5383
|
const internalId = state.docStore.ensureInternalId(docId);
|
|
5312
|
-
const flatSchema = getFlatSchema(state, schema);
|
|
5313
5384
|
const { fieldLengths, tokensByField } = indexDocument(
|
|
5314
5385
|
state,
|
|
5315
5386
|
docId,
|
|
5316
5387
|
document,
|
|
5317
|
-
|
|
5388
|
+
schemaFieldsOf(schema),
|
|
5318
5389
|
language,
|
|
5319
5390
|
options
|
|
5320
5391
|
);
|
|
@@ -5334,8 +5405,14 @@ function createPartitionIndex(partitionId, trackPositions = true) {
|
|
|
5334
5405
|
partitionId
|
|
5335
5406
|
});
|
|
5336
5407
|
}
|
|
5337
|
-
const
|
|
5338
|
-
|
|
5408
|
+
const { fieldLengths, tokensByField } = removeFromIndexes(
|
|
5409
|
+
state,
|
|
5410
|
+
docId,
|
|
5411
|
+
stored,
|
|
5412
|
+
schemaFieldsOf(schema),
|
|
5413
|
+
language,
|
|
5414
|
+
options
|
|
5415
|
+
);
|
|
5339
5416
|
const internalId = state.docStore.getInternalId(docId);
|
|
5340
5417
|
state.docStore.remove(docId);
|
|
5341
5418
|
state.stats.removeDocument(fieldLengths, tokensByField);
|
|
@@ -5366,19 +5443,19 @@ function createPartitionIndex(partitionId, trackPositions = true) {
|
|
|
5366
5443
|
});
|
|
5367
5444
|
}
|
|
5368
5445
|
if (options?.validate !== false) {
|
|
5369
|
-
validateDocument(document, schema);
|
|
5446
|
+
validateDocument(document, schema, options?.patternValueLimit);
|
|
5370
5447
|
if (options?.strict) {
|
|
5371
5448
|
validateDocumentStrict(document, schema);
|
|
5372
5449
|
}
|
|
5373
5450
|
}
|
|
5374
|
-
const
|
|
5375
|
-
const needsTextReindex = textFieldsChanged(stored.fields, document,
|
|
5451
|
+
const fields = schemaFieldsOf(schema);
|
|
5452
|
+
const needsTextReindex = textFieldsChanged(stored.fields, document, fields);
|
|
5376
5453
|
if (needsTextReindex) {
|
|
5377
5454
|
const { fieldLengths: oldFieldLengths, tokensByField: oldTokens } = removeFromIndexes(
|
|
5378
5455
|
state,
|
|
5379
5456
|
docId,
|
|
5380
5457
|
stored,
|
|
5381
|
-
|
|
5458
|
+
fields,
|
|
5382
5459
|
language,
|
|
5383
5460
|
options
|
|
5384
5461
|
);
|
|
@@ -5391,7 +5468,7 @@ function createPartitionIndex(partitionId, trackPositions = true) {
|
|
|
5391
5468
|
state,
|
|
5392
5469
|
docId,
|
|
5393
5470
|
document,
|
|
5394
|
-
|
|
5471
|
+
fields,
|
|
5395
5472
|
language,
|
|
5396
5473
|
options
|
|
5397
5474
|
);
|
|
@@ -5399,7 +5476,7 @@ function createPartitionIndex(partitionId, trackPositions = true) {
|
|
|
5399
5476
|
state.stats.addDocument(newFieldLengths, newTokens);
|
|
5400
5477
|
recordSortValues(state, internalId, document);
|
|
5401
5478
|
} else {
|
|
5402
|
-
updateFieldIndexOnly(state, docId, stored.fields, document,
|
|
5479
|
+
updateFieldIndexOnly(state, docId, stored.fields, document, fields);
|
|
5403
5480
|
state.docStore.store(docId, document, stored.fieldLengths);
|
|
5404
5481
|
const internalId = state.docStore.getInternalId(docId);
|
|
5405
5482
|
if (internalId !== void 0) recordSortValues(state, internalId, document);
|
|
@@ -6164,9 +6241,11 @@ function resolvePartitionInsertOptions(config, analysis, options) {
|
|
|
6164
6241
|
const applyStrict = config.strict === true;
|
|
6165
6242
|
const applyAnalyzer = analysis.stopWords !== void 0 || analysis.customTokenizer !== void 0;
|
|
6166
6243
|
const applySurfaces = config.surfaceForms !== false;
|
|
6167
|
-
|
|
6244
|
+
const applyPatternLimit = config.patternValueLimit !== void 0;
|
|
6245
|
+
if (!applyStrict && !applyAnalyzer && !applySurfaces && !applyPatternLimit) return options;
|
|
6168
6246
|
const resolved = { ...options };
|
|
6169
6247
|
if (applyStrict) resolved.strict = true;
|
|
6248
|
+
if (applyPatternLimit) resolved.patternValueLimit = config.patternValueLimit;
|
|
6170
6249
|
if (applyAnalyzer) {
|
|
6171
6250
|
resolved.stopWordOverride = options?.stopWordOverride ?? analysis.stopWords;
|
|
6172
6251
|
resolved.customTokenizer = options?.customTokenizer ?? analysis.customTokenizer;
|
|
@@ -6175,6 +6254,44 @@ function resolvePartitionInsertOptions(config, analysis, options) {
|
|
|
6175
6254
|
return resolved;
|
|
6176
6255
|
}
|
|
6177
6256
|
|
|
6257
|
+
// src/partitioning/manager/capacity.ts
|
|
6258
|
+
function createCapacityChecks(source) {
|
|
6259
|
+
const { indexName, config } = source;
|
|
6260
|
+
return {
|
|
6261
|
+
assertCapacity(pendingWrites = 0, partitionCountCap) {
|
|
6262
|
+
const maxDocsPerPartition = config.partitions?.maxDocsPerPartition;
|
|
6263
|
+
if (maxDocsPerPartition === void 0) return;
|
|
6264
|
+
const partitionCount = source.partitionCount();
|
|
6265
|
+
const effectivePartitionCount = partitionCountCap === void 0 ? partitionCount : Math.min(partitionCount, partitionCountCap);
|
|
6266
|
+
const totalCapacity = maxDocsPerPartition * effectivePartitionCount;
|
|
6267
|
+
const currentCount = source.documentCount() + pendingWrites;
|
|
6268
|
+
if (currentCount < totalCapacity) return;
|
|
6269
|
+
throw new NarsilError(
|
|
6270
|
+
ErrorCodes.PARTITION_CAPACITY_EXCEEDED,
|
|
6271
|
+
`Index "${indexName}" has reached its capacity of ${totalCapacity} documents (${maxDocsPerPartition} per partition \xD7 ${effectivePartitionCount} partitions)`,
|
|
6272
|
+
{
|
|
6273
|
+
indexName,
|
|
6274
|
+
currentCount,
|
|
6275
|
+
totalCapacity,
|
|
6276
|
+
maxDocsPerPartition,
|
|
6277
|
+
partitionCount: effectivePartitionCount
|
|
6278
|
+
}
|
|
6279
|
+
);
|
|
6280
|
+
},
|
|
6281
|
+
assertPartitionCapacity(partitionId, pendingWrites = 0) {
|
|
6282
|
+
const maxDocsPerPartition = config.partitions?.maxDocsPerPartition;
|
|
6283
|
+
if (maxDocsPerPartition === void 0) return;
|
|
6284
|
+
const currentCount = source.getPartition(partitionId).count() + pendingWrites;
|
|
6285
|
+
if (currentCount < maxDocsPerPartition) return;
|
|
6286
|
+
throw new NarsilError(
|
|
6287
|
+
ErrorCodes.PARTITION_CAPACITY_EXCEEDED,
|
|
6288
|
+
`Partition ${partitionId} of index "${indexName}" has reached its capacity of ${maxDocsPerPartition} documents`,
|
|
6289
|
+
{ indexName, partitionId, currentCount, maxDocsPerPartition }
|
|
6290
|
+
);
|
|
6291
|
+
}
|
|
6292
|
+
};
|
|
6293
|
+
}
|
|
6294
|
+
|
|
6178
6295
|
// src/partitioning/manager/index.ts
|
|
6179
6296
|
function createPartitionManager(indexName, config, language, router, initialPartitionCount, vectorIndexes) {
|
|
6180
6297
|
const count = initialPartitionCount ?? 1;
|
|
@@ -6302,27 +6419,17 @@ function createPartitionManager(indexName, config, language, router, initialPart
|
|
|
6302
6419
|
}
|
|
6303
6420
|
partitions.length = newCount;
|
|
6304
6421
|
},
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
{
|
|
6315
|
-
indexName,
|
|
6316
|
-
currentCount: docPartitionMap.size + pendingWrites,
|
|
6317
|
-
totalCapacity,
|
|
6318
|
-
maxDocsPerPartition: currentMaxDocs,
|
|
6319
|
-
partitionCount: effectivePartitionCount
|
|
6320
|
-
}
|
|
6321
|
-
);
|
|
6322
|
-
}
|
|
6422
|
+
...createCapacityChecks({
|
|
6423
|
+
indexName,
|
|
6424
|
+
config,
|
|
6425
|
+
partitionCount: () => partitions.length,
|
|
6426
|
+
documentCount: () => manager.countDocuments(),
|
|
6427
|
+
getPartition: (partitionId) => manager.getPartition(partitionId)
|
|
6428
|
+
}),
|
|
6429
|
+
routePartition(docId) {
|
|
6430
|
+
return router.route(docId, partitions.length);
|
|
6323
6431
|
},
|
|
6324
6432
|
insert(docId, document, options) {
|
|
6325
|
-
manager.assertCapacity();
|
|
6326
6433
|
const pid = router.route(docId, partitions.length);
|
|
6327
6434
|
const insertOpts = resolveInsertOptions(options);
|
|
6328
6435
|
partitions[pid].insert(docId, document, config.schema, language, insertOpts);
|
|
@@ -10364,7 +10471,7 @@ function refuseRepeatedDocIds(documents) {
|
|
|
10364
10471
|
function validateAsAnInsertDoes(documents, schema, options) {
|
|
10365
10472
|
if (options?.validate === false) return;
|
|
10366
10473
|
for (const { document } of documents) {
|
|
10367
|
-
validateDocument(document, schema);
|
|
10474
|
+
validateDocument(document, schema, options?.patternValueLimit);
|
|
10368
10475
|
if (options?.strict) validateDocumentStrict(document, schema);
|
|
10369
10476
|
}
|
|
10370
10477
|
}
|
|
@@ -10574,7 +10681,7 @@ var FieldLengths = class {
|
|
|
10574
10681
|
function buildSegmentPayload(documents, schema, language, options, trackPositions) {
|
|
10575
10682
|
refuseRepeatedDocIds(documents);
|
|
10576
10683
|
validateAsAnInsertDoes(documents, schema, options);
|
|
10577
|
-
const fields =
|
|
10684
|
+
const fields = schemaFieldsOf(schema);
|
|
10578
10685
|
const tokenizing = tokenizeOptions(options);
|
|
10579
10686
|
const postings = new TextPostings(trackPositions);
|
|
10580
10687
|
const surfaces = new SurfaceCounts();
|
|
@@ -10592,10 +10699,10 @@ function buildSegmentPayload(documents, schema, language, options, trackPosition
|
|
|
10592
10699
|
};
|
|
10593
10700
|
for (let ordinal = 0; ordinal < documents.length; ordinal++) {
|
|
10594
10701
|
const document = documents[ordinal].document;
|
|
10595
|
-
for (const
|
|
10702
|
+
for (const { path: fieldPath, base: fieldType } of fields) {
|
|
10596
10703
|
const value = getNestedValue(document, fieldPath);
|
|
10597
10704
|
if (value === void 0 || value === null) continue;
|
|
10598
|
-
if (fieldType
|
|
10705
|
+
if (!isWordIndexedBase(fieldType)) {
|
|
10599
10706
|
indexFilterValue(filters, ordinal, fieldPath, fieldType, value);
|
|
10600
10707
|
continue;
|
|
10601
10708
|
}
|
|
@@ -11159,4 +11266,4 @@ function createDirectExecutor(options) {
|
|
|
11159
11266
|
};
|
|
11160
11267
|
}
|
|
11161
11268
|
|
|
11162
|
-
export { CONSECUTIVE_TIMEOUTS_BEFORE_DEATH, DEFAULT_BACKPRESSURE_LIMIT, DEFAULT_REQUEST_TIMEOUT_MS, FIELD_FILTER_OPERATORS, FILTER_EXPRESSION_KEYS, NO_LIVE_VECTOR_AT_POSITION, SHUTDOWN_TIMEOUT_MS, VECTOR_FILE_MAX_VECTORS, buildSegmentPayload, countDead, createCompositePartition, createDirectExecutor, createFrozenSegment, createPartitionIndex, createPartitionManager, createPartitionRouter, createSharedFrozenSegment, deadBitsWhere, deadBytesFor, decodeVectorFilePayload, decodeVectorGraphPayload, decodeVectorIndexParts, deserializeMetadata, deserializePayloadV1, deserializePayloadV2, documentsOfPayloadV2, encodeSegmentState, freezeSegmentShared, generateId,
|
|
11269
|
+
export { CONSECUTIVE_TIMEOUTS_BEFORE_DEATH, DEFAULT_BACKPRESSURE_LIMIT, DEFAULT_REQUEST_TIMEOUT_MS, FIELD_FILTER_OPERATORS, FILTER_EXPRESSION_KEYS, NO_LIVE_VECTOR_AT_POSITION, SHUTDOWN_TIMEOUT_MS, VECTOR_FILE_MAX_VECTORS, buildSegmentPayload, countDead, createCompositePartition, createDirectExecutor, createFrozenSegment, createPartitionIndex, createPartitionManager, createPartitionRouter, createSharedFrozenSegment, deadBitsWhere, deadBytesFor, decodeVectorFilePayload, decodeVectorGraphPayload, decodeVectorIndexParts, deserializeMetadata, deserializePayloadV1, deserializePayloadV2, documentsOfPayloadV2, encodeSegmentState, freezeSegmentShared, generateId, getStopWords, getTokenizer, hasStopWords, hasTokenizer, isCompositePartition, isNodeMainThread, mergeFrozenSegments, missingWorkerEntry, nodeThreadId, readHeapStatistics, registerStopWords, registerTokenizer, resolveIndexAnalysis, resolvePartitionInsertOptions, resolveRequestThreadCount, resolveWorkerCount, resolveWorkerEntry, serializeMetadata, spawnNodeWorker, splitWorkerBudget, workerResourceLimits };
|