File size: 7,219 Bytes
bcbb712
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// ===== KIMI MEMORY DATABASE OPTIMIZATION SUGGESTIONS =====

/**

 * Performance Optimization Guide for Kimi Memory System

 *

 * This file contains recommendations for database schema optimizations

 * to improve query performance in the memory system.

 */

// RECOMMENDED DEXIE INDEX CONFIGURATION
// Add these indexes to your database schema for optimal performance

const RECOMMENDED_MEMORY_INDEXES = {
    // Current schema (for reference)
    current: "++id, character, category, type, timestamp, isActive, confidence, importance, keywords",

    // OPTIMIZED schema with composite indexes
    optimized: [
        "++id", // Primary key (auto-increment)

        // Single field indexes (existing)
        "character",
        "category",
        "type",
        "timestamp",
        "isActive",
        "confidence",
        "importance",
        "*keywords", // Multi-entry index for keyword array

        // COMPOSITE INDEXES for frequent query patterns
        "[character+isActive]", // Filter by character and active status
        "[character+category]", // Get memories by character and category
        "[character+category+isActive]", // Most common query pattern
        "[character+timestamp]", // Chronological queries by character
        "[isActive+importance]", // Get active memories by importance
        "[isActive+timestamp]", // Recent active memories
        "[character+type+isActive]", // Filter by character, type, and status

        // Advanced composite indexes for complex queries
        "[character+isActive+importance]", // Prioritized active memories by character
        "[character+category+timestamp]" // Category-specific chronological queries
    ]
};

// QUERY OPTIMIZATION EXAMPLES
const OPTIMIZED_QUERY_PATTERNS = {
    // BEFORE: Multiple filter operations
    getAllMemoriesOld: `

        db.memories

            .where("character").equals(character)

            .filter(m => m.isActive !== false)

            .reverse()

            .sortBy("timestamp")

    `,

    // AFTER: Use composite index
    getAllMemoriesOptimized: `

        db.memories

            .where("[character+isActive]").equals([character, true])

            .reverse()

            .sortBy("timestamp")

    `,

    // BEFORE: Filter after retrieval
    getMemoriesByCategoryOld: `

        db.memories

            .where("[character+category]").equals([character, category])

            .and(m => m.isActive)

    `,

    // AFTER: Direct composite index
    getMemoriesByCategoryOptimized: `

        db.memories

            .where("[character+category+isActive]").equals([character, category, true])

    `,

    // NEW: Efficient importance-based queries
    getTopMemoriesByImportance: `

        db.memories

            .where("[character+isActive+importance]")

            .between([character, true, 0.8], [character, true, 1.0])

            .reverse()

            .limit(10)

    `
};

// PERFORMANCE MONITORING UTILITIES
class MemoryDatabaseProfiler {
    constructor() {
        this.queryTimes = new Map();
        this.queryCount = new Map();
    }

    // Wrap database operations to measure performance
    async profileQuery(queryName, queryFn) {
        const start = performance.now();
        const result = await queryFn();
        const duration = performance.now() - start;

        // Update statistics
        if (!this.queryTimes.has(queryName)) {
            this.queryTimes.set(queryName, []);
            this.queryCount.set(queryName, 0);
        }

        this.queryTimes.get(queryName).push(duration);
        this.queryCount.set(queryName, this.queryCount.get(queryName) + 1);

        // Log slow queries
        if (duration > 50) {
            // 50ms threshold
            console.warn(`🐌 Slow query detected: ${queryName} took ${duration.toFixed(2)}ms`);
        }

        return result;
    }

    // Get performance statistics
    getStats() {
        const stats = {};

        for (const [queryName, times] of this.queryTimes.entries()) {
            const count = this.queryCount.get(queryName);
            const avgTime = times.reduce((sum, time) => sum + time, 0) / times.length;
            const maxTime = Math.max(...times);
            const minTime = Math.min(...times);

            stats[queryName] = {
                count,
                avgTime: Math.round(avgTime * 100) / 100,
                maxTime: Math.round(maxTime * 100) / 100,
                minTime: Math.round(minTime * 100) / 100,
                totalTime: Math.round(times.reduce((sum, time) => sum + time, 0) * 100) / 100
            };
        }

        return stats;
    }

    // Reset statistics
    reset() {
        this.queryTimes.clear();
        this.queryCount.clear();
    }
}

// MEMORY USAGE OPTIMIZATION
const MEMORY_CLEANUP_STRATEGIES = {
    // Strategy 1: Batch cleanup operations
    batchCleanup: async (db, maxBatchSize = 100) => {
        const oldMemories = await db.memories.where("isActive").equals(false).limit(maxBatchSize).toArray();

        if (oldMemories.length > 0) {
            await db.memories.bulkDelete(oldMemories.map(m => m.id));
            console.log(`🧹 Batch deleted ${oldMemories.length} inactive memories`);
        }
    },

    // Strategy 2: Incremental keyword cleanup
    cleanupKeywords: async db => {
        const memoriesWithEmptyKeywords = await db.memories
            .filter(m => !m.keywords || m.keywords.length === 0)
            .limit(50)
            .toArray();

        for (const memory of memoriesWithEmptyKeywords) {
            const keywords = deriveKeywords(memory.content || "");
            await db.memories.update(memory.id, { keywords });
        }
    },

    // Strategy 3: Compress old memories
    compressOldMemories: async (db, daysThreshold = 90) => {
        const cutoff = new Date();
        cutoff.setDate(cutoff.getDate() - daysThreshold);

        const oldMemories = await db.memories
            .where("timestamp")
            .below(cutoff)
            .and(m => m.isActive && !m.compressed)
            .limit(20)
            .toArray();

        for (const memory of oldMemories) {
            // Compress by removing redundant fields and shortening content
            const compressed = {
                compressed: true,
                originalLength: memory.content?.length || 0,
                content: memory.content?.substring(0, 100) + "...",
                // Remove non-essential fields
                sourceText: undefined,
                tags: memory.tags?.slice(0, 3) // Keep only top 3 tags
            };

            await db.memories.update(memory.id, compressed);
        }
    }
};

// EXPORT UTILITIES
if (typeof window !== "undefined") {
    window.KIMI_MEMORY_DB_OPTIMIZATION = {
        RECOMMENDED_MEMORY_INDEXES,
        OPTIMIZED_QUERY_PATTERNS,
        MemoryDatabaseProfiler,
        MEMORY_CLEANUP_STRATEGIES
    };
}

export { RECOMMENDED_MEMORY_INDEXES, OPTIMIZED_QUERY_PATTERNS, MemoryDatabaseProfiler, MEMORY_CLEANUP_STRATEGIES };