fix: remove repeated full-table scans from knowledge and activity paths
Binding checks loaded and parsed every external knowledge binding to answer a single-row question. requireLibrary did this on more than thirty call sites including one inside a task reconciliation loop, and the knowledge snapshot scanned the table twice per library across its seven callers. Add keyed store lookups (getBinding, hasBinding, getBindingsForInstance) that use the existing primary key, build the snapshot's bindings once into a Map, and count bindings per instance in a single pass. Memoize the conversation activity index in the renderer. It was rebuilt on every render, including once per streaming token, which discarded half the benefit of the memoized activity summary directly above it. Release note: 知识库页面、对话预检索和跨项目活动列表在绑定较多时响应更快,流式回答期间的 界面开销降低。
This commit is contained in:
+7
-2
@@ -992,10 +992,15 @@ function getKnowledgeSnapshot(
|
||||
])
|
||||
}
|
||||
}
|
||||
const bindingsByLibraryId = new Map(
|
||||
service.database.externalStore
|
||||
.listBindings()
|
||||
.map((binding) => [binding.knowledgeBaseId, binding])
|
||||
)
|
||||
return {
|
||||
libraries: snapshot.libraries.map((library) => ({
|
||||
kind: service.database.externalStore.listBindings().some(item=>item.knowledgeBaseId===library.id) ? 'external' : 'local',
|
||||
external: service.database.externalStore.listBindings().find(item=>item.knowledgeBaseId===library.id),
|
||||
kind: bindingsByLibraryId.has(library.id) ? 'external' : 'local',
|
||||
external: bindingsByLibraryId.get(library.id),
|
||||
id: library.id,
|
||||
name: library.name,
|
||||
description: library.description ?? '',
|
||||
|
||||
@@ -19,6 +19,16 @@ export class ExternalKnowledgeStore {
|
||||
deleteInstance(id: string): void {
|
||||
this.database.prepare('DELETE FROM external_knowledge_instances WHERE id=?').run(id)
|
||||
}
|
||||
getBinding(knowledgeBaseId: string): ExternalKnowledgeBinding | undefined {
|
||||
const row = this.database.prepare('SELECT value_json FROM external_knowledge_bindings WHERE knowledge_base_id=?').get(knowledgeBaseId)
|
||||
return row ? JSON.parse(String(row.value_json)) as ExternalKnowledgeBinding : undefined
|
||||
}
|
||||
hasBinding(knowledgeBaseId: string): boolean {
|
||||
return this.database.prepare('SELECT 1 FROM external_knowledge_bindings WHERE knowledge_base_id=?').get(knowledgeBaseId) !== undefined
|
||||
}
|
||||
getBindingsForInstance(instanceId: string): ExternalKnowledgeBinding[] {
|
||||
return this.database.prepare('SELECT value_json FROM external_knowledge_bindings WHERE instance_id=? ORDER BY rowid').all(instanceId).map(row => JSON.parse(String(row.value_json)) as ExternalKnowledgeBinding)
|
||||
}
|
||||
listBindings(): ExternalKnowledgeBinding[] {
|
||||
return this.database.prepare('SELECT value_json FROM external_knowledge_bindings ORDER BY rowid').all().map(row => JSON.parse(String(row.value_json)) as ExternalKnowledgeBinding)
|
||||
}
|
||||
|
||||
@@ -926,7 +926,7 @@ export class KnowledgeDatabase {
|
||||
input: UpdateKnowledgeBaseInput
|
||||
): KnowledgeBase {
|
||||
const current = this.requiredKnowledgeBase(id)
|
||||
if (this.externalStore.listBindings().some(item => item.knowledgeBaseId === id) &&
|
||||
if (this.externalStore.hasBinding(id) &&
|
||||
(input.graphEnabled !== undefined || input.graphStrategy !== undefined || input.storageMode !== undefined)) {
|
||||
throw new Error('EXTERNAL_KB_READ_ONLY')
|
||||
}
|
||||
|
||||
@@ -3791,8 +3791,15 @@ function App(): React.JSX.Element {
|
||||
[conversations, conversationTitles, assistantTasks, activeConversationIds,
|
||||
projects, projectNames, tWorkspace],
|
||||
);
|
||||
const activityByConversationId = new Map(
|
||||
projectActivity.activities.map((activity) => [activity.conversationId, activity]),
|
||||
const activityByConversationId = useMemo(
|
||||
() =>
|
||||
new Map(
|
||||
projectActivity.activities.map((activity) => [
|
||||
activity.conversationId,
|
||||
activity,
|
||||
]),
|
||||
),
|
||||
[projectActivity],
|
||||
);
|
||||
const pendingSidebarApprovals = useMemo<PendingSidebarApproval[]>(
|
||||
() =>
|
||||
|
||||
Reference in New Issue
Block a user