1.1 --- a/iixr/data.py Tue Feb 08 00:08:27 2011 +0100
1.2 +++ b/iixr/data.py Thu Feb 10 01:19:13 2011 +0100
1.3 @@ -35,14 +35,23 @@
1.4 last = current
1.5 i += 1
1.6
1.7 +def op_seq_monotonic(x, y, op):
1.8 + return tuple([op(a, b) for a, b in zip(x, y)])
1.9 +
1.10 def add_seq_monotonic(x, y):
1.11 return op_seq_monotonic(x, y, operator.add)
1.12
1.13 def sub_seq_monotonic(x, y):
1.14 return op_seq_monotonic(x, y, operator.sub)
1.15
1.16 -def op_seq_monotonic(x, y, op):
1.17 - return tuple([op(a, b) for a, b in zip(x, y)])
1.18 +def op_first_monotonic(x, y, op):
1.19 + return (op(x[0], y[0]),) + tuple(zip(x[1:], y[1:]))
1.20 +
1.21 +def add_first_monotonic(x, y):
1.22 + return op_first_monotonic(x, y, operator.add)
1.23 +
1.24 +def sub_first_monotonic(x, y):
1.25 + return op_first_monotonic(x, y, operator.sub)
1.26
1.27 def add_seq(x, y):
1.28 length = min(len(x), len(y))
1.29 @@ -72,6 +81,9 @@
1.30 def is_sequence(value):
1.31 return isinstance(value, (list, tuple))
1.32
1.33 +def sizeof(value):
1.34 + return is_sequence(value) and len(value) or 0
1.35 +
1.36 def get_monotonic_adder(value):
1.37 return is_sequence(value) and add_seq_monotonic or operator.add
1.38
1.39 @@ -176,26 +188,28 @@
1.40
1.41 # Sequence serialisation.
1.42
1.43 -def sequence_to_array(value, bytes):
1.44 +def sequence_to_array(value, size, bytes):
1.45
1.46 - "Write the given sequence 'value' to 'bytes'."
1.47 + "Write the given sequence 'value' with the given 'size' to 'bytes'."
1.48
1.49 - size = is_sequence(value) and len(value) or 0
1.50 - vint_to_array(size, bytes)
1.51 if size:
1.52 - for a in value:
1.53 - vint_to_array(a, bytes)
1.54 + i = 0
1.55 + limit = min(len(value), size)
1.56 + while i < limit:
1.57 + vint_to_array(value[i], bytes)
1.58 + i += 1
1.59 + while i < size:
1.60 + vint_to_array(0, bytes)
1.61 else:
1.62 vint_to_array(value, bytes)
1.63
1.64 -def sequence_from_array(bytes, start=0):
1.65 +def sequence_from_array(bytes, size, start=0):
1.66
1.67 """
1.68 - Read a sequence from 'bytes', returning the sequence and the first position
1.69 - after the sequence.
1.70 + Read a sequence from 'bytes' having the given 'size', returning the sequence
1.71 + and the first position after the sequence.
1.72 """
1.73
1.74 - size, start = vint_from_array_start(bytes, start)
1.75 if size:
1.76 j = 0
1.77 value = []