Skip to content

Commit 079a627

Browse files
committed
add array capacity
1 parent 2ea5333 commit 079a627

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

karchive/array.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@
55
from .blob import BLOCK, OFFSET
66
from .blob import ZERO_BLOCK, BLOCK_MASK, BLOCK_SIZE
77

8-
MAX_SMALL = (1<<12) - len(Blob.HEADER) * 4
9-
108
class Array(Blob):
9+
10+
HEADER = dict((k, i) for i, k in enumerate([
11+
'capacity',
12+
'length',
13+
'num_blocks',
14+
'type',
15+
'checksum', # must be last
16+
]))
17+
1118
def __init__(self, host, root, format, new):
1219
super(Array, self).__init__(host, root, new)
1320
self.format = format
@@ -51,28 +58,33 @@ def __setitem__(self, i, v):
5158
# TODO cache this
5259
b.cast(self.format)[k] = v
5360

61+
def extend(self, iter):
62+
raise NotImplementedError
63+
5464
def append(self, v):
5565
l = self.length
56-
j = l + 1
57-
self.resize(j)
66+
assert self.capacity >= l + 1
67+
self.length += 1
5868
self[l] = v
69+
# ensure 1 extra slot
70+
self.resize(l + 2)
5971

6072
def pop(self):
6173
if not self.length:
6274
raise IndexError
6375
l = self.length
6476
j = l - 1
6577
x = self[j]
66-
self.resize(j)
78+
self.resize(l + 2)
6779
return x
6880

69-
def resize(self, items):
81+
def resize(self, capacity):
7082
'''
7183
Resizes the array to a given size (in elements, not bytes)
7284
'''
7385
# requested size fits in a small block
7486
# handles both grow and shrink operation
75-
length = items * self.item_size
87+
length = capacity * self.item_size
7688

7789
if length <= MAX_SMALL:
7890
if self.type == REGULAR_BLOB:
@@ -90,7 +102,7 @@ def resize(self, items):
90102
# no zero fill when growing, since we assume the block was
91103
# zeroed either above or on blob creation
92104
self.type = SMALL_BLOB
93-
self.length = items
105+
self.capacity = items
94106
self.flush_root()
95107
return
96108

@@ -106,15 +118,15 @@ def resize(self, items):
106118
b = self.get_block(i)
107119
s = slice(OFFSET(length), BLOCK_SIZE)
108120
b[s] = ZERO_BLOCK[s]
109-
self.length = items
121+
self.capacity = items
110122
self.flush_root()
111123
return
112124

113125
data = None
114126
if self.type == SMALL_BLOB:
115127
data = bytes(self.host[self.root][0:self.length * self.item_size])
116128
self.type = REGULAR_BLOB
117-
self.length = 0
129+
self.capacity = 0
118130

119131
# allocate/free blocks
120132
# may call append/pop!

0 commit comments

Comments
 (0)