mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-27 13:34:15 -07:00
Remove LRUCache class migrating to mnemoist (#16872)
This commit is contained in:
@@ -10,6 +10,7 @@ import os from 'node:os';
|
|||||||
import pathMod from 'node:path';
|
import pathMod from 'node:path';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
import { useState, useCallback, useEffect, useMemo, useReducer } from 'react';
|
import { useState, useCallback, useEffect, useMemo, useReducer } from 'react';
|
||||||
|
import { LRUCache } from 'mnemonist';
|
||||||
import {
|
import {
|
||||||
coreEvents,
|
coreEvents,
|
||||||
CoreEvent,
|
CoreEvent,
|
||||||
@@ -18,7 +19,6 @@ import {
|
|||||||
type EditorType,
|
type EditorType,
|
||||||
getEditorCommand,
|
getEditorCommand,
|
||||||
isGuiEditor,
|
isGuiEditor,
|
||||||
LruCache,
|
|
||||||
} from '@google/gemini-cli-core';
|
} from '@google/gemini-cli-core';
|
||||||
import {
|
import {
|
||||||
toCodePoints,
|
toCodePoints,
|
||||||
@@ -728,7 +728,7 @@ export function getTransformedImagePath(filePath: string): string {
|
|||||||
return `[Image ${truncatedBase}${extension}]`;
|
return `[Image ${truncatedBase}${extension}]`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const transformationsCache = new LruCache<string, Transformation[]>(
|
const transformationsCache = new LRUCache<string, Transformation[]>(
|
||||||
LRU_BUFFER_PERF_CACHE_LIMIT,
|
LRU_BUFFER_PERF_CACHE_LIMIT,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -881,7 +881,7 @@ interface LineLayoutResult {
|
|||||||
visualToTransformedMap: number[];
|
visualToTransformedMap: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const lineLayoutCache = new LruCache<string, LineLayoutResult>(
|
const lineLayoutCache = new LRUCache<string, LineLayoutResult>(
|
||||||
LRU_BUFFER_PERF_CACHE_LIMIT,
|
LRU_BUFFER_PERF_CACHE_LIMIT,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { LruCache } from '@google/gemini-cli-core';
|
import { LRUCache } from 'mnemonist';
|
||||||
import type { Transformation } from '../components/shared/text-buffer.js';
|
import type { Transformation } from '../components/shared/text-buffer.js';
|
||||||
import { cpLen, cpSlice } from './textUtils.js';
|
import { cpLen, cpSlice } from './textUtils.js';
|
||||||
import { LRU_BUFFER_PERF_CACHE_LIMIT } from '../constants.js';
|
import { LRU_BUFFER_PERF_CACHE_LIMIT } from '../constants.js';
|
||||||
@@ -20,7 +20,7 @@ export type HighlightToken = {
|
|||||||
// semicolon, common punctuation, and brackets.
|
// semicolon, common punctuation, and brackets.
|
||||||
const HIGHLIGHT_REGEX = /(^\/[a-zA-Z0-9_-]+|@(?:\\ |[^,\s;!?()[\]{}])+)/g;
|
const HIGHLIGHT_REGEX = /(^\/[a-zA-Z0-9_-]+|@(?:\\ |[^,\s;!?()[\]{}])+)/g;
|
||||||
|
|
||||||
const highlightCache = new LruCache<string, readonly HighlightToken[]>(
|
const highlightCache = new LRUCache<string, readonly HighlightToken[]>(
|
||||||
LRU_BUFFER_PERF_CACHE_LIMIT,
|
LRU_BUFFER_PERF_CACHE_LIMIT,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import stripAnsi from 'strip-ansi';
|
|||||||
import ansiRegex from 'ansi-regex';
|
import ansiRegex from 'ansi-regex';
|
||||||
import { stripVTControlCharacters } from 'node:util';
|
import { stripVTControlCharacters } from 'node:util';
|
||||||
import stringWidth from 'string-width';
|
import stringWidth from 'string-width';
|
||||||
import { LruCache } from '@google/gemini-cli-core';
|
import { LRUCache } from 'mnemonist';
|
||||||
import { LRU_BUFFER_PERF_CACHE_LIMIT } from '../constants.js';
|
import { LRU_BUFFER_PERF_CACHE_LIMIT } from '../constants.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,7 +32,7 @@ export const getAsciiArtWidth = (asciiArt: string): number => {
|
|||||||
|
|
||||||
// Cache for code points
|
// Cache for code points
|
||||||
const MAX_STRING_LENGTH_TO_CACHE = 1000;
|
const MAX_STRING_LENGTH_TO_CACHE = 1000;
|
||||||
const codePointsCache = new LruCache<string, string[]>(
|
const codePointsCache = new LRUCache<string, string[]>(
|
||||||
LRU_BUFFER_PERF_CACHE_LIMIT,
|
LRU_BUFFER_PERF_CACHE_LIMIT,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ export function stripUnsafeCharacters(str: string): string {
|
|||||||
.join('');
|
.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
const stringWidthCache = new LruCache<string, number>(
|
const stringWidthCache = new LRUCache<string, number>(
|
||||||
LRU_BUFFER_PERF_CACHE_LIMIT,
|
LRU_BUFFER_PERF_CACHE_LIMIT,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,6 @@ export * from './utils/version.js';
|
|||||||
export * from './utils/checkpointUtils.js';
|
export * from './utils/checkpointUtils.js';
|
||||||
export * from './utils/apiConversionUtils.js';
|
export * from './utils/apiConversionUtils.js';
|
||||||
export * from './utils/channel.js';
|
export * from './utils/channel.js';
|
||||||
export * from './utils/LruCache.js';
|
|
||||||
|
|
||||||
// Export services
|
// Export services
|
||||||
export * from './services/fileDiscoveryService.js';
|
export * from './services/fileDiscoveryService.js';
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2025 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { describe, it, expect } from 'vitest';
|
|
||||||
import { LruCache } from './LruCache.js';
|
|
||||||
|
|
||||||
describe('LruCache', () => {
|
|
||||||
it('should store and retrieve values', () => {
|
|
||||||
const cache = new LruCache<string, number>(10);
|
|
||||||
cache.set('a', 1);
|
|
||||||
expect(cache.get('a')).toBe(1);
|
|
||||||
expect(cache.get('b')).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should evict oldest items when limit is reached', () => {
|
|
||||||
const cache = new LruCache<string, number>(2);
|
|
||||||
cache.set('a', 1);
|
|
||||||
cache.set('b', 2);
|
|
||||||
cache.set('c', 3);
|
|
||||||
|
|
||||||
expect(cache.get('a')).toBeUndefined();
|
|
||||||
expect(cache.get('b')).toBe(2);
|
|
||||||
expect(cache.get('c')).toBe(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update LRU order on get', () => {
|
|
||||||
const cache = new LruCache<string, number>(2);
|
|
||||||
cache.set('a', 1);
|
|
||||||
cache.set('b', 2);
|
|
||||||
cache.get('a'); // Mark 'a' as recently used
|
|
||||||
cache.set('c', 3); // Should evict 'b'
|
|
||||||
|
|
||||||
expect(cache.get('b')).toBeUndefined();
|
|
||||||
expect(cache.get('a')).toBe(1);
|
|
||||||
expect(cache.get('c')).toBe(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly handle falsy values (truthiness bug fix)', () => {
|
|
||||||
const cache = new LruCache<string, unknown>(2);
|
|
||||||
cache.set('zero', 0);
|
|
||||||
cache.set('empty', '');
|
|
||||||
|
|
||||||
// Both should be in cache
|
|
||||||
expect(cache.get('zero')).toBe(0);
|
|
||||||
expect(cache.get('empty')).toBe('');
|
|
||||||
|
|
||||||
// Access 'zero' to move it to end
|
|
||||||
cache.get('zero');
|
|
||||||
|
|
||||||
// Add new item, should evict 'empty' (because 'zero' was just accessed)
|
|
||||||
cache.set('new', 'item');
|
|
||||||
|
|
||||||
expect(cache.get('empty')).toBeUndefined();
|
|
||||||
expect(cache.get('zero')).toBe(0);
|
|
||||||
expect(cache.get('new')).toBe('item');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly handle undefined as a value', () => {
|
|
||||||
// NOTE: mnemonist LRUMap returns undefined if not found.
|
|
||||||
// If we store undefined, we can't distinguish between "not found" and "found undefined".
|
|
||||||
// But we should at least check its behavior.
|
|
||||||
const cache = new LruCache<string, unknown>(10);
|
|
||||||
cache.set('key', undefined);
|
|
||||||
expect(cache.has('key')).toBe(true);
|
|
||||||
expect(cache.get('key')).toBeUndefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright 2025 Google LLC
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { LRUMap } from 'mnemonist';
|
|
||||||
|
|
||||||
export class LruCache<K, V> {
|
|
||||||
private cache: LRUMap<K, V>;
|
|
||||||
|
|
||||||
constructor(maxSize: number) {
|
|
||||||
this.cache = new LRUMap<K, V>(maxSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
get(key: K): V | undefined {
|
|
||||||
return this.cache.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
has(key: K): boolean {
|
|
||||||
return this.cache.has(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
set(key: K, value: V): void {
|
|
||||||
this.cache.set(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
clear(): void {
|
|
||||||
this.cache.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,7 +15,6 @@ import {
|
|||||||
READ_MANY_FILES_TOOL_NAME,
|
READ_MANY_FILES_TOOL_NAME,
|
||||||
WRITE_FILE_TOOL_NAME,
|
WRITE_FILE_TOOL_NAME,
|
||||||
} from '../tools/tool-names.js';
|
} from '../tools/tool-names.js';
|
||||||
import { LruCache } from './LruCache.js';
|
|
||||||
import {
|
import {
|
||||||
isFunctionResponse,
|
isFunctionResponse,
|
||||||
isFunctionCall,
|
isFunctionCall,
|
||||||
@@ -23,6 +22,7 @@ import {
|
|||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import { promptIdContext } from './promptIdContext.js';
|
import { promptIdContext } from './promptIdContext.js';
|
||||||
import { debugLogger } from './debugLogger.js';
|
import { debugLogger } from './debugLogger.js';
|
||||||
|
import { LRUCache } from 'mnemonist';
|
||||||
|
|
||||||
const CODE_CORRECTION_SYSTEM_PROMPT = `
|
const CODE_CORRECTION_SYSTEM_PROMPT = `
|
||||||
You are an expert code-editing assistant. Your task is to analyze a failed edit attempt and provide a corrected version of the text snippets.
|
You are an expert code-editing assistant. Your task is to analyze a failed edit attempt and provide a corrected version of the text snippets.
|
||||||
@@ -39,12 +39,12 @@ function getPromptId(): string {
|
|||||||
const MAX_CACHE_SIZE = 50;
|
const MAX_CACHE_SIZE = 50;
|
||||||
|
|
||||||
// Cache for ensureCorrectEdit results
|
// Cache for ensureCorrectEdit results
|
||||||
const editCorrectionCache = new LruCache<string, CorrectedEditResult>(
|
const editCorrectionCache = new LRUCache<string, CorrectedEditResult>(
|
||||||
MAX_CACHE_SIZE,
|
MAX_CACHE_SIZE,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Cache for ensureCorrectFileContent results
|
// Cache for ensureCorrectFileContent results
|
||||||
const fileContentCorrectionCache = new LruCache<string, string>(MAX_CACHE_SIZE);
|
const fileContentCorrectionCache = new LRUCache<string, string>(MAX_CACHE_SIZE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the structure of the parameters within CorrectedEditResult
|
* Defines the structure of the parameters within CorrectedEditResult
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
import { createHash } from 'node:crypto';
|
import { createHash } from 'node:crypto';
|
||||||
import { type Content, Type } from '@google/genai';
|
import { type Content, Type } from '@google/genai';
|
||||||
import { type BaseLlmClient } from '../core/baseLlmClient.js';
|
import { type BaseLlmClient } from '../core/baseLlmClient.js';
|
||||||
import { LruCache } from './LruCache.js';
|
import { LRUCache } from 'mnemonist';
|
||||||
import { promptIdContext } from './promptIdContext.js';
|
import { promptIdContext } from './promptIdContext.js';
|
||||||
import { debugLogger } from './debugLogger.js';
|
import { debugLogger } from './debugLogger.js';
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ const SearchReplaceEditSchema = {
|
|||||||
required: ['search', 'replace', 'explanation'],
|
required: ['search', 'replace', 'explanation'],
|
||||||
};
|
};
|
||||||
|
|
||||||
const editCorrectionWithInstructionCache = new LruCache<
|
const editCorrectionWithInstructionCache = new LRUCache<
|
||||||
string,
|
string,
|
||||||
SearchReplaceEdit
|
SearchReplaceEdit
|
||||||
>(MAX_CACHE_SIZE);
|
>(MAX_CACHE_SIZE);
|
||||||
|
|||||||
Reference in New Issue
Block a user