about summary refs log tree commit diff
path: root/src/libstore/nar-info-disk-cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/nar-info-disk-cache.cc')
-rw-r--r--src/libstore/nar-info-disk-cache.cc52
1 files changed, 38 insertions, 14 deletions
diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc
index d28ff42c7f23..13b67b81f35e 100644
--- a/src/libstore/nar-info-disk-cache.cc
+++ b/src/libstore/nar-info-disk-cache.cc
@@ -36,13 +36,9 @@ create table if not exists NARs (
     foreign key (cache) references BinaryCaches(id) on delete cascade
 );
 
-create table if not exists NARExistence (
-    cache            integer not null,
-    storePath        text not null,
-    exist            integer not null,
-    timestamp        integer not null,
-    primary key (cache, storePath),
-    foreign key (cache) references BinaryCaches(id) on delete cascade
+create table if not exists LastPurge (
+    dummy            text primary key,
+    value            integer
 );
 
 )sql";
@@ -51,8 +47,12 @@ class NarInfoDiskCacheImpl : public NarInfoDiskCache
 {
 public:
 
-    /* How long negative lookups are valid. */
+    /* How long negative and positive lookups are valid. */
     const int ttlNegative = 3600;
+    const int ttlPositive = 30 * 24 * 3600;
+
+    /* How often to purge expired entries from the cache. */
+    const int purgeInterval = 24 * 3600;
 
     struct Cache
     {
@@ -65,7 +65,7 @@ public:
     struct State
     {
         SQLite db;
-        SQLiteStmt insertCache, queryCache, insertNAR, insertMissingNAR, queryNAR;
+        SQLiteStmt insertCache, queryCache, insertNAR, insertMissingNAR, queryNAR, purgeCache;
         std::map<std::string, Cache> caches;
     };
 
@@ -103,7 +103,28 @@ public:
             "insert or replace into NARs(cache, hashPart, timestamp, present) values (?, ?, ?, 0)");
 
         state->queryNAR.create(state->db,
-            "select * from NARs where cache = ? and hashPart = ?");
+            "select * from NARs where cache = ? and hashPart = ? and ((present = 0 and timestamp > ?) or (present = 1 and timestamp > ?))");
+
+        /* Periodically purge expired entries from the database. */
+        auto now = time(0);
+
+        SQLiteStmt queryLastPurge(state->db, "select value from LastPurge");
+        auto queryLastPurge_(queryLastPurge.use());
+
+        if (!queryLastPurge_.next() || queryLastPurge_.getInt(0) < now - purgeInterval) {
+            SQLiteStmt(state->db,
+                "delete from NARs where ((present = 0 and timestamp < ?) or (present = 1 and timestamp < ?))")
+                .use()
+                (now - ttlNegative)
+                (now - ttlPositive)
+                .exec();
+
+            debug("deleted %d entries from the NAR info disk cache", sqlite3_changes(state->db));
+
+            SQLiteStmt(state->db,
+                "insert or replace into LastPurge(dummy, value) values ('', ?)")
+                .use()(now).exec();
+        }
     }
 
     Cache & getCache(State & state, const std::string & uri)
@@ -152,10 +173,15 @@ public:
 
         auto & cache(getCache(*state, uri));
 
-        auto queryNAR(state->queryNAR.use()(cache.id)(hashPart));
+        auto now = time(0);
+
+        auto queryNAR(state->queryNAR.use()
+            (cache.id)
+            (hashPart)
+            (now - ttlNegative)
+            (now - ttlPositive));
 
         if (!queryNAR.next())
-            // FIXME: check NARExistence
             return {oUnknown, 0};
 
         if (!queryNAR.getInt(13))
@@ -163,8 +189,6 @@ public:
 
         auto narInfo = make_ref<NarInfo>();
 
-        // FIXME: implement TTL.
-
         auto namePart = queryNAR.getStr(2);
         narInfo->path = cache.storeDir + "/" +
             hashPart + (namePart.empty() ? "" : "-" + namePart);