Package grassyknoll :: Package backend :: Package lucene :: Module HitsWrapper
[hide private]

Source Code for Module grassyknoll.backend.lucene.HitsWrapper

 1  """containts L{HitsWrapper}""" 
 2  from itertools import islice 
 3   
4 -class HitsWrapper(object):
5 """a L{lucene.Hits} delegator that yields L{SmartHit} subclasses 6 7 We support open intervals of the form hits[10:], but you almost certainly 8 don't want to do this, as it will be slow. 9 10 @warning: Instances of this class are not threadsafe. 11 """ 12 13 __slots__=['__hits', '__class', '__cache', '__hits_iter'] 14
15 - def __init__(self, hits, klass):
16 """ 17 @arg hits: the raw hits to wrap 18 @type hits: L{lucene.Hits} 19 20 @arg klass: type of hit to yield up 21 @type klass: class 22 """ 23 self.__hits=hits 24 self.__hits_iter=iter(hits) 25 self.__class=klass 26 self.__cache=[]
27
28 - def __getattr__(self, attr):
29 return getattr(self.__hits, attr)
30
31 - def __len__(self):
32 return len(self.__hits)
33 34 # XXX everything below is dramatically not threadsafe
35 - def __extend_cache(self, n):
36 """extend the internal cache s.t. it contains n elements 37 38 the cache may contain less than n elements after calling this method if 39 the underlying hits are exhausted. 40 """ 41 # unbounded slice - exhaust hits_iter 42 if n is None: 43 self.__cache.extend(self.__class(raw_hit) for raw_hit in self.__hits_iter) 44 return 45 46 # bounded - if cache is long enough, just return 47 if len(self.__cache) > n: return 48 49 # bounded - extend cache to length n+1 (s.t. there is an element cache[n]) 50 self.__cache.extend(self.__class(raw_hit) for raw_hit in 51 islice(self.__hits_iter, n-len(self.__cache)+1))
52
53 - def __getitem__(self, x):
54 ## we only support getting items from the left. Getting items from the 55 ## right is: 56 ## 1) difficult to do correctly 57 ## 2) absurdly slow 58 59 ## XXX if you really want to get items from the right, you should 60 ## reverse the sort of your underlying query. 61 62 if isinstance(x, (int, long)): 63 if x < 0: 64 raise IndexError("negative indices not supported", x) 65 elif x >= len(self): 66 raise IndexError, x 67 else: 68 end=x 69 elif isinstance(x, slice): 70 if (x.start is not None and x.start < 0) or \ 71 (x.stop is not None and x.stop < 0) or \ 72 (x.step is not None and x.step < 0): 73 raise IndexError("negative slices not supported", x) 74 elif x.start >= len(self): 75 return [] 76 else: 77 end=x.stop 78 if end is not None: end-=1 79 else: 80 raise TypeError, "indices must be integers" 81 82 self.__extend_cache(end) 83 return self.__cache[x]
84
85 - def __iter__(self):
86 n=-1 87 while 1: 88 n+=1 89 if n < len(self.__cache): 90 yield self.__cache[n] 91 else: 92 self.__extend_cache(n) 93 if n < len(self.__cache): 94 yield self.__cache[n] 95 else: 96 return
97