grepmax 0.26.53 → 0.26.54
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.54",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "Robert Owens",
|
|
16
16
|
"email": "robowens@me.com"
|
|
@@ -47,6 +47,9 @@ exports.compactionSchema = zod_1.z.object({
|
|
|
47
47
|
freeBytesBefore: zod_1.z.number().optional(),
|
|
48
48
|
freeBytesAfter: zod_1.z.number().optional(),
|
|
49
49
|
bytesReclaimed: zod_1.z.number().optional(),
|
|
50
|
+
netBytesReclaimed: zod_1.z.number().optional(),
|
|
51
|
+
cleanupPasses: zod_1.z.number().int().min(0).max(1).optional(),
|
|
52
|
+
cleanupReason: zod_1.z.string().optional(),
|
|
50
53
|
});
|
|
51
54
|
const embedding = zod_1.z.object({
|
|
52
55
|
tier: zod_1.z.string(),
|
|
@@ -1108,9 +1108,80 @@ class VectorDB {
|
|
|
1108
1108
|
(0, logger_1.log)("vectordb", `Compaction result: ${JSON.stringify(result)}`);
|
|
1109
1109
|
return Object.assign({}, result);
|
|
1110
1110
|
}
|
|
1111
|
+
/** Prune the reserve-ID snapshot without another data rewrite. Caller holds
|
|
1112
|
+
* compactingPromise and has drained writes; never use this for retention > 0.
|
|
1113
|
+
* Lance 12 treats one deletion-free fragment as a compaction no-op. */
|
|
1114
|
+
cleanupCompactionReservation(table) {
|
|
1115
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1116
|
+
var _a;
|
|
1117
|
+
let passes = 0;
|
|
1118
|
+
const deferred = (reason) => ({
|
|
1119
|
+
passes: 0,
|
|
1120
|
+
bytesRemoved: 0,
|
|
1121
|
+
reason,
|
|
1122
|
+
});
|
|
1123
|
+
try {
|
|
1124
|
+
const stats = yield table.stats();
|
|
1125
|
+
if (((_a = stats.fragmentStats) === null || _a === void 0 ? void 0 : _a.numFragments) !== 1) {
|
|
1126
|
+
return deferred("cleanup deferred: table is not a single fragment");
|
|
1127
|
+
}
|
|
1128
|
+
const version = yield table.version();
|
|
1129
|
+
const fresh = yield this.openExistingTableUnsafe();
|
|
1130
|
+
if (!fresh || (yield fresh.version()) !== version) {
|
|
1131
|
+
return deferred("cleanup deferred: table changed after compaction");
|
|
1132
|
+
}
|
|
1133
|
+
const latest = (yield fresh.listVersions()).find((v) => v.version === version);
|
|
1134
|
+
if ((latest === null || latest === void 0 ? void 0 : latest.metadata.total_fragments) !== "1" ||
|
|
1135
|
+
latest.metadata.total_deletion_files !== "0" ||
|
|
1136
|
+
latest.metadata.total_deletion_file_rows !== "0") {
|
|
1137
|
+
return deferred("cleanup deferred: deletion-free fragment not verified");
|
|
1138
|
+
}
|
|
1139
|
+
// Manifest timestamps have sub-ms precision; wait for a real later tick,
|
|
1140
|
+
// never invent a future cutoff. No gmax writes can enter while gated.
|
|
1141
|
+
yield new Promise((resolve) => setTimeout(resolve, 1));
|
|
1142
|
+
const cutoff = new Date();
|
|
1143
|
+
if (!Number.isFinite(latest.timestamp.getTime()) ||
|
|
1144
|
+
cutoff.getTime() <= latest.timestamp.getTime()) {
|
|
1145
|
+
return deferred("cleanup deferred: clock has not passed the commit");
|
|
1146
|
+
}
|
|
1147
|
+
const freeBytes = this.getAvailableBytes();
|
|
1148
|
+
const requiredBytes = stats.totalBytes * 2 + config_1.DISK_CRITICAL_BYTES;
|
|
1149
|
+
if (!Number.isFinite(stats.totalBytes) ||
|
|
1150
|
+
stats.totalBytes < 0 ||
|
|
1151
|
+
freeBytes < requiredBytes) {
|
|
1152
|
+
return deferred("cleanup deferred: insufficient rewrite headroom");
|
|
1153
|
+
}
|
|
1154
|
+
(0, logger_1.log)("vectordb", `Compaction cleanup attempt: ${JSON.stringify({ version, cutoff: cutoff.getTime(), freeBytes, requiredBytes })}`);
|
|
1155
|
+
passes = 1;
|
|
1156
|
+
const result = yield fresh.optimize({
|
|
1157
|
+
cleanupOlderThan: cutoff,
|
|
1158
|
+
deleteUnverified: true,
|
|
1159
|
+
});
|
|
1160
|
+
if (result.compaction.fragmentsRemoved !== 0 ||
|
|
1161
|
+
result.compaction.fragmentsAdded !== 0) {
|
|
1162
|
+
return {
|
|
1163
|
+
passes,
|
|
1164
|
+
bytesRemoved: result.prune.bytesRemoved,
|
|
1165
|
+
failed: true,
|
|
1166
|
+
reason: "cleanup unexpectedly rewrote data; no retry",
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
return { passes, bytesRemoved: result.prune.bytesRemoved };
|
|
1170
|
+
}
|
|
1171
|
+
catch (error) {
|
|
1172
|
+
return {
|
|
1173
|
+
passes,
|
|
1174
|
+
bytesRemoved: 0,
|
|
1175
|
+
failed: true,
|
|
1176
|
+
reason: `cleanup failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
});
|
|
1180
|
+
}
|
|
1111
1181
|
optimize() {
|
|
1112
1182
|
return __awaiter(this, arguments, void 0, function* (retries = COMPACTION_MAX_ATTEMPTS, retentionMs = 0, bypassExclusiveMutation = false) {
|
|
1113
1183
|
var _a;
|
|
1184
|
+
var _b;
|
|
1114
1185
|
if (!bypassExclusiveMutation) {
|
|
1115
1186
|
while (this.exclusiveMutationPromise)
|
|
1116
1187
|
yield this.exclusiveMutationPromise;
|
|
@@ -1120,7 +1191,7 @@ class VectorDB {
|
|
|
1120
1191
|
if (this.compactingPromise) {
|
|
1121
1192
|
(0, logger_1.debug)("vectordb", "Optimize already in progress, skipping");
|
|
1122
1193
|
yield this.compactingPromise;
|
|
1123
|
-
return ((
|
|
1194
|
+
return ((_b = this.compactionStatus()) !== null && _b !== void 0 ? _b : (0, compaction_result_1.skippedCompaction)("compaction unavailable"));
|
|
1124
1195
|
}
|
|
1125
1196
|
this.lastOptimizeDidWork = false;
|
|
1126
1197
|
let resolveCompacting;
|
|
@@ -1133,7 +1204,10 @@ class VectorDB {
|
|
|
1133
1204
|
let logicalBytes;
|
|
1134
1205
|
let diskBytesBefore;
|
|
1135
1206
|
let freeBytesBefore;
|
|
1207
|
+
let cleanupPasses = 0;
|
|
1208
|
+
let cleanupReason;
|
|
1136
1209
|
const finish = (status, reason, bytesReclaimed) => {
|
|
1210
|
+
const diskBytesAfter = this.getDirectorySize(this.lancedbDir);
|
|
1137
1211
|
const result = {
|
|
1138
1212
|
status,
|
|
1139
1213
|
at: Date.now(),
|
|
@@ -1143,9 +1217,14 @@ class VectorDB {
|
|
|
1143
1217
|
logicalBytes,
|
|
1144
1218
|
diskBytesBefore,
|
|
1145
1219
|
freeBytesBefore,
|
|
1146
|
-
diskBytesAfter
|
|
1220
|
+
diskBytesAfter,
|
|
1147
1221
|
freeBytesAfter: this.getAvailableBytes(),
|
|
1148
1222
|
bytesReclaimed,
|
|
1223
|
+
netBytesReclaimed: diskBytesBefore === undefined
|
|
1224
|
+
? undefined
|
|
1225
|
+
: diskBytesBefore - diskBytesAfter,
|
|
1226
|
+
cleanupPasses,
|
|
1227
|
+
cleanupReason,
|
|
1149
1228
|
};
|
|
1150
1229
|
this.lastCompactionResult = result;
|
|
1151
1230
|
(0, logger_1.log)("vectordb", `Compaction result: ${JSON.stringify(result)}`);
|
|
@@ -1210,7 +1289,18 @@ class VectorDB {
|
|
|
1210
1289
|
else {
|
|
1211
1290
|
(0, logger_1.debug)("vectordb", "Optimize: nothing to compact or prune");
|
|
1212
1291
|
}
|
|
1213
|
-
|
|
1292
|
+
let bytesReclaimed = prune.bytesRemoved;
|
|
1293
|
+
if (retentionMs === 0 && compaction.fragmentsRemoved > 0) {
|
|
1294
|
+
const cleanup = yield this.cleanupCompactionReservation(table);
|
|
1295
|
+
cleanupPasses = cleanup.passes;
|
|
1296
|
+
cleanupReason = (_a = cleanup.reason) === null || _a === void 0 ? void 0 : _a.replace(/[\r\n\t]/g, " ").slice(0, 512);
|
|
1297
|
+
bytesReclaimed += cleanup.bytesRemoved;
|
|
1298
|
+
this.lastOptimizeDidWork || (this.lastOptimizeDidWork = cleanup.bytesRemoved > 0);
|
|
1299
|
+
(0, logger_1.log)("vectordb", `Compaction cleanup result: ${JSON.stringify(Object.assign(Object.assign({}, cleanup), { reason: cleanupReason }))}`);
|
|
1300
|
+
if (cleanup.failed)
|
|
1301
|
+
return finish("failed", cleanupReason, bytesReclaimed);
|
|
1302
|
+
}
|
|
1303
|
+
return finish("completed", undefined, bytesReclaimed);
|
|
1214
1304
|
}
|
|
1215
1305
|
catch (e) {
|
|
1216
1306
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -1337,7 +1427,7 @@ class VectorDB {
|
|
|
1337
1427
|
// call, so a productive first pass followed by a barren bloat retry would
|
|
1338
1428
|
// otherwise read as unproductive and trigger a spurious backoff.
|
|
1339
1429
|
let didWork = this.lastOptimizeDidWork;
|
|
1340
|
-
if (this.lastOptimizeDidWork) {
|
|
1430
|
+
if (result.status === "completed" && this.lastOptimizeDidWork) {
|
|
1341
1431
|
const table = yield this.openExistingTableUnsafe();
|
|
1342
1432
|
if (table) {
|
|
1343
1433
|
// Collect abandoned scratch files before measuring. They are pure
|
|
@@ -72,6 +72,12 @@ function formatDoctorOptimize(report, agent) {
|
|
|
72
72
|
...(typeof (r === null || r === void 0 ? void 0 : r.bytesReclaimed) === "number"
|
|
73
73
|
? [`bytes_reclaimed=${r.bytesReclaimed}`]
|
|
74
74
|
: []),
|
|
75
|
+
...(typeof (r === null || r === void 0 ? void 0 : r.netBytesReclaimed) === "number"
|
|
76
|
+
? [`net_bytes_reclaimed=${r.netBytesReclaimed}`]
|
|
77
|
+
: []),
|
|
78
|
+
...(typeof (r === null || r === void 0 ? void 0 : r.cleanupPasses) === "number"
|
|
79
|
+
? [`cleanup_passes=${r.cleanupPasses}`]
|
|
80
|
+
: []),
|
|
75
81
|
...(reason ? [`reason=${reason}`] : []),
|
|
76
82
|
].join("\t");
|
|
77
83
|
}
|
package/package.json
CHANGED