def setRanges(self, ranges):

        if ranges is None:
            self._ranges = None
        else:
            self._ranges = RangeSet(ranges)
            assert self._ranges.rangesAreValid()
    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 __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'
Example #4
0
    def setRanges(self, ranges):

        if ranges is None:
            self._ranges = None
        else:
            self._ranges = RangeSet(ranges)
            assert self._ranges.rangesAreValid()
Example #5
0
    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 _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
Example #7
0
    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'
Example #8
0
    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
Example #9
0
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