summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/hashserv
diff options
context:
space:
mode:
authorJoshua Watt <JPEWhacker@gmail.com>2023-10-06 09:36:44 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-10-09 15:48:44 +0100
commitb026e816f710170138fa23c9cbc8aa8c1a882647 (patch)
tree1e0ad22d1d94e6c01e2168471e72dc466bd7e807 /bitbake/lib/hashserv
parentcc218dd1080b4df151e90c6e4a0c3d664e1aeee2 (diff)
downloadpoky-b026e816f710170138fa23c9cbc8aa8c1a882647.tar.gz
bitbake: hashserv: Add API to clean unused entries
Adds an API to remove unused entries in the outhash database based on age and if they are referenced by any unihash (Bitbake rev: a169ac523d166c6cbba918b152a76782176c3e88) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/hashserv')
-rw-r--r--bitbake/lib/hashserv/client.py5
-rw-r--r--bitbake/lib/hashserv/server.py20
-rw-r--r--bitbake/lib/hashserv/tests.py19
3 files changed, 43 insertions, 1 deletions
diff --git a/bitbake/lib/hashserv/client.py b/bitbake/lib/hashserv/client.py
index eeafeabda0..f676d267fa 100644
--- a/bitbake/lib/hashserv/client.py
+++ b/bitbake/lib/hashserv/client.py
@@ -105,6 +105,10 @@ class AsyncClient(bb.asyncrpc.AsyncClient):
105 await self._set_mode(self.MODE_NORMAL) 105 await self._set_mode(self.MODE_NORMAL)
106 return await self.send_message({"remove": {"where": where}}) 106 return await self.send_message({"remove": {"where": where}})
107 107
108 async def clean_unused(self, max_age):
109 await self._set_mode(self.MODE_NORMAL)
110 return await self.send_message({"clean-unused": {"max_age_seconds": max_age}})
111
108 112
109class Client(bb.asyncrpc.Client): 113class Client(bb.asyncrpc.Client):
110 def __init__(self): 114 def __init__(self):
@@ -120,6 +124,7 @@ class Client(bb.asyncrpc.Client):
120 "reset_stats", 124 "reset_stats",
121 "backfill_wait", 125 "backfill_wait",
122 "remove", 126 "remove",
127 "clean_unused",
123 ) 128 )
124 129
125 def _get_async_client(self): 130 def _get_async_client(self):
diff --git a/bitbake/lib/hashserv/server.py b/bitbake/lib/hashserv/server.py
index d52e1d46df..45bf476bfe 100644
--- a/bitbake/lib/hashserv/server.py
+++ b/bitbake/lib/hashserv/server.py
@@ -4,7 +4,7 @@
4# 4#
5 5
6from contextlib import closing, contextmanager 6from contextlib import closing, contextmanager
7from datetime import datetime 7from datetime import datetime, timedelta
8import enum 8import enum
9import asyncio 9import asyncio
10import logging 10import logging
@@ -187,6 +187,7 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection):
187 'reset-stats': self.handle_reset_stats, 187 'reset-stats': self.handle_reset_stats,
188 'backfill-wait': self.handle_backfill_wait, 188 'backfill-wait': self.handle_backfill_wait,
189 'remove': self.handle_remove, 189 'remove': self.handle_remove,
190 'clean-unused': self.handle_clean_unused,
190 }) 191 })
191 192
192 def validate_proto_version(self): 193 def validate_proto_version(self):
@@ -542,6 +543,23 @@ class ServerClient(bb.asyncrpc.AsyncServerConnection):
542 543
543 self.write_message({"count": count}) 544 self.write_message({"count": count})
544 545
546 async def handle_clean_unused(self, request):
547 max_age = request["max_age_seconds"]
548 with closing(self.db.cursor()) as cursor:
549 cursor.execute(
550 """
551 DELETE FROM outhashes_v2 WHERE created<:oldest AND NOT EXISTS (
552 SELECT unihashes_v2.id FROM unihashes_v2 WHERE unihashes_v2.method=outhashes_v2.method AND unihashes_v2.taskhash=outhashes_v2.taskhash LIMIT 1
553 )
554 """,
555 {
556 "oldest": datetime.now() - timedelta(seconds=-max_age)
557 }
558 )
559 count = cursor.rowcount
560
561 self.write_message({"count": count})
562
545 def query_equivalent(self, cursor, method, taskhash): 563 def query_equivalent(self, cursor, method, taskhash):
546 # This is part of the inner loop and must be as fast as possible 564 # This is part of the inner loop and must be as fast as possible
547 cursor.execute( 565 cursor.execute(
diff --git a/bitbake/lib/hashserv/tests.py b/bitbake/lib/hashserv/tests.py
index a3e066406e..f343c586b5 100644
--- a/bitbake/lib/hashserv/tests.py
+++ b/bitbake/lib/hashserv/tests.py
@@ -158,6 +158,25 @@ class HashEquivalenceCommonTests(object):
158 result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash) 158 result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash)
159 self.assertIsNone(result_outhash) 159 self.assertIsNone(result_outhash)
160 160
161 def test_clean_unused(self):
162 taskhash, outhash, unihash = self.test_create_hash()
163
164 # Clean the database, which should not remove anything because all hashes an in-use
165 result = self.client.clean_unused(0)
166 self.assertEqual(result["count"], 0)
167 self.assertClientGetHash(self.client, taskhash, unihash)
168
169 # Remove the unihash. The row in the outhash table should still be present
170 self.client.remove({"unihash": unihash})
171 result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False)
172 self.assertIsNotNone(result_outhash)
173
174 # Now clean with no minimum age which will remove the outhash
175 result = self.client.clean_unused(0)
176 self.assertEqual(result["count"], 1)
177 result_outhash = self.client.get_outhash(self.METHOD, outhash, taskhash, False)
178 self.assertIsNone(result_outhash)
179
161 def test_huge_message(self): 180 def test_huge_message(self):
162 # Simple test that hashes can be created 181 # Simple test that hashes can be created
163 taskhash = 'c665584ee6817aa99edfc77a44dd853828279370' 182 taskhash = 'c665584ee6817aa99edfc77a44dd853828279370'