1
2
3
4
5
6 import os
7 import types
8 import time
9
10 from diskutils import *
11
13 - def __init__(self, dirname, tries_limit = 200):
14
15
16
17 self.dirname = dirname
18 self.tries_limit = tries_limit
19
20
22 - def __init__(self, entries = None, entrlen = None, name = None, storage = None):
23 if entries is None:
24 entries = []
25 if entrlen is None:
26 entrlen = len(entries)
27 self.entries = entries
28 self.name = name
29 self.storage = storage
30 self.in_memory = True
31 self.on_disk = False
32 self.setLen(entrlen)
33 self.updateKeys()
34
36 if i < self.__len__():
37 return self.entries[i]
38 else:
39 raise IndexError('list index out of range')
40
42 if i < self.__len__():
43 if self.entries[i][0] != item[0]:
44 self.delKey(self.entries[i][0])
45 self.addKey(item[0])
46 self.entries[i] = item
47 self.on_disk = False
48 else:
49 raise IndexError('list index out of range')
50
52 entrlen = self.__len__()
53 if i < entrlen:
54 self.delKey(self.entries[i][0])
55 del self.entries[i]
56 self.setLen(entrlen - 1)
57 self.on_disk = False
58 else:
59 raise IndexError('list index out of range')
60
63
65 entrlen = self.__len__()
66 self.addKey(item[0])
67 if entrlen < len(self.entries):
68 self.entries[entrlen] = item
69 else:
70 self.entries.append(item)
71 self.setLen(entrlen + 1)
72 self.on_disk = False
73
75 entrlen = self.__len__()
76 if i < entrlen:
77 self.addKey(item[0])
78 self.entries.insert(i, item)
79 self.setLen(entrlen + 1)
80 self.on_disk = False
81 else:
82 self.append(item)
83
87
89 self.entrlen = entrlen
90
92 self.entry_keys[key] = {}
93
95 del self.entry_keys[key]
96
99
101 self.entry_keys = {}
102 for i in xrange(self.__len__()):
103 self.addKey(self.entries[i][0])
104
106
107
108 if self.in_memory:
109 if not self.on_disk:
110 self.save()
111 self.in_memory = False
112 entries = self.entries
113 self.entries = []
114 return entries
115
116 - def load(self, forced = False, entries = None):
117 if self.storage:
118 dirname = self.storage.dirname
119 generic_name = self.genericName()
120 if generic_name:
121 try:
122 last = getLast(os.path.join(dirname, generic_name))
123 except OSError, e:
124 self.on_disk = False
125 else:
126 self.on_disk = True
127 lfn = os.path.basename(last)
128 if self.name != lfn or forced:
129 self.entries, entrlen = read(last, entries)
130 self.name = lfn
131 self.in_memory = True
132 self.setLen(entrlen)
133 self.updateKeys()
134
136 if not self.on_disk:
137 if self.in_memory:
138 if self.storage:
139 dirname = self.storage.dirname
140 tries_limit = self.storage.tries_limit
141 generic_name = self.genericName()
142 if generic_name:
143 fn = os.path.join(dirname, generic_name)
144 entrlen = self.__len__()
145 if entrlen > 0:
146 self.name = os.path.basename(write(self.entries, fn, entrlen, tries_limit))
147 self.on_disk = True
148 else:
149 remove(fn)
150 self.on_disk = False
151
152
153 -class EntryBlock(Block):
154
155 - def addKey(self, key):
156
157
158 kk = key.split('.')
159 dd = self.entry_keys
160 for k in kk:
161 if not dd.has_key(k):
162 dd[k] = {}
163 dd = dd[k]
164
165 - def delKey(self, key):
166
167 kk = key.split('.')
168 dd = self.entry_keys
169 visited = []
170 for k in kk:
171 if dd.has_key(k):
172 visited.append((dd,k))
173 dd = dd[k]
174 else:
175 break
176 else:
177 visited.reverse()
178 for dd, k in visited:
179 del dd[k]
180 if len(dd) > 0:
181 break
182
183 - def hasKey(self, key):
184 kk = key.split('.')
185 dd = self.entry_keys
186 for k in kk:
187 if not dd.has_key(k):
188 return False
189 else:
190 dd = dd[k]
191 return True
192
193
195
197
198
199 self.maxsize = maxsize
200 self.blocks = []
201
202 - def put(self, block):
203 if block.in_memory:
204 if block not in self.blocks:
205 self.blocks.append(block)
206
208 if self.maxsize > 0:
209 if len(self.blocks) >= self.maxsize:
210 return self.blocks.pop(0).memoryRelease()
211
212
214 block_prefix = 'BLOCK-'
215 block_class = Block
216
217 - def __init__(self, ll = None,
218 dirname = '',
219 blocklength = 100,
220 cache_size = 3,
221 tries_limit = 200):
222 self.storage = Storage(dirname, tries_limit)
223 self.blocklength = blocklength
224 if ll == None:
225 ll = []
226 self.cache = BlockCache(cache_size)
227 self.blocks = []
228 start = 0
229 stop = self.blocklength
230 while 1:
231 entries = ll[start:stop]
232 if not entries:
233 break
234 self._addNewBlock(entries)
235 start = stop
236 stop += self.blocklength
237
239 bni = len(self.blocks)
240 if bni > 0:
241 last_blk = self.blocks[-1]
242 gn = last_blk.genericName()
243 if gn:
244 bni = int(gn.split('-')[1])+ 1
245 generic_name = self.block_prefix + str(bni)
246 entrlen = len(entries)
247 free_entries = self.cache.get()
248 if free_entries is not None:
249 free_entries[:entrlen] = entries
250 entries = free_entries
251 blk = self.block_class(entries = entries,
252 entrlen = entrlen,
253 name = generic_name,
254 storage = self.storage)
255 self.blocks.append(blk)
256 self.cache.put(blk)
257
259
260 if not (blk.in_memory and forced):
261 free_entries = self.cache.get()
262 blk.load(forced, free_entries)
263 self.cache.put(blk)
264
266 if i < 0:
267 i += self.__len__()
268 i = max(0,i)
269 blk_i = i
270 for blk in self.blocks:
271 tt = blk_i - len(blk)
272 if tt < 0:
273 return (blk, blk_i)
274 blk_i = tt
275 raise IndexError('list index out of range')
276
286
288 if type(i) == types.SliceType:
289 ss = i.indices(self.__len__())
290 ii = range(*ss)
291 len_ii = len(ii)
292 len_item = len(item)
293 if i.step != None:
294 if len_ii != len_item:
295 msg = "attempt to assign sequence of size %d to extended slice of size %d" %(len_item, len_ii)
296 raise ValueError(msg)
297 else:
298 delete = ii[len_item:]
299 delete.reverse()
300 insert = item[len_ii:]
301 insert.reverse()
302 for d in delete:
303 del self[d]
304 for s in insert:
305 self.insert(len_ii, s)
306 map(lambda x: self.__setitem__(*x), zip(ii,item))
307 else:
308 (blk, blk_i) = self._translateIndex(i)
309 self._loadBlock(blk)
310 blk[blk_i] = item
311
323
325 blen = 0
326 for blk in self.blocks:
327 blen += len(blk)
328 return blen
329
331 if not self.blocks:
332 self._addNewBlock([])
333 blk = self.blocks[-1]
334 if len(blk) >= self.blocklength:
335 self._addNewBlock([])
336 blk = self.blocks[-1]
337 self._loadBlock(blk)
338 blk.append(item)
339
341 for item in iter:
342 self.append(item)
343
349
351 dd = {}
352 for blk in self.blocks:
353 generic_name = blk.genericName()
354 if generic_name != None:
355 dd[generic_name] = blk
356 return dd
357
359 x, y = map(lambda f: int(f.split('-')[1]), (x, y))
360 if x < y:
361 return -1
362 elif x == y:
363 return 0
364 elif x > y:
365 return 1
366
380
381 - def load(self, dirname = ''):
382 if dirname:
383 self.storage.dirname = dirname
384 blocks = []
385 bns = self._getStoredBlockNames()
386 ndict = self._getBlockNames()
387 for bn in bns:
388 if bn in ndict:
389 blk = ndict[bn]
390 else:
391 blk = self.block_class(name = bn, storage = self.storage)
392 self._loadBlock(blk, forced = False)
393 blocks.append(blk)
394 self.blocks = blocks
395
396 - def save(self, dirname = ''):
397 if dirname:
398 self.storage.dirname = dirname
399 for i in xrange(len(self.blocks)-1, -1, -1):
400 blk = self.blocks[i]
401 blk.save()
402 if len(blk) == 0:
403 del self.blocks[i]
404
406 map(lambda x: setattr(x,'on_disk',False), self.blocks)
407
409 for blk in self.blocks:
410 if blk.hasKey(key):
411 return True
412 return False
413
414
416 block_prefix = 'Attr-'
417
418 - def __init__(self, ll = None,
419 dirname = '',
420 blocklength = 20,
421 cache_size = 3,
422 tries_limit = 200):
424
425
427 block_prefix = 'Entr-'
428 block_class = EntryBlock
429
430 - def __init__(self, ll = None,
431 dirname = '',
432 blocklength = 100,
433 cache_size = 3,
434 tries_limit = 200):
435 super(Entries, self).__init__(ll, dirname, blocklength, cache_size, tries_limit)
436