mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
perf: add dirty persist and hydrate/layout optimizations
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
buildBmeDbName,
|
||||
buildGraphFromSnapshot,
|
||||
buildPersistDelta,
|
||||
buildPersistDeltaFromGraphDirtyState,
|
||||
buildSnapshotFromGraph,
|
||||
evaluateNativeHydrateGate,
|
||||
evaluatePersistNativeDeltaGate,
|
||||
@@ -83,13 +84,17 @@ import {
|
||||
getGraphStats,
|
||||
getNode,
|
||||
serializeGraph,
|
||||
updateNode,
|
||||
} from "../graph/graph.js";
|
||||
import {
|
||||
buildPersistedRecallRecord,
|
||||
readPersistedRecallFromUserMessage,
|
||||
} from "../retrieval/recall-persistence.js";
|
||||
import { getNodeDisplayName } from "../graph/node-labels.js";
|
||||
import { normalizeGraphRuntimeState } from "../runtime/runtime-state.js";
|
||||
import {
|
||||
normalizeGraphRuntimeState,
|
||||
pruneGraphPersistDirtyState,
|
||||
} from "../runtime/runtime-state.js";
|
||||
import {
|
||||
defaultSettings,
|
||||
getPersistedSettingsSnapshot,
|
||||
@@ -1032,9 +1037,11 @@ async function createGraphPersistenceHarness({
|
||||
__contextImmediateSaveCalls: 0,
|
||||
buildGraphFromSnapshot,
|
||||
buildPersistDelta,
|
||||
buildPersistDeltaFromGraphDirtyState,
|
||||
buildSnapshotFromGraph,
|
||||
evaluateNativeHydrateGate,
|
||||
evaluatePersistNativeDeltaGate,
|
||||
pruneGraphPersistDirtyState,
|
||||
buildBmeDbName,
|
||||
BME_GRAPH_LOCAL_STORAGE_MODE_AUTO: "auto",
|
||||
BME_GRAPH_LOCAL_STORAGE_MODE_INDEXEDDB: "indexeddb",
|
||||
@@ -3303,6 +3310,58 @@ result = {
|
||||
assert.equal(harness.api.getIndexedDbSnapshot()?.meta?.revision, 8);
|
||||
}
|
||||
|
||||
{
|
||||
const chatId = "chat-idb-dirty-runtime-fast-path";
|
||||
const baseGraph = createMeaningfulGraph(chatId, "dirty-runtime-base");
|
||||
const runtimeGraph = cloneGraphForPersistence(baseGraph, chatId);
|
||||
updateNode(runtimeGraph, runtimeGraph.nodes[0]?.id, {
|
||||
importance: Number(runtimeGraph.nodes[0]?.importance || 0) + 2,
|
||||
});
|
||||
const baseSnapshot = buildSnapshotFromGraph(baseGraph, {
|
||||
chatId,
|
||||
revision: 7,
|
||||
});
|
||||
const harness = await createGraphPersistenceHarness({
|
||||
chatId,
|
||||
globalChatId: chatId,
|
||||
chatMetadata: {
|
||||
integrity: "meta-idb-dirty-runtime-fast-path",
|
||||
},
|
||||
indexedDbSnapshot: baseSnapshot,
|
||||
});
|
||||
harness.api.setCurrentGraph(runtimeGraph);
|
||||
harness.api.setGraphPersistenceState({
|
||||
loadState: "loaded",
|
||||
chatId,
|
||||
revision: 8,
|
||||
lastPersistedRevision: 0,
|
||||
writesBlocked: false,
|
||||
});
|
||||
|
||||
const originalBuildSnapshotFromGraph = harness.runtimeContext.buildSnapshotFromGraph;
|
||||
let buildSnapshotCallCount = 0;
|
||||
harness.runtimeContext.buildSnapshotFromGraph = (...args) => {
|
||||
buildSnapshotCallCount += 1;
|
||||
return originalBuildSnapshotFromGraph(...args);
|
||||
};
|
||||
|
||||
const result = await harness.api.saveGraphToIndexedDb(chatId, runtimeGraph, {
|
||||
revision: 8,
|
||||
reason: "dirty-runtime-fast-path-save",
|
||||
scheduleCloudUpload: false,
|
||||
sourceGraph: runtimeGraph,
|
||||
});
|
||||
|
||||
assert.equal(result.saved, true);
|
||||
assert.equal(
|
||||
buildSnapshotCallCount,
|
||||
0,
|
||||
"dirty-set 命中时 saveGraphToIndexedDb 不应退回 full snapshot build",
|
||||
);
|
||||
assert.equal(result.snapshot?.meta?.revision, 8);
|
||||
assert.equal(harness.api.getIndexedDbSnapshot()?.meta?.revision, 8);
|
||||
}
|
||||
|
||||
{
|
||||
const chatId = "chat-indexeddb-probe-empty-early-return";
|
||||
const persistedSnapshot = {
|
||||
|
||||
@@ -95,6 +95,8 @@ function resolveCurrentChatIdentity() {
|
||||
}
|
||||
function readCachedIndexedDbSnapshot() { return null; }
|
||||
function resolvePersistRevisionFloor(revision = 0) { return Number(revision) || 1; }
|
||||
function buildPersistDeltaFromGraphDirtyState() { return null; }
|
||||
function pruneGraphPersistDirtyState() { return null; }
|
||||
function buildSnapshotFromGraph(graph, options = {}) {
|
||||
return {
|
||||
meta: {
|
||||
|
||||
@@ -171,6 +171,45 @@ rebuilt.nodes[0].embedding[0] = 99;
|
||||
assert.equal(snapshot.nodes[0].fields.title, "Native Node");
|
||||
assert.equal(snapshot.nodes[0].embedding[0], 1);
|
||||
|
||||
globalThis.__stBmeNativeHydrateSnapshotRecords = (snapshotView = {}, options = {}) => {
|
||||
assert.equal(options.recordsNormalized, true);
|
||||
return {
|
||||
ok: true,
|
||||
usedNative: true,
|
||||
nodesJson: JSON.stringify(
|
||||
cloneValue(snapshotView.nodes).map((node) => ({
|
||||
...node,
|
||||
compactHydrated: true,
|
||||
})),
|
||||
),
|
||||
edgesJson: JSON.stringify(
|
||||
cloneValue(snapshotView.edges).map((edge) => ({
|
||||
...edge,
|
||||
compactHydrated: true,
|
||||
})),
|
||||
),
|
||||
diagnostics: {
|
||||
solver: "test-native-hydrate-compact",
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
let compactDiagnostics = null;
|
||||
const compactGraph = buildGraphFromSnapshot(snapshot, {
|
||||
chatId: "chat-native-hydrate",
|
||||
useNativeHydrate: true,
|
||||
minSnapshotRecords: 0,
|
||||
onDiagnostics(snapshotValue) {
|
||||
compactDiagnostics = snapshotValue;
|
||||
},
|
||||
});
|
||||
assert.equal(compactGraph.nodes[0].compactHydrated, true);
|
||||
assert.equal(compactGraph.edges[0].compactHydrated, true);
|
||||
assert.equal(
|
||||
compactDiagnostics.nativeModuleDiagnostics?.hydrateBridgeMode,
|
||||
"compact-json",
|
||||
);
|
||||
|
||||
delete globalThis.__stBmeNativeHydrateSnapshotRecords;
|
||||
|
||||
let fallbackDiagnostics = null;
|
||||
|
||||
Reference in New Issue
Block a user