|
23 | 23 | import string |
24 | 24 | import struct |
25 | 25 | import sys |
| 26 | +import tempfile |
26 | 27 | import time |
| 28 | +import types |
27 | 29 | import urlparse |
28 | 30 | import unicodedata |
29 | 31 |
|
@@ -205,31 +207,86 @@ def __init__(self): |
205 | 207 | self.chunks = [[]] |
206 | 208 | self.cache = None |
207 | 209 | self.length = 0 |
| 210 | + self.filenames = set() |
208 | 211 |
|
209 | 212 | def append(self, value): |
210 | 213 | self.chunks[-1].append(value) |
211 | 214 | if len(self.chunks[-1]) >= BIGARRAY_CHUNK_LENGTH: |
212 | | - fp = tempfile.TemporaryFile() |
213 | | - pickle.dump(self.chunks[-1], fp) |
| 215 | + filename = self._dump(self.chunks[-1]) |
214 | 216 | del(self.chunks[-1][:]) |
215 | | - self.chunks[-1] = fp |
| 217 | + self.chunks[-1] = filename |
216 | 218 | self.chunks.append([]) |
217 | 219 |
|
| 220 | + def pop(self): |
| 221 | + if len(self.chunks[-1]) < 1: |
| 222 | + self.chunks.pop() |
| 223 | + fp = open(self.chunks[-1], 'rb') |
| 224 | + self.chunks[-1] = pickle.load(fp) |
| 225 | + fp.close() |
| 226 | + return self.chunks[-1].pop() |
| 227 | + |
| 228 | + def index(self, value): |
| 229 | + for index in xrange(len(self)): |
| 230 | + if self[index] == value: |
| 231 | + return index |
| 232 | + return ValueError, "%s is not in list" % value |
| 233 | + |
| 234 | + def _dump(self, value): |
| 235 | + handle, filename = tempfile.mkstemp() |
| 236 | + self.filenames.add(filename) |
| 237 | + os.close(handle) |
| 238 | + fp = open(filename, 'w+b') |
| 239 | + pickle.dump(value, fp) |
| 240 | + fp.close() |
| 241 | + return filename |
| 242 | + |
| 243 | + def _checkcache(self, index): |
| 244 | + if (self.cache and self.cache[0] != index and self.cache[2]): |
| 245 | + filename = self._dump(self.cache[1]) |
| 246 | + self.chunks[self.cache[0]] = filename |
| 247 | + if not (self.cache and self.cache[0] == index): |
| 248 | + fp = open(self.chunks[index], 'rb') |
| 249 | + self.cache = [index, pickle.load(fp), False] |
| 250 | + fp.close() |
| 251 | + |
218 | 252 | def __getitem__(self, y): |
219 | 253 | index = y / BIGARRAY_CHUNK_LENGTH |
220 | 254 | offset = y % BIGARRAY_CHUNK_LENGTH |
221 | 255 | chunk = self.chunks[index] |
222 | 256 | if isinstance(chunk, list): |
223 | 257 | return chunk[offset] |
224 | 258 | else: |
225 | | - if not (self.cache and self.cache[0] == index): |
226 | | - chunk.seek(0) |
227 | | - self.cache = (index, pickle.load(chunk)) |
| 259 | + self._checkcache(index) |
228 | 260 | return self.cache[1][offset] |
229 | 261 |
|
| 262 | + def __setitem__(self, y, value): |
| 263 | + index = y / BIGARRAY_CHUNK_LENGTH |
| 264 | + offset = y % BIGARRAY_CHUNK_LENGTH |
| 265 | + chunk = self.chunks[index] |
| 266 | + if isinstance(chunk, list): |
| 267 | + chunk[offset] = value |
| 268 | + else: |
| 269 | + self._checkcache(index) |
| 270 | + self.cache[1][offset] = value |
| 271 | + self.cache[2] = True # dirty flag |
| 272 | + |
| 273 | + def __repr__(self): |
| 274 | + return "%s%s" % ("..." if len(self.chunks) > 1 else "", self.chunks[-1].__repr__()) |
| 275 | + |
| 276 | + def __iter__(self): |
| 277 | + for i in xrange(len(self)): |
| 278 | + yield self[i] |
| 279 | + |
230 | 280 | def __len__(self): |
231 | 281 | return len(self.chunks[-1]) if len(self.chunks) == 1 else (len(self.chunks) - 1) * BIGARRAY_CHUNK_LENGTH + len(self.chunks[-1]) |
232 | 282 |
|
| 283 | + def __del__(self): |
| 284 | + for filename in self.filenames: |
| 285 | + try: |
| 286 | + os.remove(filename) |
| 287 | + except OSError: |
| 288 | + pass |
| 289 | + |
233 | 290 | class DynamicContentItem: |
234 | 291 | """ |
235 | 292 | Represents line in content page with dynamic properties (candidate |
@@ -561,6 +618,15 @@ def isVersionGreaterOrEqualThan(version): |
561 | 618 | def isOs(os): |
562 | 619 | return Backend.getOs() is not None and Backend.getOs().lower() == os.lower() |
563 | 620 |
|
| 621 | +# Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/ |
| 622 | +def cachedmethod(f, cache={}): |
| 623 | + def g(*args, **kwargs): |
| 624 | + key = ( f, tuple(args), frozenset(kwargs.items()) ) |
| 625 | + if key not in cache: |
| 626 | + cache[key] = f(*args, **kwargs) |
| 627 | + return cache[key] |
| 628 | + return g |
| 629 | + |
564 | 630 | def paramToDict(place, parameters=None): |
565 | 631 | """ |
566 | 632 | Split the parameters into names and values, check if these parameters |
@@ -1266,7 +1332,7 @@ def parseUnionPage(output, expression, partial=False, condition=None, sort=True) |
1266 | 1332 | if output is None: |
1267 | 1333 | return None |
1268 | 1334 |
|
1269 | | - data = [] |
| 1335 | + data = BigArray() |
1270 | 1336 |
|
1271 | 1337 | outCond1 = ( output.startswith(kb.misc.start) and output.endswith(kb.misc.stop) ) |
1272 | 1338 | outCond2 = ( output.startswith(DUMP_START_MARKER) and output.endswith(DUMP_STOP_MARKER) ) |
@@ -2204,6 +2270,7 @@ def isNumPosStrValue(value): |
2204 | 2270 |
|
2205 | 2271 | return value and isinstance(value, basestring) and value.isdigit() and value != "0" |
2206 | 2272 |
|
| 2273 | +@cachedmethod |
2207 | 2274 | def aliasToDbmsEnum(dbms): |
2208 | 2275 | """ |
2209 | 2276 | Returns major DBMS name from a given alias |
@@ -2730,8 +2797,8 @@ def isNoneValue(value): |
2730 | 2797 | if len(value) == 1: |
2731 | 2798 | return isNoneValue(value[0]) |
2732 | 2799 | else: |
2733 | | - for i in xrange(len(value)): |
2734 | | - if value[i] and value[i] != "None": |
| 2800 | + for item in value: |
| 2801 | + if item and item != "None": |
2735 | 2802 | return False |
2736 | 2803 | return True |
2737 | 2804 | elif isinstance(value, dict): |
|
0 commit comments