diff --git a/frontend/lib/caching/codeCache.ts b/frontend/lib/caching/codeCache.ts new file mode 100644 index 00000000..0897abcd --- /dev/null +++ b/frontend/lib/caching/codeCache.ts @@ -0,0 +1,105 @@ +/** + * 공통 코드 캐시 시스템 + * 자주 사용되는 공통 코드들을 메모리에 캐싱하여 성능을 향상시킵니다. + */ + +interface CacheEntry { + data: any; + timestamp: number; + expiry: number; +} + +class CodeCache { + private cache = new Map(); + private defaultTTL = 5 * 60 * 1000; // 5분 + + /** + * 캐시에 데이터 저장 + */ + set(key: string, data: any, ttl?: number): void { + const expiry = ttl || this.defaultTTL; + const entry: CacheEntry = { + data, + timestamp: Date.now(), + expiry, + }; + this.cache.set(key, entry); + } + + /** + * 캐시에서 데이터 조회 + */ + get(key: string): any | null { + const entry = this.cache.get(key); + if (!entry) { + return null; + } + + // TTL 체크 + if (Date.now() - entry.timestamp > entry.expiry) { + this.cache.delete(key); + return null; + } + + return entry.data; + } + + /** + * 캐시에서 데이터 삭제 + */ + delete(key: string): boolean { + return this.cache.delete(key); + } + + /** + * 모든 캐시 삭제 + */ + clear(): void { + this.cache.clear(); + } + + /** + * 만료된 캐시 정리 + */ + cleanup(): void { + const now = Date.now(); + for (const [key, entry] of this.cache.entries()) { + if (now - entry.timestamp > entry.expiry) { + this.cache.delete(key); + } + } + } + + /** + * 캐시 상태 조회 + */ + getStats(): { size: number; keys: string[] } { + return { + size: this.cache.size, + keys: Array.from(this.cache.keys()), + }; + } + + /** + * 공통 코드 캐시 키 생성 + */ + createCodeKey(category: string, companyCode?: string): string { + return `code:${category}:${companyCode || "*"}`; + } +} + +// 싱글톤 인스턴스 생성 +const codeCache = new CodeCache(); + +// 주기적으로 만료된 캐시 정리 (10분마다) +if (typeof window !== "undefined") { + setInterval( + () => { + codeCache.cleanup(); + }, + 10 * 60 * 1000, + ); +} + +export default codeCache; +export { CodeCache, codeCache }; diff --git a/frontend/lib/hooks/useEntityJoinOptimization.ts b/frontend/lib/hooks/useEntityJoinOptimization.ts index b124963a..3c3c7545 100644 --- a/frontend/lib/hooks/useEntityJoinOptimization.ts +++ b/frontend/lib/hooks/useEntityJoinOptimization.ts @@ -4,7 +4,7 @@ */ import { useState, useEffect, useCallback, useMemo, useRef } from "react"; -import { codeCache } from "@/lib/cache/codeCache"; +import { codeCache } from "@/lib/caching/codeCache"; interface ColumnMetaInfo { webType?: string; diff --git a/frontend/lib/registry/components/table-list/TableListComponent.tsx b/frontend/lib/registry/components/table-list/TableListComponent.tsx index 21996dd9..3d8285fc 100644 --- a/frontend/lib/registry/components/table-list/TableListComponent.tsx +++ b/frontend/lib/registry/components/table-list/TableListComponent.tsx @@ -4,7 +4,7 @@ import React, { useState, useEffect, useMemo } from "react"; import { TableListConfig, ColumnConfig } from "./types"; import { tableTypeApi } from "@/lib/api/screen"; import { entityJoinApi } from "@/lib/api/entityJoin"; -import { codeCache } from "@/lib/cache/codeCache"; +import { codeCache } from "@/lib/caching/codeCache"; import { useEntityJoinOptimization } from "@/lib/hooks/useEntityJoinOptimization"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input";