summaryrefslogtreecommitdiffstats
path: root/pym/cache/flat_hash.py
diff options
context:
space:
mode:
authorBrian Harring <ferringb@gentoo.org>2005-11-05 06:09:45 +0000
committerBrian Harring <ferringb@gentoo.org>2005-11-05 06:09:45 +0000
commit6972e5da0cbda080c1cfd2c07eedb2298fa9c0b9 (patch)
treef60b85ea28fe1fb69ee1e6ed614cfa6e7fbcc8f0 /pym/cache/flat_hash.py
parent202c0acb0b68acd88b96cacf8f296b9892642423 (diff)
downloadportage-6972e5da0cbda080c1cfd2c07eedb2298fa9c0b9.tar.gz
portage-6972e5da0cbda080c1cfd2c07eedb2298fa9c0b9.tar.bz2
portage-6972e5da0cbda080c1cfd2c07eedb2298fa9c0b9.zip
replacement cache subsystem that's gestated in 2.1 and 3.0.
it rocks your world, baby. svn path=/main/branches/2.0/; revision=2257
Diffstat (limited to 'pym/cache/flat_hash.py')
-rw-r--r--pym/cache/flat_hash.py129
1 files changed, 129 insertions, 0 deletions
diff --git a/pym/cache/flat_hash.py b/pym/cache/flat_hash.py
new file mode 100644
index 000000000..6882afd7e
--- /dev/null
+++ b/pym/cache/flat_hash.py
@@ -0,0 +1,129 @@
+# Copyright: 2005 Gentoo Foundation
+# Author(s): Brian Harring (ferringb@gentoo.org)
+# License: GPL2
+# $Id: flat_list.py 1911 2005-08-25 03:44:21Z ferringb $
+
+import fs_template
+import cache_errors
+import os, stat
+from mappings import LazyLoad, ProtectedDict
+from template import reconstruct_eclasses
+# store the current key order *here*.
+class database(fs_template.FsBased):
+
+ autocommits = True
+
+ def __init__(self, *args, **config):
+ super(database,self).__init__(*args, **config)
+ self.location = os.path.join(self.location,
+ self.label.lstrip(os.path.sep).rstrip(os.path.sep))
+
+ if not os.path.exists(self.location):
+ self._ensure_dirs()
+
+ def __getitem__(self, cpv):
+ fp = os.path.join(self.location, cpv)
+ try:
+ def curry(*args):
+ def callit(*args2):
+ return args[0](*args[1:]+args2)
+ return callit
+ return ProtectedDict(LazyLoad(curry(self._pull, fp, cpv), initial_items=[("_mtime_", os.stat(fp).st_mtime)]))
+ except OSError:
+ raise KeyError(cpv)
+ return self._getitem(cpv)
+
+ def _pull(self, fp, cpv):
+ try:
+ myf = open(fp,"r")
+ except IOError:
+ raise KeyError(cpv)
+ except OSError, e:
+ raise cache_errors.CacheCorruption(cpv, e)
+ try:
+ d = self._parse_data(myf, cpv)
+ except (OSError, ValueError), e:
+ myf.close()
+ raise cache_errors.CacheCorruption(cpv, e)
+ myf.close()
+ return d
+
+
+ def _parse_data(self, data, cpv, mtime=0):
+ d = dict(map(lambda x:x.rstrip().split("=", 1), data))
+ if mtime != 0:
+ d["_mtime_"] = long(mtime)
+ if "_eclasses_" in d:
+ d["_eclasses_"] = reconstruct_eclasses(cpv, d["_eclasses_"])
+ return d
+
+ for x in self._known_keys:
+ if x not in d:
+ d[x] = ''
+
+
+ return d
+
+
+ def _setitem(self, cpv, values):
+# import pdb;pdb.set_trace()
+ s = cpv.rfind("/")
+ fp = os.path.join(self.location,cpv[:s],".update.%i.%s" % (os.getpid(), cpv[s+1:]))
+ try: myf=open(fp, "w")
+ except IOError, ie:
+ if ie.errno == 2:
+ try:
+ self._ensure_dirs(cpv)
+ myf=open(fp,"w")
+ except (OSError, IOError),e:
+ raise cache_errors.CacheCorruption(cpv, e)
+ except OSError, e:
+ raise cache_errors.CacheCorruption(cpv, e)
+
+ for k, v in values.items():
+ if k != "_mtime_":
+ myf.writelines("%s=%s\n" % (k, v))
+
+ myf.close()
+ self._ensure_access(fp, mtime=values["_mtime_"])
+
+ #update written. now we move it.
+
+ new_fp = os.path.join(self.location,cpv)
+ try: os.rename(fp, new_fp)
+ except (OSError, IOError), e:
+ os.remove(fp)
+ raise cache_errors.CacheCorruption(cpv, e)
+
+
+ def _delitem(self, cpv):
+# import pdb;pdb.set_trace()
+ try:
+ os.remove(os.path.join(self.location,cpv))
+ except OSError, e:
+ if e.errno == 2:
+ raise KeyError(cpv)
+ else:
+ raise cache_errors.CacheCorruption(cpv, e)
+
+
+ def has_key(self, cpv):
+ return os.path.exists(os.path.join(self.location, cpv))
+
+
+ def iterkeys(self):
+ """generator for walking the dir struct"""
+ dirs = [self.location]
+ len_base = len(self.location)
+ while len(dirs):
+ for l in os.listdir(dirs[0]):
+ if l.endswith(".cpickle"):
+ continue
+ p = os.path.join(dirs[0],l)
+ st = os.lstat(p)
+ if stat.S_ISDIR(st.st_mode):
+ dirs.append(p)
+ continue
+ yield p[len_base+1:]
+ dirs.pop(0)
+