about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-01-27T14·19+0100
committerEelco Dolstra <edolstra@gmail.com>2017-01-27T14·19+0100
commitcb1951e746cb04f331b126c746758c96bb9fdc81 (patch)
tree6a4668f294e0c1fe32faaa80d6b3c3b55623d482
parent211bc7f0e6daa65fe4083334e2411bc441067904 (diff)
Periodically purge binary-cache.sqlite
-rw-r--r--src/libstore/nar-info-disk-cache.cc31
-rw-r--r--src/libstore/sqlite.hh1
2 files changed, 31 insertions, 1 deletions
diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc
index ed2f18ffe829..13b67b81f35e 100644
--- a/src/libstore/nar-info-disk-cache.cc
+++ b/src/libstore/nar-info-disk-cache.cc
@@ -36,6 +36,11 @@ create table if not exists NARs (
     foreign key (cache) references BinaryCaches(id) on delete cascade
 );
 
+create table if not exists LastPurge (
+    dummy            text primary key,
+    value            integer
+);
+
 )sql";
 
 class NarInfoDiskCacheImpl : public NarInfoDiskCache
@@ -46,6 +51,9 @@ public:
     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
     {
         int id;
@@ -57,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;
     };
 
@@ -96,6 +104,27 @@ public:
 
         state->queryNAR.create(state->db,
             "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)
diff --git a/src/libstore/sqlite.hh b/src/libstore/sqlite.hh
index 7c1ed538215c..4d347a2e56ab 100644
--- a/src/libstore/sqlite.hh
+++ b/src/libstore/sqlite.hh
@@ -31,6 +31,7 @@ struct SQLiteStmt
     sqlite3 * db = 0;
     sqlite3_stmt * stmt = 0;
     SQLiteStmt() { }
+    SQLiteStmt(sqlite3 * db, const std::string & s) { create(db, s); }
     void create(sqlite3 * db, const std::string & s);
     ~SQLiteStmt();
     operator sqlite3_stmt * () { return stmt; }