Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r12737 - main/trunk/pym/portage/cache
Date: Sun, 01 Mar 2009 20:39:44
Message-Id: E1LdsRq-0002Ey-Ga@stork.gentoo.org
1 Author: zmedico
2 Date: 2009-03-01 20:39:41 +0000 (Sun, 01 Mar 2009)
3 New Revision: 12737
4
5 Added:
6 main/trunk/pym/portage/cache/ebuild_xattr.py
7 Log:
8 Thanks to Petteri R?\195?\164ty <betelgeuse@g.o> for this new cache module which
9 uses extended attributes (via pyxattr) to attach metadata cache directly to
10 the ebuild files themselves.
11
12
13 Added: main/trunk/pym/portage/cache/ebuild_xattr.py
14 ===================================================================
15 --- main/trunk/pym/portage/cache/ebuild_xattr.py (rev 0)
16 +++ main/trunk/pym/portage/cache/ebuild_xattr.py 2009-03-01 20:39:41 UTC (rev 12737)
17 @@ -0,0 +1,163 @@
18 +# -*- coding: UTF8 -*-
19 +# Copyright: 2009 Gentoo Foundation
20 +# Author(s): Petteri Räty (betelgeuse@g.o)
21 +# License: GPL2
22 +# $Id$
23 +
24 +__all__ = ['database']
25 +
26 +from portage.cache import fs_template
27 +from portage.versions import catsplit
28 +from portage import cpv_getkey
29 +from portage.util import writemsg
30 +import os
31 +import xattr
32 +from errno import ENODATA,ENOSPC,E2BIG
33 +
34 +class NoValueException(Exception):
35 + pass
36 +
37 +class database(fs_template.FsBased):
38 +
39 + autocommits = True
40 +
41 + def __init__(self, *args, **config):
42 + super(database,self).__init__(*args, **config)
43 + self.portdir = self.label
44 + self.ns = xattr.NS_USER + '.gentoo.cache'
45 + self.keys = set(self._known_keys)
46 + self.keys.add('_mtime_')
47 + self.keys.add('_eclasses_')
48 + # xattrs have an upper length
49 + self.max_len = self.__get_max()
50 +
51 + def __get_max(self):
52 + path = os.path.join(self.portdir,'profiles/repo_name')
53 + try:
54 + return int(self.__get(path,'value_max_len'))
55 + except NoValueException,e:
56 + max = self.__calc_max(path)
57 + self.__set(path,'value_max_len',str(max))
58 + return max
59 +
60 + def __calc_max(self,path):
61 + """ Find out max attribute length supported by the file system """
62 +
63 + hundred = ''
64 + for i in range(100):
65 + hundred+='a'
66 +
67 + s=hundred
68 +
69 + # Could use finally but needs python 2.5 then
70 + try:
71 + while True:
72 + self.__set(path,'test_max',s)
73 + s+=hundred
74 + except IOError,e:
75 + # ext based give wrong errno
76 + # http://bugzilla.kernel.org/show_bug.cgi?id=12793
77 + if e.errno in (E2BIG,ENOSPC):
78 + result = len(s)-100
79 + else:
80 + raise e
81 +
82 + try:
83 + self.__remove(path,'test_max')
84 + except IOError,e:
85 + if e.errno is not ENODATA:
86 + raise e
87 +
88 + return result
89 +
90 + def __get_path(self,cpv):
91 + cat,pn = catsplit(cpv_getkey(cpv))
92 + return os.path.join(self.portdir,cat,pn,os.path.basename(cpv) + ".ebuild")
93 +
94 + def __has_cache(self,path):
95 + try:
96 + self.__get(path,'_mtime_')
97 + except NoValueException,e:
98 + return False
99 +
100 + return True
101 +
102 + def __get(self,path,key,default=None):
103 + try:
104 + return xattr.get(path,key,namespace=self.ns)
105 + except IOError,e:
106 + if not default is None and ENODATA == e.errno:
107 + return default
108 + else:
109 + raise NoValueException()
110 +
111 + def __remove(self,path,key):
112 + xattr.remove(path,key,namespace=self.ns)
113 +
114 + def __set(self,path,key,value):
115 + xattr.set(path,key,value,namespace=self.ns)
116 +
117 + def _getitem(self, cpv):
118 + values = {}
119 + path = self.__get_path(cpv)
120 + all = {}
121 + for tuple in xattr.get_all(path,namespace=self.ns):
122 + key,value = tuple
123 + all[key] = value
124 +
125 + if not '_mtime_' in all:
126 + raise KeyError(cpv)
127 +
128 + # We default to '' like other caches
129 + for key in self.keys:
130 + attr_value = all.get(key,'1:')
131 + parts,sep,value = attr_value.partition(':')
132 + parts = int(parts)
133 + if parts > 1:
134 + for i in range(1,parts):
135 + value += all.get(key+str(i))
136 + values[key] = value
137 +
138 + return values
139 +
140 + def _setitem(self, cpv, values):
141 + path = self.__get_path(cpv)
142 + max = self.max_len
143 + for key,value in values.iteritems():
144 + # mtime comes in as long so need to convert to strings
145 + s = str(value)
146 + # We need to split long values
147 + value_len = len(s)
148 + parts = 0
149 + if value_len > max:
150 + # Find out how many parts we need
151 + parts = value_len/max
152 + if value_len % max > 0:
153 + parts += 1
154 +
155 + # Only the first entry carries the number of parts
156 + self.__set(path,key,'%s:%s'%(parts,s[0:max]))
157 +
158 + # Write out the rest
159 + for i in range(1,parts):
160 + start = i * max
161 + val = s[start:start+max]
162 + self.__set(path,key+str(i),val)
163 + else:
164 + self.__set(path,key,"%s:%s"%(1,s))
165 +
166 + def _delitem(self, cpv):
167 + pass # Will be gone with the ebuild
168 +
169 + def __contains__(self, cpv):
170 + return os.path.exists(self.__get_path(cpv))
171 +
172 + def __iter__(self):
173 + for root,dirs,files in os.walk(self.portdir):
174 + for file in files:
175 + if file[-7:] == '.ebuild':
176 + cat = os.path.basename(os.path.dirname(root))
177 + pn_pv = file[:-7]
178 + path = os.path.join(root,file)
179 + if self.__has_cache(path):
180 + yield "%s/%s/%s" % (cat,os.path.basename(root),file[:-7])
181
182
183 Property changes on: main/trunk/pym/portage/cache/ebuild_xattr.py
184 ___________________________________________________________________
185 Name: svn:keywords
186 + Id