Exemple #1
0
 def __init__(self, file, max_oid=-2, max_offset=0):
     self.start = file.tell()
     file.seek(0, 2)
     if file.tell() == self.start:
         for step in self.__class__.generate(file, max_oid, max_offset):
             pass
     file.seek(self.start)
     self.int_array = IntArray(file=file)
Exemple #2
0
 def a(self):
     s = BytesIO()
     for sample in ([], [0], [2, 1], range(7)):
         int_array = IntArray(file=s, number_of_ints=10, maximum_int=10)
         for j, x in enumerate(sample):
             int_array[j] = x
         non_blanks = set(int_array)
         non_blanks.discard(int_array.get_blank_value())
         assert set(sample) == non_blanks, (list(int_array), sample)
     assert raises(IndexError, int_array.__getitem__, 10)
     int_array2 = IntArray(file=BytesIO(s.getvalue()))
     int_array3 = IntArray(number_of_ints=10, maximum_int=300)
     for x in range(10):
         assert int_array3.get(x) == None
     assert int_array3[1] == int_array3.get_blank_value()
     int_array3[1] = 42
     assert int_array3.get(1)== 42
     assert len(int_array3) == 10
     raises(ValueError, int_array3.__setitem__, 2, 100000)
     int_array4 = IntArray(number_of_ints=10)
     assert int_array4.get(1, default=42) == 42
     assert int_array4.get(100, default=42) == 42
     assert list(iteritems(int_array4)) == []
     int_array4[3] = 4
     int_array4[8] = 9
     assert list(iteritems(int_array4)) == [(3, 4), (8, 9)]
Exemple #3
0
 def generate(file, max_oid=-2, max_offset=0):
     start = file.tell()
     assert max_offset < start
     for step in IntArray.generate(file=file, number_of_ints=max_oid + 2,
         maximum_int=start + max_oid + 2):
         yield step
     file.seek(start)
Exemple #4
0
 def generate(file, max_oid=-2, max_offset=0):
     start = file.tell()
     assert max_offset < start
     for step in IntArray.generate(file=file,
                                   number_of_ints=max_oid + 2,
                                   maximum_int=start + max_oid + 2):
         yield step
     file.seek(start)
Exemple #5
0
 def __init__(self, file, max_oid=-2, max_offset=0):
     self.start = file.tell()
     file.seek(0, 2)
     if file.tell() == self.start:
         for step in self.__class__.generate(file, max_oid, max_offset):
             pass
     file.seek(self.start)
     self.int_array = IntArray(file=file)
Exemple #6
0
class OffsetMap(object):
    """
    An offset map holds the offsets for a set of oids.
    It uses an inner array to hold the offsets.  It does not actually
    store any oids.  Instead it uses oids as indices into an array
    that is big enough to hold all oids.  The array will probably have
    more slots than we have oids.  We call the unused slots holes, and
    this class gives us a way to iterate over the holes, so that they
    can be allocated when oids are needed for new objects.
    """
    def __init__(self, file, max_oid=-2, max_offset=0):
        self.start = file.tell()
        file.seek(0, 2)
        if file.tell() == self.start:
            for step in self.__class__.generate(file, max_oid, max_offset):
                pass
        file.seek(self.start)
        self.int_array = IntArray(file=file)

    @staticmethod
    def generate(file, max_oid=-2, max_offset=0):
        start = file.tell()
        assert max_offset < start
        for step in IntArray.generate(file=file,
                                      number_of_ints=max_oid + 2,
                                      maximum_int=start + max_oid + 2):
            yield step
        file.seek(start)

    def get_start(self):
        return self.start

    def get(self, j, default=None):
        result = self.int_array.get(j, default=None)
        if result is None or result >= self.start:
            return default
        else:
            return result

    def __getitem__(self, j):
        result = self.get(j)
        if result is None:
            raise IndexError(j)
        else:
            return result

    def __setitem__(self, j, value):
        """
        Note that this is not called after self.gen_stitch() is consumed.
        We don't overwrite any non-blank values.
        """
        assert self.get(j) is None
        self.int_array[j] = value

    def __iter__(self):
        for j, number in enumerate(self.int_array):
            if number < self.start:
                yield j

    def iteritems(self):
        for j, number in enumerate(self.int_array):
            if number < self.start:
                yield j, number

    items = iteritems

    def get_array_size(self):
        """() -> int
        Note that this is the total capacity of the array.
        """
        return len(self.int_array)

    def gen_stitch(self):
        """
        Return a generator that does the following as it is consumed.
        Build the linked list of holes.
        Each value is the index of the next hole plus self.start.
        The offset is added so that we can distinguish ordinary offsets,
        which are less than self.start, from elements of this linked list.
        """
        last_index = len(self.int_array) - 1
        for index in xrange(0, len(self.int_array)):
            if self.get(index) is None:
                self.int_array[index] = last_index + self.start
                last_index = index
            yield index

    def gen_holes(self):
        """Generate the sequence of holes."""
        last_index = len(self.int_array) - 1
        if last_index >= 0:
            j = last_index
            while True:
                new_j = self.int_array[j] - self.start
                yield new_j
                if new_j == last_index:
                    break
                j = new_j
Exemple #7
0
class OffsetMap (object):
    """
    An offset map holds the offsets for a set of oids.
    It uses an inner array to hold the offsets.  It does not actually
    store any oids.  Instead it uses oids as indices into an array
    that is big enough to hold all oids.  The array will probably have
    more slots than we have oids.  We call the unused slots holes, and
    this class gives us a way to iterate over the holes, so that they
    can be allocated when oids are needed for new objects.
    """
    def __init__(self, file, max_oid=-2, max_offset=0):
        self.start = file.tell()
        file.seek(0, 2)
        if file.tell() == self.start:
            for step in self.__class__.generate(file, max_oid, max_offset):
                pass
        file.seek(self.start)
        self.int_array = IntArray(file=file)

    @staticmethod
    def generate(file, max_oid=-2, max_offset=0):
        start = file.tell()
        assert max_offset < start
        for step in IntArray.generate(file=file, number_of_ints=max_oid + 2,
            maximum_int=start + max_oid + 2):
            yield step
        file.seek(start)

    def get_start(self):
        return self.start

    def get(self, j, default=None):
        result = self.int_array.get(j, default=None)
        if result is None or result >= self.start:
            return default
        else:
            return result

    def __getitem__(self, j):
        result = self.get(j)
        if result is None:
            raise IndexError(j)
        else:
            return result

    def __setitem__(self, j, value):
        """
        Note that this is not called after self.gen_stitch() is consumed.
        We don't overwrite any non-blank values.
        """
        assert self.get(j) is None
        self.int_array[j] = value

    def __iter__(self):
        for j, number in enumerate(self.int_array):
            if number < self.start:
                yield j

    def iteritems(self):
        for j, number in enumerate(self.int_array):
            if number < self.start:
                yield j, number

    items = iteritems

    def get_array_size(self):
        """() -> int
        Note that this is the total capacity of the array.
        """
        return len(self.int_array)

    def gen_stitch(self):
        """
        Return a generator that does the following as it is consumed.
        Build the linked list of holes.
        Each value is the index of the next hole plus self.start.
        The offset is added so that we can distinguish ordinary offsets,
        which are less than self.start, from elements of this linked list.
        """
        last_index = len(self.int_array) - 1
        for index in xrange(0, len(self.int_array)):
            if self.get(index) is None:
                self.int_array[index] = last_index + self.start
                last_index = index
            yield index

    def gen_holes(self):
        """Generate the sequence of holes."""
        last_index = len(self.int_array) - 1
        if last_index >= 0:
            j = last_index
            while True:
                new_j = self.int_array[j] - self.start
                yield new_j
                if new_j == last_index:
                    break
                j = new_j