@harperfast/harper 5.2.10 → 5.2.13
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/resources/Table.d.ts +2 -2
- package/dist/resources/Table.js +182 -61
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/databases.d.ts +1 -0
- package/dist/resources/databases.js +73 -40
- package/dist/resources/databases.js.map +1 -1
- package/dist/utility/errors/hdbError.d.ts +8 -0
- package/dist/utility/errors/hdbError.js +29 -0
- package/dist/utility/errors/hdbError.js.map +1 -1
- package/npm-shrinkwrap.json +38 -38
- package/package.json +2 -2
- package/resources/Table.ts +177 -62
- package/resources/databases.ts +74 -42
- package/studio/web/assets/{Chat-Br06zdMA.js → Chat-4RrB5134.js} +1 -1
- package/studio/web/assets/{FloatingChat-BWImX5fA.js → FloatingChat-omlNMDcJ.js} +3 -3
- package/studio/web/assets/{apiToken-DN0nmDsq.js → apiToken-Bke3wvfZ.js} +1 -1
- package/studio/web/assets/{applications-kSxVoyeU.js → applications-DvFDYJgK.js} +1 -1
- package/studio/web/assets/{cssMode-C1JeufH5.js → cssMode-C1vRa7zh.js} +1 -1
- package/studio/web/assets/{editor-qoo9CrGO.js → editor-3XRWEDWX.js} +1 -1
- package/studio/web/assets/{html-Dt4IIy04.js → html-CTY5tdMr.js} +1 -1
- package/studio/web/assets/{htmlMode-DXgKKr4C.js → htmlMode-CG1vSD9t.js} +1 -1
- package/studio/web/assets/{index-6onkYFOG.js → index-Dfpeofdu.js} +5 -5
- package/studio/web/assets/{index.lazy-BrCFnpNJ.js → index.lazy-B1VOIv-t.js} +1 -1
- package/studio/web/assets/{javascript-DNCQGUBc.js → javascript-CJeJzGnI.js} +1 -1
- package/studio/web/assets/{jsonMode-CR6HWruP.js → jsonMode-CYPBwM82.js} +1 -1
- package/studio/web/assets/{languageServices-BM4fI4rS.js → languageServices-IKH4GUHl.js} +1 -1
- package/studio/web/assets/{lspLanguageFeatures-DSa1ttcD.js → lspLanguageFeatures-BC8_gxKG.js} +1 -1
- package/studio/web/assets/{notifications-BHXLnh6x.js → notifications-BfKBpYcq.js} +1 -1
- package/studio/web/assets/{notifications-CUmtIA6z.js → notifications-DFbArTfC.js} +1 -1
- package/studio/web/assets/{profile-8BeFSF3j.js → profile-Q4-T6c-S.js} +1 -1
- package/studio/web/assets/{regions-C8qR0HhD.js → regions-CtkV0xje.js} +1 -1
- package/studio/web/assets/{register-B4n5i0SD.js → register-1ZZuMsiA.js} +2 -2
- package/studio/web/assets/{setComponentFile-g0_B0lgX.js → setComponentFile-ZWLcWv5X.js} +1 -1
- package/studio/web/assets/{setup-B0CTj_Q5.js → setup-DWprJyJy.js} +2 -2
- package/studio/web/assets/{status-C6Yib7-K.js → status--aNm8isn.js} +1 -1
- package/studio/web/assets/{toggleHighContrast-Dgta7bVi.js → toggleHighContrast-Cq_lt3XD.js} +1 -1
- package/studio/web/assets/{tsMode-CH_jHvU-.js → tsMode-pjgytARx.js} +1 -1
- package/studio/web/assets/{typescript-Co9LCXd5.js → typescript-Cdg0mqUh.js} +1 -1
- package/studio/web/assets/{useEntityRestURL-wKC8NsC_.js → useEntityRestURL-RZhaY8Rn.js} +1 -1
- package/studio/web/assets/{workers-CWeLxCXA.js → workers-BgoXIqQe.js} +1 -1
- package/studio/web/assets/{xml-BadC-0Rk.js → xml-BwSeDMiP.js} +1 -1
- package/studio/web/assets/{yaml-BiUfxPbC.js → yaml-DotCUG5l.js} +1 -1
- package/studio/web/index.html +1 -1
- package/utility/errors/hdbError.ts +26 -0
|
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.hdbErrors = exports.AccessViolation = exports.Violation = exports.ValidationError = exports.IndexRebuildingError = exports.ServerError = exports.ClientError = exports.HdbError = void 0;
|
|
40
40
|
exports.handleHDBError = handleHDBError;
|
|
41
41
|
exports.isHDBError = isHDBError;
|
|
42
|
+
exports.appendErrorContext = appendErrorContext;
|
|
42
43
|
const harper_logger_ts_1 = __importDefault(require("../logging/harper_logger.js"));
|
|
43
44
|
const hdbErrors = __importStar(require("./commonErrors.js"));
|
|
44
45
|
exports.hdbErrors = hdbErrors;
|
|
@@ -205,4 +206,32 @@ exports.AccessViolation = AccessViolation;
|
|
|
205
206
|
function isHDBError(e) {
|
|
206
207
|
return e.__proto__.constructor.name === HdbError.name;
|
|
207
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Append context to an error's message, tolerating errors whose `message` cannot be assigned.
|
|
211
|
+
*
|
|
212
|
+
* A `DOMException` - what `fetch` rejects with when an `AbortSignal.timeout` fires - inherits
|
|
213
|
+
* `message` as a getter-only accessor, so a plain assignment throws under strict mode. Callers use
|
|
214
|
+
* this where losing the context is acceptable but throwing from a catch block is not.
|
|
215
|
+
*/
|
|
216
|
+
function appendErrorContext(error, context) {
|
|
217
|
+
try {
|
|
218
|
+
if (typeof error?.message !== 'string')
|
|
219
|
+
return;
|
|
220
|
+
const annotated = `${error.message}${context}`;
|
|
221
|
+
try {
|
|
222
|
+
error.message = annotated;
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// A getter-only `message` (DOMException) takes an own property instead.
|
|
226
|
+
Object.defineProperty(error, 'message', {
|
|
227
|
+
value: annotated,
|
|
228
|
+
writable: true,
|
|
229
|
+
configurable: true,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
/* frozen, or a throwing accessor - the original message still propagates */
|
|
235
|
+
}
|
|
236
|
+
}
|
|
208
237
|
//# sourceMappingURL=hdbError.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hdbError.js","sourceRoot":"","sources":["../../../utility/errors/hdbError.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoIb,wCAoBC;AAkCD,gCAEC;
|
|
1
|
+
{"version":3,"file":"hdbError.js","sourceRoot":"","sources":["../../../utility/errors/hdbError.ts"],"names":[],"mappings":"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"}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harper",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.13",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "harper",
|
|
9
|
-
"version": "5.2.
|
|
9
|
+
"version": "5.2.13",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@aws-sdk/client-s3": "^3.1012.0",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@fastify/cors": "^11.2.0",
|
|
18
18
|
"@fastify/static": "^9.1.3",
|
|
19
19
|
"@harperfast/extended-iterable": "1.0.3",
|
|
20
|
-
"@harperfast/rocksdb-js": "2.9.
|
|
20
|
+
"@harperfast/rocksdb-js": "2.9.1",
|
|
21
21
|
"@harperfast/skills": "^1.10.8",
|
|
22
22
|
"@turf/area": "6.5.0",
|
|
23
23
|
"@turf/boolean-contains": "6.5.0",
|
|
@@ -1063,9 +1063,9 @@
|
|
|
1063
1063
|
"license": "Apache-2.0"
|
|
1064
1064
|
},
|
|
1065
1065
|
"node_modules/@harperfast/rocksdb-js": {
|
|
1066
|
-
"version": "2.9.
|
|
1067
|
-
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js/-/rocksdb-js-2.9.
|
|
1068
|
-
"integrity": "sha512-
|
|
1066
|
+
"version": "2.9.1",
|
|
1067
|
+
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js/-/rocksdb-js-2.9.1.tgz",
|
|
1068
|
+
"integrity": "sha512-zWTY44pgmup0Owuvy7FAnY4yYI85cwvhVwvacisTDizDboytXaX49y3vmt21w81NEwkcpaA8lO9oH6BPCCpjEA==",
|
|
1069
1069
|
"license": "Apache-2.0",
|
|
1070
1070
|
"dependencies": {
|
|
1071
1071
|
"@harperfast/extended-iterable": "^1.0.3",
|
|
@@ -1079,20 +1079,20 @@
|
|
|
1079
1079
|
"node": "^22.18.0 || >=24.0.0"
|
|
1080
1080
|
},
|
|
1081
1081
|
"optionalDependencies": {
|
|
1082
|
-
"@harperfast/rocksdb-js-darwin-arm64": "2.9.
|
|
1083
|
-
"@harperfast/rocksdb-js-darwin-x64": "2.9.
|
|
1084
|
-
"@harperfast/rocksdb-js-linux-arm64-glibc": "2.9.
|
|
1085
|
-
"@harperfast/rocksdb-js-linux-arm64-musl": "2.9.
|
|
1086
|
-
"@harperfast/rocksdb-js-linux-x64-glibc": "2.9.
|
|
1087
|
-
"@harperfast/rocksdb-js-linux-x64-musl": "2.9.
|
|
1088
|
-
"@harperfast/rocksdb-js-win32-arm64": "2.9.
|
|
1089
|
-
"@harperfast/rocksdb-js-win32-x64": "2.9.
|
|
1082
|
+
"@harperfast/rocksdb-js-darwin-arm64": "2.9.1",
|
|
1083
|
+
"@harperfast/rocksdb-js-darwin-x64": "2.9.1",
|
|
1084
|
+
"@harperfast/rocksdb-js-linux-arm64-glibc": "2.9.1",
|
|
1085
|
+
"@harperfast/rocksdb-js-linux-arm64-musl": "2.9.1",
|
|
1086
|
+
"@harperfast/rocksdb-js-linux-x64-glibc": "2.9.1",
|
|
1087
|
+
"@harperfast/rocksdb-js-linux-x64-musl": "2.9.1",
|
|
1088
|
+
"@harperfast/rocksdb-js-win32-arm64": "2.9.1",
|
|
1089
|
+
"@harperfast/rocksdb-js-win32-x64": "2.9.1"
|
|
1090
1090
|
}
|
|
1091
1091
|
},
|
|
1092
1092
|
"node_modules/@harperfast/rocksdb-js-darwin-arm64": {
|
|
1093
|
-
"version": "2.9.
|
|
1094
|
-
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-darwin-arm64/-/rocksdb-js-darwin-arm64-2.9.
|
|
1095
|
-
"integrity": "sha512-
|
|
1093
|
+
"version": "2.9.1",
|
|
1094
|
+
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-darwin-arm64/-/rocksdb-js-darwin-arm64-2.9.1.tgz",
|
|
1095
|
+
"integrity": "sha512-PQupgyuFYEIDHkQLBGWd0T20TJAHF9u3E7JmcbnhSqEIu4TyvUB3bT5CsMofvNlSvkmuc/CFEkVDCZBjmW3jIg==",
|
|
1096
1096
|
"cpu": [
|
|
1097
1097
|
"arm64"
|
|
1098
1098
|
],
|
|
@@ -1106,9 +1106,9 @@
|
|
|
1106
1106
|
}
|
|
1107
1107
|
},
|
|
1108
1108
|
"node_modules/@harperfast/rocksdb-js-darwin-x64": {
|
|
1109
|
-
"version": "2.9.
|
|
1110
|
-
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-darwin-x64/-/rocksdb-js-darwin-x64-2.9.
|
|
1111
|
-
"integrity": "sha512-
|
|
1109
|
+
"version": "2.9.1",
|
|
1110
|
+
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-darwin-x64/-/rocksdb-js-darwin-x64-2.9.1.tgz",
|
|
1111
|
+
"integrity": "sha512-zo53r+Y7mdb/yjlcCcAA0ASYD4Xue7SVgNVJuNrMB13iLCftpITqe3uEBm60P9TArDO+Ug0bSU8skMb0NfFP9A==",
|
|
1112
1112
|
"cpu": [
|
|
1113
1113
|
"x64"
|
|
1114
1114
|
],
|
|
@@ -1122,9 +1122,9 @@
|
|
|
1122
1122
|
}
|
|
1123
1123
|
},
|
|
1124
1124
|
"node_modules/@harperfast/rocksdb-js-linux-arm64-glibc": {
|
|
1125
|
-
"version": "2.9.
|
|
1126
|
-
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-linux-arm64-glibc/-/rocksdb-js-linux-arm64-glibc-2.9.
|
|
1127
|
-
"integrity": "sha512
|
|
1125
|
+
"version": "2.9.1",
|
|
1126
|
+
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-linux-arm64-glibc/-/rocksdb-js-linux-arm64-glibc-2.9.1.tgz",
|
|
1127
|
+
"integrity": "sha512-gbpMzMVxcPQ2IDSI+/8zv3zqLgdqOQ4xJkVIeANoIFfhClzbx8ZFG+VdszbMZq7wUsqO62XPydEWj9Fx4iSawQ==",
|
|
1128
1128
|
"cpu": [
|
|
1129
1129
|
"arm64"
|
|
1130
1130
|
],
|
|
@@ -1141,9 +1141,9 @@
|
|
|
1141
1141
|
}
|
|
1142
1142
|
},
|
|
1143
1143
|
"node_modules/@harperfast/rocksdb-js-linux-arm64-musl": {
|
|
1144
|
-
"version": "2.9.
|
|
1145
|
-
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-linux-arm64-musl/-/rocksdb-js-linux-arm64-musl-2.9.
|
|
1146
|
-
"integrity": "sha512-
|
|
1144
|
+
"version": "2.9.1",
|
|
1145
|
+
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-linux-arm64-musl/-/rocksdb-js-linux-arm64-musl-2.9.1.tgz",
|
|
1146
|
+
"integrity": "sha512-edj0Mj9+Vq7rTp0JBVUNHHRVzeu/WINgg/fnTB5Dvvn3HZQAtCQXb3YIqDOu1h4WPJXjSPZPH5gl26CuVX5hdg==",
|
|
1147
1147
|
"cpu": [
|
|
1148
1148
|
"arm64"
|
|
1149
1149
|
],
|
|
@@ -1160,9 +1160,9 @@
|
|
|
1160
1160
|
}
|
|
1161
1161
|
},
|
|
1162
1162
|
"node_modules/@harperfast/rocksdb-js-linux-x64-glibc": {
|
|
1163
|
-
"version": "2.9.
|
|
1164
|
-
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-linux-x64-glibc/-/rocksdb-js-linux-x64-glibc-2.9.
|
|
1165
|
-
"integrity": "sha512-
|
|
1163
|
+
"version": "2.9.1",
|
|
1164
|
+
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-linux-x64-glibc/-/rocksdb-js-linux-x64-glibc-2.9.1.tgz",
|
|
1165
|
+
"integrity": "sha512-x2NdHcr4WU7WvJWbBkwa4fdtN5E4WZIlPtGn6TEH97x0zGe/r61Bwnxpr4+SgjG7ooFT66Jqv/lbSOi08xBTGA==",
|
|
1166
1166
|
"cpu": [
|
|
1167
1167
|
"x64"
|
|
1168
1168
|
],
|
|
@@ -1179,9 +1179,9 @@
|
|
|
1179
1179
|
}
|
|
1180
1180
|
},
|
|
1181
1181
|
"node_modules/@harperfast/rocksdb-js-linux-x64-musl": {
|
|
1182
|
-
"version": "2.9.
|
|
1183
|
-
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-linux-x64-musl/-/rocksdb-js-linux-x64-musl-2.9.
|
|
1184
|
-
"integrity": "sha512-
|
|
1182
|
+
"version": "2.9.1",
|
|
1183
|
+
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-linux-x64-musl/-/rocksdb-js-linux-x64-musl-2.9.1.tgz",
|
|
1184
|
+
"integrity": "sha512-OmhRNdT9JS+jMe3UMk0SN7fgMo2RZMaU0j67HY636kNMTPdtrJesUjp9IbekmE+NZzJnQvPucvgGxNDk+mm0Pg==",
|
|
1185
1185
|
"cpu": [
|
|
1186
1186
|
"x64"
|
|
1187
1187
|
],
|
|
@@ -1198,9 +1198,9 @@
|
|
|
1198
1198
|
}
|
|
1199
1199
|
},
|
|
1200
1200
|
"node_modules/@harperfast/rocksdb-js-win32-arm64": {
|
|
1201
|
-
"version": "2.9.
|
|
1202
|
-
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-win32-arm64/-/rocksdb-js-win32-arm64-2.9.
|
|
1203
|
-
"integrity": "sha512-
|
|
1201
|
+
"version": "2.9.1",
|
|
1202
|
+
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-win32-arm64/-/rocksdb-js-win32-arm64-2.9.1.tgz",
|
|
1203
|
+
"integrity": "sha512-Tn66YO/6e8BOwKLERig9GkBftLqgqLpCv0MkpIjc9WcVMHObeZmosTyhXzvU3KtxBDRQs6nAC+VgYSH8LJAOnw==",
|
|
1204
1204
|
"cpu": [
|
|
1205
1205
|
"arm64"
|
|
1206
1206
|
],
|
|
@@ -1214,9 +1214,9 @@
|
|
|
1214
1214
|
}
|
|
1215
1215
|
},
|
|
1216
1216
|
"node_modules/@harperfast/rocksdb-js-win32-x64": {
|
|
1217
|
-
"version": "2.9.
|
|
1218
|
-
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-win32-x64/-/rocksdb-js-win32-x64-2.9.
|
|
1219
|
-
"integrity": "sha512-
|
|
1217
|
+
"version": "2.9.1",
|
|
1218
|
+
"resolved": "https://registry.npmjs.org/@harperfast/rocksdb-js-win32-x64/-/rocksdb-js-win32-x64-2.9.1.tgz",
|
|
1219
|
+
"integrity": "sha512-vgsNVv7mwXpGPlba11fgcLgM3cLubwxr8aUIN9RoXx+PWLcoQLEQJ/fhSrtctdlkIWNGHjM5i3gvuv0jbqWxmw==",
|
|
1220
1220
|
"cpu": [
|
|
1221
1221
|
"x64"
|
|
1222
1222
|
],
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harperfast/harper",
|
|
3
3
|
"description": "Harper is an open-source Node.js performance platform that unifies database, cache, application, and messaging layers into one in-memory process.",
|
|
4
|
-
"version": "5.2.
|
|
4
|
+
"version": "5.2.13",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://harper.fast",
|
|
7
7
|
"bugs": {
|
|
@@ -179,7 +179,7 @@
|
|
|
179
179
|
"@fastify/cors": "^11.2.0",
|
|
180
180
|
"@fastify/static": "^9.1.3",
|
|
181
181
|
"@harperfast/extended-iterable": "1.0.3",
|
|
182
|
-
"@harperfast/rocksdb-js": "2.9.
|
|
182
|
+
"@harperfast/rocksdb-js": "2.9.1",
|
|
183
183
|
"@harperfast/skills": "^1.10.8",
|
|
184
184
|
"@turf/area": "6.5.0",
|
|
185
185
|
"@turf/boolean-contains": "6.5.0",
|
package/resources/Table.ts
CHANGED
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
ServerError,
|
|
50
50
|
AccessViolation,
|
|
51
51
|
ValidationError,
|
|
52
|
+
appendErrorContext,
|
|
52
53
|
type ValidationIssue,
|
|
53
54
|
} from '../utility/errors/hdbError.ts';
|
|
54
55
|
import * as signalling from '../utility/signalling.ts';
|
|
@@ -139,6 +140,20 @@ const EVICTION_BATCH_SIZE = 100;
|
|
|
139
140
|
// letting an unbounded number of open transactions (and their snapshots) accumulate.
|
|
140
141
|
const MAX_INFLIGHT_EVICTION_BATCHES = 4;
|
|
141
142
|
const CACHEABLE_STATUS_CODES = new Set([200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501]);
|
|
143
|
+
// Smallest forward sample `getRecordCount` will extrapolate a record rate from; below it the scan runs
|
|
144
|
+
// to completion and reports an exact count.
|
|
145
|
+
const MIN_ESTIMATOR_SAMPLE = 1_000;
|
|
146
|
+
// Budget intervals the forward scan may spend before it must estimate rather than keep scanning.
|
|
147
|
+
const MAX_ESTIMATE_CHECKPOINTS = 20;
|
|
148
|
+
// A store estimate's `count`, or 0 when the store answered with a shape that cannot be trusted --
|
|
149
|
+
// DESIGN.md's invariant for this API family is that such an answer degrades rather than poisons.
|
|
150
|
+
function usableCount(estimate: any): number {
|
|
151
|
+
const { count, confidence } = estimate ?? {};
|
|
152
|
+
// `confidence` needs its own finiteness check, not just the range: `null >= 0 && null <= 1` is true
|
|
153
|
+
if (!Number.isFinite(count) || count < 0 || !Number.isFinite(confidence) || confidence < 0 || confidence > 1)
|
|
154
|
+
return 0;
|
|
155
|
+
return count;
|
|
156
|
+
}
|
|
142
157
|
envMngr.initSync();
|
|
143
158
|
const LMDB_PREFETCH_WRITES = envMngr.get(CONFIG_PARAMS.STORAGE_PREFETCHWRITES);
|
|
144
159
|
const LOCK_TIMEOUT = 10000;
|
|
@@ -1595,8 +1610,7 @@ export function makeTable(options) {
|
|
|
1595
1610
|
records: './', // an href to the records themselves
|
|
1596
1611
|
name: tableName,
|
|
1597
1612
|
database: databaseName,
|
|
1598
|
-
auditSize:
|
|
1599
|
-
auditStore instanceof RocksDatabase ? auditStore.getKeysCount() : auditStore?.getStats().entryCount,
|
|
1613
|
+
auditSize: auditStore?.getStats().entryCount,
|
|
1600
1614
|
attributes,
|
|
1601
1615
|
recordCount: undefined,
|
|
1602
1616
|
estimatedRecordRange: undefined,
|
|
@@ -4896,82 +4910,174 @@ export function makeTable(options) {
|
|
|
4896
4910
|
const exactCount = options?.exactCount;
|
|
4897
4911
|
const TIME_LIMIT = options?.timeLimit ?? 1000 / 2; // one second time limit, enforced by seeing if we are halfway through at 500ms
|
|
4898
4912
|
const start = performance.now();
|
|
4899
|
-
// `entryCount` (the exact key count) is only needed once the scan blows the time budget --
|
|
4900
|
-
// to decide whether to estimate and as the extrapolation base. On RocksDB it is a full
|
|
4901
|
-
// key-only scan, so we defer it: tables that finish within budget (the common case) and
|
|
4902
|
-
// `exact_count` requests never pay for it. `halfway`/`entryCount` stay 0 until first computed.
|
|
4903
4913
|
let entryCount = 0;
|
|
4904
|
-
let
|
|
4905
|
-
let
|
|
4906
|
-
|
|
4914
|
+
let remainderPhysical = 0;
|
|
4915
|
+
let estimator;
|
|
4916
|
+
// feature-detected per DESIGN.md's invariant for this API family; LMDB stores do not implement it
|
|
4917
|
+
const canEstimate =
|
|
4918
|
+
typeof primaryStore.createCountEstimator === 'function' && typeof primaryStore.estimateCount === 'function';
|
|
4919
|
+
let estimatorFailed = false;
|
|
4920
|
+
let warnedNoBase = false;
|
|
4921
|
+
let checkpoints = 0;
|
|
4922
|
+
let checkpointedEntries = 0;
|
|
4907
4923
|
let recordCount = 0;
|
|
4908
4924
|
let entriesScanned = 0;
|
|
4925
|
+
let lastKey;
|
|
4909
4926
|
let limit: number;
|
|
4910
|
-
|
|
4927
|
+
let nextCheckAt = start + TIME_LIMIT;
|
|
4928
|
+
for (const { key, value } of primaryStore.getRange({ start: true, lazy: true, snapshot: false })) {
|
|
4911
4929
|
if (value != null) recordCount++;
|
|
4912
4930
|
entriesScanned++;
|
|
4931
|
+
lastKey = key;
|
|
4913
4932
|
await rest();
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4933
|
+
// a table too small to reach the floor is small enough to finish exactly
|
|
4934
|
+
if (exactCount || entriesScanned < MIN_ESTIMATOR_SAMPLE) continue;
|
|
4935
|
+
const now = performance.now();
|
|
4936
|
+
if (now <= nextCheckAt) continue;
|
|
4937
|
+
nextCheckAt = now + TIME_LIMIT;
|
|
4938
|
+
checkpoints++;
|
|
4939
|
+
if (canEstimate && !estimatorFailed) {
|
|
4940
|
+
try {
|
|
4941
|
+
estimator ??= primaryStore.createCountEstimator({ start: true });
|
|
4942
|
+
estimator.advance(lastKey, entriesScanned - checkpointedEntries);
|
|
4943
|
+
checkpointedEntries = entriesScanned;
|
|
4944
|
+
entryCount = usableCount(estimator.estimate());
|
|
4945
|
+
} catch (error) {
|
|
4946
|
+
// a store closing concurrently -- drop_table can, while this scan is parked in a yield
|
|
4947
|
+
logger.debug?.('Count estimator unavailable, falling back to an exact scan', error);
|
|
4948
|
+
estimatorFailed = true;
|
|
4949
|
+
estimator = undefined;
|
|
4950
|
+
entryCount = 0;
|
|
4921
4951
|
}
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4952
|
+
} else if (!canEstimate) {
|
|
4953
|
+
// `canEstimate` false is not the same as "LMDB": a RocksDB store whose native module predates
|
|
4954
|
+
// the estimator API lands here too, and `RocksDatabase.getStats()` carries no `entryCount`.
|
|
4955
|
+
try {
|
|
4956
|
+
const stats = primaryStore.getStats?.();
|
|
4957
|
+
entryCount = Number.isFinite(stats?.entryCount) && stats.entryCount > 0 ? stats.entryCount : 0;
|
|
4958
|
+
} catch {
|
|
4959
|
+
entryCount = 0;
|
|
4926
4960
|
}
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4961
|
+
}
|
|
4962
|
+
if (!entryCount && canEstimate && !estimatorFailed) {
|
|
4963
|
+
// Range estimates are block-granular and can report 0 for a store whose entries are still
|
|
4964
|
+
// in the memtable. Without a base the escape cannot fire at all, so fall back to the
|
|
4965
|
+
// whole-store property rather than silently walking the table.
|
|
4966
|
+
try {
|
|
4967
|
+
const wholeStore = primaryStore.getEstimatedKeyCount();
|
|
4968
|
+
entryCount = Number.isFinite(wholeStore) && wholeStore > 0 ? wholeStore : 0;
|
|
4969
|
+
} catch {
|
|
4970
|
+
entryCount = 0;
|
|
4971
|
+
}
|
|
4972
|
+
if (!entryCount && !warnedNoBase) {
|
|
4973
|
+
warnedNoBase = true;
|
|
4974
|
+
logger.debug?.(`No usable key-count estimate for ${tableName}; counting records by full scan`);
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
// Zero is "no usable base": degrade to the exact scan. The checkpoint ceiling is what stops a
|
|
4978
|
+
// base that keeps undershooting from holding the halfway test false forever and walking the
|
|
4979
|
+
// whole table; the reverse sample is bounded by `limit` in turn.
|
|
4980
|
+
if (
|
|
4981
|
+
entryCount > 0 &&
|
|
4982
|
+
(checkpoints >= MAX_ESTIMATE_CHECKPOINTS || entriesScanned < Math.floor(entryCount / 2))
|
|
4983
|
+
) {
|
|
4984
|
+
if (canEstimate) {
|
|
4985
|
+
try {
|
|
4986
|
+
const remaining = primaryStore.estimateCount({ start: lastKey, exclusiveStart: true });
|
|
4987
|
+
// widened by its own reported untrustworthiness: block-granular, so it can land below
|
|
4988
|
+
// the live count it is meant to bound
|
|
4989
|
+
const remainingCount = usableCount(remaining);
|
|
4990
|
+
remainderPhysical = remainingCount > 0 ? remainingCount * (2 - remaining.confidence) : 0;
|
|
4991
|
+
} catch {
|
|
4992
|
+
remainderPhysical = 0;
|
|
4993
|
+
}
|
|
4994
|
+
// A zero or unusable remainder is valid -- entries still in the memtable read as none
|
|
4995
|
+
// through range statistics -- but it would leave `baseMax` resting on the sampled ends
|
|
4996
|
+
// alone. The whole-store property is a separate, non-range source, so fall back to it.
|
|
4997
|
+
if (!remainderPhysical) {
|
|
4998
|
+
try {
|
|
4999
|
+
const wholeStore = primaryStore.getEstimatedKeyCount();
|
|
5000
|
+
if (Number.isFinite(wholeStore)) remainderPhysical = Math.max(wholeStore - entriesScanned, 0);
|
|
5001
|
+
} catch {
|
|
5002
|
+
remainderPhysical = 0;
|
|
5003
|
+
}
|
|
5004
|
+
}
|
|
5005
|
+
}
|
|
5006
|
+
limit = entriesScanned;
|
|
5007
|
+
break;
|
|
4930
5008
|
}
|
|
4931
5009
|
}
|
|
4932
5010
|
if (limit) {
|
|
4933
5011
|
// in this case we are going to make an estimate of the table count using the first thousand
|
|
4934
5012
|
// entries and last thousand entries
|
|
4935
5013
|
const firstRecordCount = recordCount;
|
|
5014
|
+
const firstKey = lastKey;
|
|
4936
5015
|
recordCount = 0;
|
|
4937
5016
|
// Bound the reverse scan explicitly. The getRange `limit` option is honored by lmdb-js but
|
|
4938
5017
|
// ignored by rocksdb-js; without this break the scan reads the whole table, so `recordRate`
|
|
4939
5018
|
// blows up to ~entryCount/(2*limit) and the estimate scales with entryCount^2 -- the source
|
|
4940
5019
|
// of the wildly inflated `record_count` (e.g. 20,000,000 for ~105k rows) on large RocksDB
|
|
4941
|
-
// tables.
|
|
5020
|
+
// tables.
|
|
4942
5021
|
let reverseScanned = 0;
|
|
4943
|
-
|
|
5022
|
+
// Sized independently of the forward scan. `entriesScanned` is whatever the forward pass
|
|
5023
|
+
// covered before it escaped, and the checkpoint ceiling lets that run twenty budget
|
|
5024
|
+
// intervals when the base keeps undershooting; matching it here would read that same count
|
|
5025
|
+
// again and double the wall clock of the call this path exists to bound.
|
|
5026
|
+
const reverseLimit = Math.min(limit, MIN_ESTIMATOR_SAMPLE);
|
|
5027
|
+
// Disjointness is enforced against the forward scan's own last key rather than inferred from
|
|
5028
|
+
// the base, which is an estimate that can overshoot by more than 2x.
|
|
5029
|
+
let sampledWholeTable = false;
|
|
5030
|
+
for (const { key, value } of primaryStore.getRange({
|
|
4944
5031
|
start: '\uffff',
|
|
4945
5032
|
reverse: true,
|
|
4946
5033
|
lazy: true,
|
|
4947
|
-
limit,
|
|
5034
|
+
limit: reverseLimit,
|
|
4948
5035
|
snapshot: false,
|
|
4949
5036
|
})) {
|
|
5037
|
+
if (compareKeys(key, firstKey) <= 0) {
|
|
5038
|
+
sampledWholeTable = true;
|
|
5039
|
+
break;
|
|
5040
|
+
}
|
|
4950
5041
|
if (value != null) recordCount++;
|
|
4951
5042
|
reverseScanned++;
|
|
4952
5043
|
await rest();
|
|
4953
|
-
if (reverseScanned >=
|
|
5044
|
+
if (reverseScanned >= reverseLimit) break;
|
|
4954
5045
|
}
|
|
5046
|
+
// the samples met, so between them they covered every entry
|
|
5047
|
+
if (sampledWholeTable) return { recordCount: recordCount + firstRecordCount };
|
|
4955
5048
|
// Use the actual entries sampled, not limit*2: the reverse scan can yield fewer than `limit`
|
|
4956
5049
|
// (concurrent deletions under snapshot:false, or an overestimated entryCount), and counting
|
|
4957
5050
|
// those un-scanned slots would inflate the denominator and underestimate the rate.
|
|
4958
|
-
const
|
|
4959
|
-
const recordRate = (
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
//
|
|
4966
|
-
|
|
4967
|
-
const
|
|
4968
|
-
const
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
5051
|
+
const sampledRecords = recordCount + firstRecordCount;
|
|
5052
|
+
const recordRate = sampledRecords / (limit + reverseScanned);
|
|
5053
|
+
// Endpoints for the extrapolation base, spanning both ways an estimated base can be wrong:
|
|
5054
|
+
// every remaining entry superseded (only what was sampled is live) through every remaining
|
|
5055
|
+
// entry live (the uncalibrated physical count). Churn concentrated outside the sampled ends
|
|
5056
|
+
// calibrates to nothing, so an interval derived from the estimator's confidence would sit
|
|
5057
|
+
// narrowly around the wrong number. Both endpoints are themselves estimates on RocksDB, so
|
|
5058
|
+
// this is a widened heuristic interval, not a guaranteed bound on the live count.
|
|
5059
|
+
const baseMin = entriesScanned + reverseScanned;
|
|
5060
|
+
const baseMax = Math.max(entriesScanned + remainderPhysical, entryCount, baseMin);
|
|
5061
|
+
const estimatedRecordCount = Math.round(recordRate * Math.max(entryCount, baseMin));
|
|
5062
|
+
// The samples counted these directly, and the entries between them can only add; everything
|
|
5063
|
+
// outside the samples could be live. A statistical interval inside those endpoints would be
|
|
5064
|
+
// narrowest exactly where the ends are least representative of the middle -- sampled ends
|
|
5065
|
+
// that are all deletion entries give a rate of 0, collapsing an upper end to ~0 with live
|
|
5066
|
+
// rows in between -- so the endpoints are the evidence itself.
|
|
5067
|
+
const lower = sampledRecords;
|
|
5068
|
+
const upper = Math.round(baseMax);
|
|
5069
|
+
// Report only the precision the interval supports, but never so coarse a unit that the
|
|
5070
|
+
// estimate rounds away: `baseMax` is physical and can exceed a calibrated estimate by
|
|
5071
|
+
// orders of magnitude, which a single division cannot walk back.
|
|
5072
|
+
let significantUnit = Math.pow(10, Math.round(Math.log10(Math.max((upper - lower) / 2, 1))));
|
|
5073
|
+
while (significantUnit > estimatedRecordCount && significantUnit > 1) significantUnit /= 10;
|
|
5074
|
+
recordCount = Math.min(
|
|
5075
|
+
Math.max(Math.round(estimatedRecordCount / significantUnit) * significantUnit, lower),
|
|
5076
|
+
upper
|
|
5077
|
+
);
|
|
4972
5078
|
return {
|
|
4973
5079
|
recordCount,
|
|
4974
|
-
estimatedRange: [
|
|
5080
|
+
estimatedRange: [lower, upper],
|
|
4975
5081
|
};
|
|
4976
5082
|
}
|
|
4977
5083
|
return {
|
|
@@ -6089,25 +6195,34 @@ export function makeTable(options) {
|
|
|
6089
6195
|
}
|
|
6090
6196
|
resolve(resolvedEntry);
|
|
6091
6197
|
} catch (error) {
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6198
|
+
// A source may reject with anything at all, so deciding how to settle is itself
|
|
6199
|
+
// fallible: `message` is not assignable on every error (a DOMException from
|
|
6200
|
+
// AbortSignal.timeout), and a nullish rejection makes the reads below throw.
|
|
6201
|
+
// Leaving this promise unsettled hangs the caller forever, so every path here
|
|
6202
|
+
// has to end in resolve() or reject().
|
|
6203
|
+
try {
|
|
6204
|
+
appendErrorContext(error, ` while resolving record ${id} for ${tableName}`);
|
|
6205
|
+
if (
|
|
6206
|
+
existingRecord &&
|
|
6207
|
+
(((error.code === 'ECONNRESET' || error.code === 'ECONNREFUSED' || error.code === 'EAI_AGAIN') &&
|
|
6208
|
+
!context?.mustRevalidate) ||
|
|
6209
|
+
(context?.staleIfError &&
|
|
6210
|
+
(error.statusCode === 500 ||
|
|
6211
|
+
error.statusCode === 502 ||
|
|
6212
|
+
error.statusCode === 503 ||
|
|
6213
|
+
error.statusCode === 504)))
|
|
6214
|
+
) {
|
|
6215
|
+
// these are conditions under which we can use stale data after an error
|
|
6216
|
+
resolve({
|
|
6217
|
+
key: id,
|
|
6218
|
+
version: existingVersion,
|
|
6219
|
+
value: existingRecord,
|
|
6220
|
+
} as any);
|
|
6221
|
+
logger.trace?.((error as Error)?.message, '(returned stale record)');
|
|
6222
|
+
} else reject(error);
|
|
6223
|
+
} catch (settlingError) {
|
|
6224
|
+
reject(error ?? settlingError);
|
|
6225
|
+
}
|
|
6111
6226
|
const resolveDuration = performance.now() - start;
|
|
6112
6227
|
recordAction(resolveDuration, 'cache-resolution', tableName, null, 'fail');
|
|
6113
6228
|
if (responseHeaders)
|