1 line
8.6 KiB
JSON
1 line
8.6 KiB
JSON
|
{"ast":null,"code":"export class SqlCache {\n #owner;\n #sqls;\n capacity;\n constructor(owner, capacity) {\n this.#owner = owner;\n this.#sqls = new Lru();\n this.capacity = capacity;\n }\n // Replaces SQL strings with cached `hrana.Sql` objects in the statements in `hranaStmts`. After this\n // function returns, we guarantee that all `hranaStmts` refer to valid (not closed) `hrana.Sql` objects,\n // but _we may invalidate any other `hrana.Sql` objects_ (by closing them, thus removing them from the\n // server).\n //\n // In practice, this means that after calling this function, you can use the statements only up to the\n // first `await`, because concurrent code may also use the cache and invalidate those statements.\n apply(hranaStmts) {\n if (this.capacity <= 0) {\n return;\n }\n const usedSqlObjs = new Set();\n for (const hranaStmt of hranaStmts) {\n if (typeof hranaStmt.sql !== \"string\") {\n continue;\n }\n const sqlText = hranaStmt.sql;\n // Stored SQL cannot exceed 5kb.\n // https://github.com/tursodatabase/libsql/blob/e9d637e051685f92b0da43849507b5ef4232fbeb/libsql-server/src/hrana/http/request.rs#L10\n if (sqlText.length >= 5000) {\n continue;\n }\n let sqlObj = this.#sqls.get(sqlText);\n if (sqlObj === undefined) {\n while (this.#sqls.size + 1 > this.capacity) {\n const [evictSqlText, evictSqlObj] = this.#sqls.peekLru();\n if (usedSqlObjs.has(evictSqlObj)) {\n // The SQL object that we are trying to evict is already in use in this batch, so we\n // must not evict and close it.\n break;\n }\n evictSqlObj.close();\n this.#sqls.delete(evictSqlText);\n }\n if (this.#sqls.size + 1 <= this.capacity) {\n sqlObj = this.#owner.storeSql(sqlText);\n this.#sqls.set(sqlText, sqlObj);\n }\n }\n if (sqlObj !== undefined) {\n hranaStmt.sql = sqlObj;\n usedSqlObjs.add(sqlObj);\n }\n }\n }\n}\nclass Lru {\n // This maps keys to the cache values. The entries are ordered by their last use (entires that were used\n // most recently are at the end).\n #cache;\n constructor() {\n this.#cache = new Map();\n }\n get(key) {\n const value = this.#cache.get(key);\n if (value !== undefined) {\n // move the entry to the back of the Map\n this.#cache.delete(key);\n this.#cache.set(key, value);\n }\n return value;\n }\n set(key, value) {\n this.#cache.set(key, value);\n }\n peekLru() {\n for (const entry of this.#cache.entries()) {\n return entry;\n }\n return undefined;\n }\n delete(key) {\n this.#cache.delete(key);\n }\n get size() {\n return this.#cache.size;\n }\n}","map":{"version":3,"names":["SqlCache","owner","sqls","capacity","constructor","Lru","apply","hranaStmts","usedSqlObjs","Set","hranaStmt","sql","sqlText","length","sqlObj","get","undefined","size","evictSqlText","evictSqlObj","peekLru","has","close","delete","storeSql","set","add","cache","Map","key","value","entry","entries"],"sources":["/Users/shoofle/Projects/the-forest/node_modules/@libsql/client/lib-esm/sql_cache.js"],"sourcesContent":["export class SqlCache {\n #owner;\n #sqls;\n capacity;\n constructor(owner, capacity) {\n this.#owner = owner;\n this.#sqls = new Lru();\n this.capacity = capacity;\n }\n // Replaces SQL strings with cached `hrana.Sql` objects in the statements in `hranaStmts`. After this\n // function returns, we guarantee that all `hranaStmts` refer to valid (not closed) `hrana.Sql` objects,\n // but _we may invalidate any other `hrana.Sql` objects_ (by closing them, thus removing them from the\n // server).\n //\n // In practice, this means that after calling this function, you can use the statements only up to the\n // first `await`, because concurrent code may also use the cache and invalidate those statements.\n apply(hranaStmts) {\n if (this.capacity <= 0) {\n
|