Re: [gentoo-portage-dev] [PATCH] rsync metadata cache patch (obsoletes metadata transfer on sync)

2006-01-01 Thread Zac Medico

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Andrew Gaffney wrote:
| Why hasn't this been done before? I'm nowhere near an expert on the 
| portage internals, but this looks like it was pretty "easy".


Well, the cache related code has had a lot of changes lately due to Brian's 
cache backport and the addition of EAPI.  Cleanup related to those probably 
made my patch easier to do.

One funny thing is that the metadb and metadbmodule properties of the portdbapi 
class already existed, but weren't being used for anything yet.  After writing 
that test script and seeing how the cache validation worked, the feasibility of 
the patch became clear to me.

Zac
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFDuLz//ejvha5XGaMRAj+7AKC3SdqvhA4Aar1WagGvGOWqTW2ATgCfYq56
NQ8JgAlw1vsxhqW741MPqRI=
=Ef+e
-END PGP SIGNATURE-
--
gentoo-portage-dev@gentoo.org mailing list



Re: [gentoo-portage-dev] [PATCH] rsync metadata cache patch (obsoletes metadata transfer on sync)

2006-01-01 Thread Andrew Gaffney

Zac Medico wrote:
I was playing with the metadata cache stuff this weekend and decided to 
write a patch that obsoletes metadata transfers on sync.  Simply apply 
this patch to portage-2.1_preX and add "metadb" to FEATURES in 
make.conf.  Side note: this feature should resolve bug 90518.


May I have the honor of bearing your children? Seriously, this is nice. Why 
hasn't this been done before? I'm nowhere near an expert on the portage 
internals, but this looks like it was pretty "easy".


--
Andrew Gaffneyhttp://dev.gentoo.org/~agaffney/
Gentoo Linux Developer   Installer Project
--
gentoo-portage-dev@gentoo.org mailing list



[gentoo-portage-dev] [PATCH] rsync metadata cache patch (obsoletes metadata transfer on sync)

2006-01-01 Thread Zac Medico

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Hi,

I was playing with the metadata cache stuff this weekend and decided to write a patch 
that obsoletes metadata transfers on sync.  Simply apply this patch to portage-2.1_preX 
and add "metadb" to FEATURES in make.conf.  Side note: this feature should 
resolve bug 90518.

I also wrote a script that tests consistency between regenerated metadata and the 
pre-generated metadata from the rsync mirrors.  Actually, writing this script taught me 
what I needed to know to write the patch.  If you want to try this script, you need to 
remove /var/cache/edb/dep/${PORTDIR} in order to force a regen.  Also, the script will 
not work as designed when FEATURES="metadb" is enabled.

Zac
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFDuI8D/ejvha5XGaMRArFhAJ9/zXBSlbMK84f0EHLjTUHf6Vg6/ACgwOkw
zjV8plh/mv3JwgXRcsxsSoA=
=7CP0
-END PGP SIGNATURE-
Index: portage-2.1_pre3/pym/cache/util.py
===
--- portage-2.1_pre3.orig/pym/cache/util.py
+++ portage-2.1_pre3/pym/cache/util.py
@@ -101,3 +101,13 @@ class non_quiet_mirroring(quiet_mirrorin
 	def corruption(self,key,*arg):	print "corrupt %s:" % key,arg
 	def eclass_stale(self,key,*arg):print "stale %s:"%key,arg
 
+def is_cache_valid(emtime, eclasses, mydata):
+	if emtime != long(mydata.get("_mtime_", 0)):
+		return False
+	ec_dict = mydata.get("_eclasses_", [])
+	if len(ec_dict) == 0:
+		return True
+	for eclass, tup in ec_dict.iteritems():
+		if eclass not in eclasses or tuple(tup) != eclasses[eclass]:
+			return False
+	return True
Index: portage-2.1_pre3/pym/portage.py
===
--- portage-2.1_pre3.orig/pym/portage.py
+++ portage-2.1_pre3/pym/portage.py
@@ -29,6 +29,7 @@ try:
 	from time import sleep
 	from random import shuffle
 	from cache.cache_errors import CacheError
+	from cache.util import is_cache_valid
 except SystemExit, e:
 	raise
 except Exception, e:
@@ -4721,7 +4722,12 @@ class portdbapi(dbapi):
 		for x in self.porttrees:
 			# location, label, auxdbkeys
 			self.auxdb[x] = self.auxdbmodule(portage_const.DEPCACHE_PATH, x, filtered_auxdbkeys, gid=portage_gid)
-			
+
+		if "metadb" in self.mysettings.features:
+			for x in self.porttrees:
+if os.path.exists(x+"/metadata/cache"):
+	self.metadb[x]=self.metadbmodule(x, "metadata/cache", auxdbkeys)
+
 	def close_caches(self):
 		for x in self.auxdb.keys():
 			self.auxdb[x].sync()
@@ -4825,14 +4831,16 @@ class portdbapi(dbapi):
 			raise KeyError
 
 		try:
-			mydata = self.auxdb[mylocation][mycpv]
-			if emtime != long(mydata.get("_mtime_", 0)):
-doregen = True
-			elif len(mydata.get("_eclasses_", [])) > 0:
-doregen = not self.eclassdb.is_eclass_data_valid(mydata["_eclasses_"])
-			else:
-doregen = False
-
+			mydata=None
+			doregen=False
+			if self.metadb.has_key(mylocation):
+try:
+	mydata = self.metadb[mylocation][mycpv]
+except (KeyError, CacheError):
+	pass
+			if not mydata or not is_cache_valid(emtime, self.eclassdb.eclasses, mydata):
+mydata = self.auxdb[mylocation][mycpv]
+doregen = not is_cache_valid(emtime, self.eclassdb.eclasses, mydata)
 		except KeyError:
 			doregen = True
 		except CacheError:
Index: portage-2.1_pre3/bin/emerge
===
--- portage-2.1_pre3.orig/bin/emerge
+++ portage-2.1_pre3/bin/emerge
@@ -2768,6 +2768,10 @@ if myaction in ["sync","rsync","metadata
 	except:
 		pass
 
+	if updatecache_flg and "metadb" in portage.features:
+		updatecache_flg=False
+		print "!!! Skipping metadata transfer because metadb is in FEATURES."
+
 	if os.path.exists(myportdir+"/metadata/cache") and updatecache_flg:
 		if "--quiet" not in myopts:
 			print "\n>>> Updating Portage cache:  ",
#!/usr/bin/env python
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
#
# Zac Medico <[EMAIL PROTECTED]>
#

import portage

def is_cache_valid(emtime, eclasses, mydata):
	if emtime != long(mydata.get("_mtime_", 0)):
		return False
	ec_dict = mydata.get("_eclasses_", [])
	if len(ec_dict) == 0:
		return True
	for eclass, tup in ec_dict.iteritems():
		if eclass not in eclasses or tuple(tup) != eclasses[eclass]:
			return False
	return True

def aux_get_dict(dbapi, cpv, auxdbkeys):
	data_list = dbapi.aux_get(cpv, auxdbkeys)
	data_dict = {}
	for i in xrange(len(auxdbkeys)):
		data_dict[auxdbkeys[i]]=data_list[i]
	return data_dict

if __name__ == "__main__":
	portdir = portage.settings["PORTDIR"]
	rsync_module = portage.settings.load_best_module("portdbapi.metadbmodule")
	auxdbkeys = filter(lambda x: not x.startswith("UNUSED_0"), portage.auxdbkeys)
	rsync_cache = rsync_module(portdir, "metadata/cache", auxdbkeys)
	portdb = portage.db["/"]["porttree"].dbapi

	# discard overlay
	for portree in portdb.porttrees:
		if portree!=portdir:
			portdb.portt