def __init__(self, **kwds): super(NumericIndex, self).__init__(**kwds) self.skipList = SkipList(self) self._ranges = None self._descending = False if not kwds.get('loading', False): if 'ranges' in kwds: self._ranges = RangeSet(kwds.pop('ranges')) self._descending = str(kwds.pop('descending', 'False')) == 'True'
def _fill(self, count): p = None class _index(dict): def _keyChanged(self, key): pass map = _index() sl = SkipList(map) for i in xrange(0, count): sl.insert(i, p) p = i return (sl, map)
class NumericIndex(Index): """ This implementation of a numeric index is not persisted, it is reconstructed when the owning item is loaded. The persistence layer is responsible for providing persisted implementations. """ def __init__(self, **kwds): super(NumericIndex, self).__init__(**kwds) self.skipList = SkipList(self) self._ranges = None self._descending = False if not kwds.get('loading', False): if 'ranges' in kwds: self._ranges = RangeSet(kwds.pop('ranges')) self._descending = str(kwds.pop('descending', 'False')) == 'True' def validateIndex(self, valid, insertMissing=False, subIndexes=True): self.skipList.validate(valid) def isValid(self): return self.skipList.isValid() def setDescending(self, descending=True): wasDescending = self._descending self._descending = descending return wasDescending def isDescending(self): return self._descending def _keyChanged(self, key): pass def setRanges(self, ranges): if ranges is None: self._ranges = None else: self._ranges = RangeSet(ranges) assert self._ranges.rangesAreValid() def getRanges(self): ranges = self._ranges if ranges is not None: return ranges.ranges return None def isInRanges(self, range): ranges = self._ranges if ranges is None: return False return ranges.isSelected(range) def addRange(self, range): if self._ranges is None: if isinstance(range, int): range = (range, range) self._ranges = RangeSet([range]) else: self._ranges.selectRange(range) def removeRange(self, range): if self._ranges is not None: self._ranges.unSelectRange(range) def getKey(self, n): if self._descending: return self.skipList[self._count - n - 1] else: return self.skipList[n] def getPosition(self, key): if self._descending: return self._count - self.skipList.position(key) - 1 else: return self.skipList.position(key) def getFirstKey(self): if self._descending: return self.skipList.last() else: return self.skipList.first() def getNextKey(self, key): if self._descending: return self.skipList.previous(key) else: return self.skipList.next(key) def getPreviousKey(self, key): if self._descending: return self.skipList.next(key) else: return self.skipList.previous(key) def getLastKey(self): if self._descending: return self.skipList.first() else: return self.skipList.last() def getIndexType(self): return 'numeric' def getInitKeywords(self): kwds = {} if self._ranges is not None: kwds['ranges'] = self._ranges.ranges if self._descending: kwds['descending'] = self._descending return kwds # key: None -> first, Default -> last def insertKey(self, key, afterKey=Default, selected=False, _setadd=False): skipList = self.skipList if afterKey is Default: afterKey = skipList.last() skipList.insert(key, afterKey) self._keyChanged(key) super(NumericIndex, self).insertKey(key, afterKey) ranges = self._ranges if ranges is not None: pos = self.getPosition(key) ranges.onInsert(key, pos) if selected: ranges.selectRange(pos) # if afterKey is None, move to the beginning of the index # if afterKey is Default, don't move the key (insert only) # if afterKey is None, move to the beginning of the index # if afterKey is Default, don't move the key (insert only) # if insertMissing is None, raise error if key not present # if insertMissing is False, skip key if key not present def moveKey(self, key, afterKey=None, insertMissing=None): if key not in self: if insertMissing: self.insertKey(key, afterKey) elif insertMissing is None: raise KeyError, key elif afterKey is not Default: ranges = self._ranges if ranges is not None: ranges.onRemove(key, self.getPosition(key)) self.skipList.move(key, afterKey) self._keyChanged(key) if ranges is not None: ranges.onInsert(key, self.getPosition(key)) super(NumericIndex, self).moveKey(key, afterKey) def moveKeys(self, keys, afterKey=None, insertMissing=None): for key in keys: self.moveKey(key, afterKey, insertMissing) def removeKey(self, key): if key in self: ranges = self._ranges if ranges is not None: pos = self.getPosition(key) selected = ranges.isSelected(pos) ranges.onRemove(key, pos) else: selected = False self.skipList.remove(key) return super(NumericIndex, self).removeKey(key), selected return False, False def removeKeys(self, keys): removed = False for key in keys: removed, selected = self.removeKey(key) return removed def clear(self): key = self.getFirstKey() while key is not None: next = self.getNextKey(key) self.removeKey(key) key = next def _writeValue(self, itemWriter, record, version): super(NumericIndex, self)._writeValue(itemWriter, record, version) if self._ranges is not None: ranges = self._ranges.ranges record += (Record.BYTE, 1, Record.INT, len(ranges)) for s, e in ranges: record += (Record.INT, s, Record.INT, e) else: record += (Record.BYTE, 0) record += (Record.BOOLEAN, self._descending) def _readValue(self, itemReader, offset, data): offset = super(NumericIndex, self)._readValue(itemReader, offset, data) withRanges = data[offset] offset += 1 if withRanges: count = data[offset] * 2 offset += 1 ranges = [data[i:i+2] for i in xrange(offset, offset+count, 2)] self._ranges = RangeSet(ranges) offset += count else: self._ranges = None self._descending = data[offset] return offset + 1
class NumericIndex(Index): """ This implementation of a numeric index is not persisted, it is reconstructed when the owning item is loaded. The persistence layer is responsible for providing persisted implementations. """ def __init__(self, **kwds): super(NumericIndex, self).__init__(**kwds) self.skipList = SkipList(self) self._ranges = None self._descending = False if not kwds.get('loading', False): if 'ranges' in kwds: self._ranges = RangeSet(kwds.pop('ranges')) self._descending = str(kwds.pop('descending', 'False')) == 'True' def validateIndex(self, valid, insertMissing=False, subIndexes=True): self.skipList.validate(valid) def isValid(self): return self.skipList.isValid() def setDescending(self, descending=True): wasDescending = self._descending self._descending = descending return wasDescending def isDescending(self): return self._descending def _keyChanged(self, key): pass def setRanges(self, ranges): if ranges is None: self._ranges = None else: self._ranges = RangeSet(ranges) assert self._ranges.rangesAreValid() def getRanges(self): ranges = self._ranges if ranges is not None: return ranges.ranges return None def isInRanges(self, range): ranges = self._ranges if ranges is None: return False return ranges.isSelected(range) def addRange(self, range): if self._ranges is None: if isinstance(range, int): range = (range, range) self._ranges = RangeSet([range]) else: self._ranges.selectRange(range) def removeRange(self, range): if self._ranges is not None: self._ranges.unSelectRange(range) def getKey(self, n): if self._descending: return self.skipList[self._count - n - 1] else: return self.skipList[n] def getPosition(self, key): if self._descending: return self._count - self.skipList.position(key) - 1 else: return self.skipList.position(key) def getFirstKey(self): if self._descending: return self.skipList.last() else: return self.skipList.first() def getNextKey(self, key): if self._descending: return self.skipList.previous(key) else: return self.skipList.next(key) def getPreviousKey(self, key): if self._descending: return self.skipList.next(key) else: return self.skipList.previous(key) def getLastKey(self): if self._descending: return self.skipList.first() else: return self.skipList.last() def getIndexType(self): return 'numeric' def getInitKeywords(self): kwds = {} if self._ranges is not None: kwds['ranges'] = self._ranges.ranges if self._descending: kwds['descending'] = self._descending return kwds # key: None -> first, Default -> last def insertKey(self, key, afterKey=Default, selected=False, _setadd=False): skipList = self.skipList if afterKey is Default: afterKey = skipList.last() skipList.insert(key, afterKey) self._keyChanged(key) super(NumericIndex, self).insertKey(key, afterKey) ranges = self._ranges if ranges is not None: pos = self.getPosition(key) ranges.onInsert(key, pos) if selected: ranges.selectRange(pos) # if afterKey is None, move to the beginning of the index # if afterKey is Default, don't move the key (insert only) # if afterKey is None, move to the beginning of the index # if afterKey is Default, don't move the key (insert only) # if insertMissing is None, raise error if key not present # if insertMissing is False, skip key if key not present def moveKey(self, key, afterKey=None, insertMissing=None): if key not in self: if insertMissing: self.insertKey(key, afterKey) elif insertMissing is None: raise KeyError, key elif afterKey is not Default: ranges = self._ranges if ranges is not None: ranges.onRemove(key, self.getPosition(key)) self.skipList.move(key, afterKey) self._keyChanged(key) if ranges is not None: ranges.onInsert(key, self.getPosition(key)) super(NumericIndex, self).moveKey(key, afterKey) def moveKeys(self, keys, afterKey=None, insertMissing=None): for key in keys: self.moveKey(key, afterKey, insertMissing) def removeKey(self, key): if key in self: ranges = self._ranges if ranges is not None: pos = self.getPosition(key) selected = ranges.isSelected(pos) ranges.onRemove(key, pos) else: selected = False self.skipList.remove(key) return super(NumericIndex, self).removeKey(key), selected return False, False def removeKeys(self, keys): removed = False for key in keys: removed, selected = self.removeKey(key) return removed def clear(self): key = self.getFirstKey() while key is not None: next = self.getNextKey(key) self.removeKey(key) key = next def _writeValue(self, itemWriter, record, version): super(NumericIndex, self)._writeValue(itemWriter, record, version) if self._ranges is not None: ranges = self._ranges.ranges record += (Record.BYTE, 1, Record.INT, len(ranges)) for s, e in ranges: record += (Record.INT, s, Record.INT, e) else: record += (Record.BYTE, 0) record += (Record.BOOLEAN, self._descending) def _readValue(self, itemReader, offset, data): offset = super(NumericIndex, self)._readValue(itemReader, offset, data) withRanges = data[offset] offset += 1 if withRanges: count = data[offset] * 2 offset += 1 ranges = [data[i:i + 2] for i in xrange(offset, offset + count, 2)] self._ranges = RangeSet(ranges) offset += count else: self._ranges = None self._descending = data[offset] return offset + 1