grepmax 0.26.41 → 0.26.42
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.
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "grepmax",
|
|
11
11
|
"source": "./plugins/grepmax",
|
|
12
12
|
"description": "Semantic code search for Claude Code. Automatically indexes your project and provides intelligent search capabilities.",
|
|
13
|
-
"version": "0.26.
|
|
13
|
+
"version": "0.26.42",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "Robert Owens",
|
|
16
16
|
"email": "robowens@me.com"
|
package/README.md
CHANGED
|
@@ -450,6 +450,8 @@ gmax watch restart # Restart daemon
|
|
|
450
450
|
|
|
451
451
|
`gmax doctor` reports ANN index state. `ANN: vector index not built` is normal with the default exact-search configuration.
|
|
452
452
|
|
|
453
|
+
Compaction pauses index writes, waits for pending writes to commit, and opens a fresh table snapshot for each attempt. Each optimize call makes at most two attempts. Before each attempt it checks current free space against twice the table's logical size plus the critical-space reserve (5 GB by default). If there is insufficient headroom, it skips the rewrite and logs the required space; search remains available. A successful prune can reclaim fragment copies left by failed attempts.
|
|
454
|
+
|
|
453
455
|
### Known issues
|
|
454
456
|
|
|
455
457
|
Some log output looks alarming but is expected and self-healing. Before filing a bug, check
|
|
@@ -188,6 +188,9 @@ const COMPACTION_MIN_INTERVAL_MS = 30 * 60 * 1000;
|
|
|
188
188
|
* so a store that cannot be improved stops paying for the attempt.
|
|
189
189
|
*/
|
|
190
190
|
const COMPACTION_MAX_INTERVAL_MS = 6 * 60 * 60 * 1000;
|
|
191
|
+
// Failed rewrites leave complete fragment copies until a later successful prune.
|
|
192
|
+
// One fresh-snapshot retry is enough; five attempts stranded ~70 GB in Oct 2026.
|
|
193
|
+
const COMPACTION_MAX_ATTEMPTS = 2;
|
|
191
194
|
/**
|
|
192
195
|
* Bounds for LanceDB's per-connection caches.
|
|
193
196
|
*
|
|
@@ -1083,7 +1086,7 @@ class VectorDB {
|
|
|
1083
1086
|
});
|
|
1084
1087
|
}
|
|
1085
1088
|
optimize() {
|
|
1086
|
-
return __awaiter(this, arguments, void 0, function* (retries =
|
|
1089
|
+
return __awaiter(this, arguments, void 0, function* (retries = COMPACTION_MAX_ATTEMPTS, retentionMs = 0, bypassExclusiveMutation = false) {
|
|
1087
1090
|
if (!bypassExclusiveMutation) {
|
|
1088
1091
|
while (this.exclusiveMutationPromise)
|
|
1089
1092
|
yield this.exclusiveMutationPromise;
|
|
@@ -1102,12 +1105,28 @@ class VectorDB {
|
|
|
1102
1105
|
});
|
|
1103
1106
|
this.activeCompactions++;
|
|
1104
1107
|
try {
|
|
1105
|
-
const
|
|
1106
|
-
const cutoff = new Date(Date.now() - retentionMs);
|
|
1108
|
+
const maxAttempts = Math.min(retries, COMPACTION_MAX_ATTEMPTS);
|
|
1107
1109
|
let rebuiltFts = false;
|
|
1108
|
-
for (let attempt = 1; attempt <=
|
|
1110
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1109
1111
|
yield this.drainWrites();
|
|
1110
1112
|
try {
|
|
1113
|
+
// Open AFTER outstanding writes commit, and reopen on every retry.
|
|
1114
|
+
// A handle opened before drainWrites carries the old snapshot even
|
|
1115
|
+
// though new writes are gated. Reusing it repeats the same conflict.
|
|
1116
|
+
const table = yield this.ensureTableUnsafe();
|
|
1117
|
+
const { totalBytes } = yield table.stats();
|
|
1118
|
+
if (!Number.isFinite(totalBytes) || totalBytes < 0) {
|
|
1119
|
+
throw new Error("Cannot estimate compaction size from table stats");
|
|
1120
|
+
}
|
|
1121
|
+
// Bypass the cached pressure check: a failed attempt can consume a
|
|
1122
|
+
// whole table within its 30s cache window. Budget two logical copies
|
|
1123
|
+
// for rewrite/index overhead, leaving the critical reserve untouched.
|
|
1124
|
+
const availableBytes = this.getAvailableBytes();
|
|
1125
|
+
const requiredBytes = totalBytes * 2 + config_1.DISK_CRITICAL_BYTES;
|
|
1126
|
+
if (availableBytes < requiredBytes) {
|
|
1127
|
+
(0, logger_1.log)("vectordb", `Optimize skipped: insufficient rewrite headroom (${(availableBytes / Math.pow(1024, 3)).toFixed(1)}GB free, ${(requiredBytes / Math.pow(1024, 3)).toFixed(1)}GB required)`);
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1111
1130
|
const done = (0, logger_1.timer)("vectordb", "optimize");
|
|
1112
1131
|
// deleteUnverified deletes files Lance cannot prove are unreferenced.
|
|
1113
1132
|
// LanceDB's own docs: only safe "if you can guarantee that no other
|
|
@@ -1119,7 +1138,8 @@ class VectorDB {
|
|
|
1119
1138
|
// Anything new that calls optimize() must preserve that: either be the
|
|
1120
1139
|
// daemon, or be the only process on the store.
|
|
1121
1140
|
const stats = yield table.optimize({
|
|
1122
|
-
|
|
1141
|
+
// Include fragment copies left by earlier failed attempts.
|
|
1142
|
+
cleanupOlderThan: new Date(Date.now() - retentionMs),
|
|
1123
1143
|
deleteUnverified: true,
|
|
1124
1144
|
});
|
|
1125
1145
|
done();
|
|
@@ -1150,10 +1170,10 @@ class VectorDB {
|
|
|
1150
1170
|
(0, logger_1.log)("vectordb", `Optimize failed (ENOSPC): disk full — skipping retries`);
|
|
1151
1171
|
return;
|
|
1152
1172
|
}
|
|
1153
|
-
if (attempt <
|
|
1173
|
+
if (attempt < maxAttempts &&
|
|
1154
1174
|
(msg.includes("conflict") || msg.includes("Retryable"))) {
|
|
1155
1175
|
const delay = 1000 * Math.pow(2, (attempt - 1));
|
|
1156
|
-
(0, logger_1.log)("vectordb", `Optimize conflict (attempt ${attempt}/${
|
|
1176
|
+
(0, logger_1.log)("vectordb", `Optimize conflict (attempt ${attempt}/${maxAttempts}), retrying with a fresh snapshot in ${delay}ms`);
|
|
1157
1177
|
yield new Promise((r) => setTimeout(r, delay));
|
|
1158
1178
|
continue;
|
|
1159
1179
|
}
|
|
@@ -1165,7 +1185,7 @@ class VectorDB {
|
|
|
1165
1185
|
// Unsafe variant: the public createFTSIndex waits on
|
|
1166
1186
|
// compactingPromise, which we hold.
|
|
1167
1187
|
if (msg.includes("Panic")) {
|
|
1168
|
-
if (attempt <
|
|
1188
|
+
if (attempt < maxAttempts &&
|
|
1169
1189
|
!rebuiltFts &&
|
|
1170
1190
|
!this.ftsPanicRecoveryExhausted) {
|
|
1171
1191
|
rebuiltFts = true;
|
package/package.json
CHANGED