1 from cStringIO import StringIO
5 from bup import hashsplit, _helpers, helpers
8 def nr_regions(x, max_count=None):
9 return list(hashsplit._nonresident_page_regions(bytearray(x), 1, max_count))
13 def test_nonresident_page_regions():
14 WVPASSEQ(nr_regions([]), [])
15 WVPASSEQ(nr_regions([1]), [])
16 WVPASSEQ(nr_regions([0]), [(0, 1)])
17 WVPASSEQ(nr_regions([1, 0]), [(1, 1)])
18 WVPASSEQ(nr_regions([0, 0]), [(0, 2)])
19 WVPASSEQ(nr_regions([1, 0, 1]), [(1, 1)])
20 WVPASSEQ(nr_regions([1, 0, 0]), [(1, 2)])
21 WVPASSEQ(nr_regions([0, 1, 0]), [(0, 1), (2, 1)])
22 WVPASSEQ(nr_regions([0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0]),
23 [(0, 2), (5, 3), (9, 2)])
24 WVPASSEQ(nr_regions([2, 42, 3, 101]), [(0, 2)])
26 WVPASSEQ(nr_regions([0, 0, 0], None), [(0, 3)])
27 WVPASSEQ(nr_regions([0, 0, 0], 1), [(0, 1), (1, 1), (2, 1)])
28 WVPASSEQ(nr_regions([0, 0, 0], 2), [(0, 2), (2, 1)])
29 WVPASSEQ(nr_regions([0, 0, 0], 3), [(0, 3)])
30 WVPASSEQ(nr_regions([0, 0, 0], 4), [(0, 3)])
31 WVPASSEQ(nr_regions([0, 0, 1], None), [(0, 2)])
32 WVPASSEQ(nr_regions([0, 0, 1], 1), [(0, 1), (1, 1)])
33 WVPASSEQ(nr_regions([0, 0, 1], 2), [(0, 2)])
34 WVPASSEQ(nr_regions([0, 0, 1], 3), [(0, 2)])
35 WVPASSEQ(nr_regions([1, 0, 0], None), [(1, 2)])
36 WVPASSEQ(nr_regions([1, 0, 0], 1), [(1, 1), (2, 1)])
37 WVPASSEQ(nr_regions([1, 0, 0], 2), [(1, 2)])
38 WVPASSEQ(nr_regions([1, 0, 0], 3), [(1, 2)])
39 WVPASSEQ(nr_regions([1, 0, 0, 0, 1], None), [(1, 3)])
40 WVPASSEQ(nr_regions([1, 0, 0, 0, 1], 1), [(1, 1), (2, 1), (3, 1)])
41 WVPASSEQ(nr_regions([1, 0, 0, 0, 1], 2), [(1, 2), (3, 1)])
42 WVPASSEQ(nr_regions([1, 0, 0, 0, 1], 3), [(1, 3)])
43 WVPASSEQ(nr_regions([1, 0, 0, 0, 1], 4), [(1, 3)])
47 def test_uncache_ours_upto():
49 def mock_fadvise_pages_done(f, ofs, len):
50 history.append((f, ofs, len))
52 uncache_upto = hashsplit._uncache_ours_upto
53 page_size = helpers.sc_page_size
54 orig_pages_done = hashsplit._fadvise_pages_done
56 hashsplit._fadvise_pages_done = mock_fadvise_pages_done
58 uncache_upto(42, 0, (0, 1), iter([]))
60 uncache_upto(42, page_size, (0, 1), iter([]))
61 WVPASSEQ([(42, 0, 1)], history)
63 uncache_upto(42, page_size, (0, 3), iter([(5, 2)]))
65 uncache_upto(42, 2 * page_size, (0, 3), iter([(5, 2)]))
67 uncache_upto(42, 3 * page_size, (0, 3), iter([(5, 2)]))
68 WVPASSEQ([(42, 0, 3)], history)
70 uncache_upto(42, 5 * page_size, (0, 3), iter([(5, 2)]))
71 WVPASSEQ([(42, 0, 3)], history)
73 uncache_upto(42, 6 * page_size, (0, 3), iter([(5, 2)]))
74 WVPASSEQ([(42, 0, 3)], history)
76 uncache_upto(42, 7 * page_size, (0, 3), iter([(5, 2)]))
77 WVPASSEQ([(42, 0, 3), (42, 5, 2)], history)
79 hashsplit._fadvise_pages_done = orig_pages_done
83 def test_rolling_sums():
84 WVPASS(_helpers.selftest())
87 def test_fanout_behaviour():
89 # Drop in replacement for bupsplit, but splitting if the int value of a
90 # byte >= BUP_BLOBBITS
91 basebits = _helpers.blobbits()
96 if ord(c) >= basebits:
100 old_splitbuf = _helpers.splitbuf
101 _helpers.splitbuf = splitbuf
102 old_BLOB_MAX = hashsplit.BLOB_MAX
103 hashsplit.BLOB_MAX = 4
104 old_BLOB_READ_SIZE = hashsplit.BLOB_READ_SIZE
105 hashsplit.BLOB_READ_SIZE = 10
106 old_fanout = hashsplit.fanout
109 levels = lambda f: [(len(b), l) for b, l in
110 hashsplit.hashsplit_iter([f], True, None)]
111 # Return a string of n null bytes
112 z = lambda n: '\x00' * n
113 # Return a byte which will be split with a level of n
114 sb = lambda n: chr(basebits + n)
116 split_never = StringIO(z(16))
117 split_first = StringIO(z(1) + sb(3) + z(14))
118 split_end = StringIO(z(13) + sb(1) + z(2))
119 split_many = StringIO(sb(1) + z(3) + sb(2) + z(4) +
120 sb(0) + z(4) + sb(5) + z(1))
121 WVPASSEQ(levels(split_never), [(4, 0), (4, 0), (4, 0), (4, 0)])
122 WVPASSEQ(levels(split_first), [(2, 3), (4, 0), (4, 0), (4, 0), (2, 0)])
123 WVPASSEQ(levels(split_end), [(4, 0), (4, 0), (4, 0), (2, 1), (2, 0)])
124 WVPASSEQ(levels(split_many),
125 [(1, 1), (4, 2), (4, 0), (1, 0), (4, 0), (1, 5), (1, 0)])
127 _helpers.splitbuf = old_splitbuf
128 hashsplit.BLOB_MAX = old_BLOB_MAX
129 hashsplit.BLOB_READ_SIZE = old_BLOB_READ_SIZE
130 hashsplit.fanout = old_fanout