# This test works by initializing a set of UintBuilders at configured logical
# widths and setting the same elements to the same indexes. The builders' Sizes
# are queried for various row sizes. Individual builders of specific widths may
# be finished separately so the test can continue with testing higher-width
# integers.

# Test a default-zero builder that only contains zeros.

init default-zero
----

size rows=100
----
Size(100, 0) = 1

get indices=(0, 10, 99)
----
b.Get(0) = 0
b.Get(10) = 0
b.Get(99) = 0

finish rows=100
----
uints
 └── 0-1: x 00 # encoding: zero

finish rows=10
----
uints
 └── 0-1: x 00 # encoding: zero

init
----

# Write a few zero values at index [0,4].

write
0:0 1:0 2:0 3:0 4:0
----

# At all row counts, the column should be encoded as a constant using the column
# type width.

size rows=(5, 4, 3, 2, 1, 0)
----
Size(5, 0) = 1
Size(4, 0) = 1
Size(3, 0) = 1
Size(2, 0) = 1
Size(1, 0) = 1
Size(0, 0) = 0

# Add a nonzero value. Size calls that include the new row count should
# increase, but the size calls that don't include the new row count should not.
# The increased sizes should reflect use of a uint8 delta encoding.

finish rows=8
----
uints
 └── 0-1: x 00 # encoding: zero

write
5:10
6:0
7:10
----

size rows=(8, 7, 6, 5, 4, 3, 2, 1, 0)
----
Size(8, 0) = 9
Size(7, 0) = 8
Size(6, 0) = 7
Size(5, 0) = 1
Size(4, 0) = 1
Size(3, 0) = 1
Size(2, 0) = 1
Size(1, 0) = 1
Size(0, 0) = 0

get indices=(0, 5, 6, 7)
----
b.Get(0) = 0
b.Get(5) = 10
b.Get(6) = 0
b.Get(7) = 10

# Check width=8 encoding.
finish rows=8
----
uints
 ├── 0-1: x 01 # encoding: 1b
 ├── 1-2: x 00 # data[0] = 0
 ├── 2-3: x 00 # data[1] = 0
 ├── 3-4: x 00 # data[2] = 0
 ├── 4-5: x 00 # data[3] = 0
 ├── 5-6: x 00 # data[4] = 0
 ├── 6-7: x 0a # data[5] = 10
 ├── 7-8: x 00 # data[6] = 0
 └── 8-9: x 0a # data[7] = 10

# Add 1000 which should force a 16-bit encoding.

write
8:1000
----

size rows=(9, 8)
----
Size(9, 0) = 20
Size(8, 0) = 9

size rows=(9, 8) offset=1
----
Size(9, 1) = 20 [19 w/o offset]
Size(8, 1) = 10 [9 w/o offset]

size rows=(9, 8) offset=2
----
Size(9, 2) = 22 [20 w/o offset]
Size(8, 2) = 11 [9 w/o offset]

size rows=(9, 8) offset=5
----
Size(9, 5) = 24 [19 w/o offset]
Size(8, 5) = 14 [9 w/o offset]

# We should be able to write up to 2^16-1 without triggering a 32-bit encoding.

write
9:65535
----

size rows=(10, 9, 8)
----
Size(10, 0) = 22
Size(9, 0) = 20
Size(8, 0) = 9

finish rows=10
----
uints
 ├── 00-01: x 02   # encoding: 2b
 ├── 01-02: x 00   # padding (aligning to 16-bit boundary)
 ├── 02-04: x 0000 # data[0] = 0
 ├── 04-06: x 0000 # data[1] = 0
 ├── 06-08: x 0000 # data[2] = 0
 ├── 08-10: x 0000 # data[3] = 0
 ├── 10-12: x 0000 # data[4] = 0
 ├── 12-14: x 0a00 # data[5] = 10
 ├── 14-16: x 0000 # data[6] = 0
 ├── 16-18: x 0a00 # data[7] = 10
 ├── 18-20: x e803 # data[8] = 1000
 └── 20-22: x ffff # data[9] = 65535

# 2^16 should trigger a 32-bit encoding.
#
write
10:65536
----

size rows=(11, 10, 9, 8)
----
Size(11, 0) = 48
Size(10, 0) = 22
Size(9, 0) = 20
Size(8, 0) = 9

# We should be able to write up to 2^32-1 without triggering a 64-bit encoding.

write
11:4294967295
----

size rows=(12, 11, 10, 9, 8)
----
Size(12, 0) = 52
Size(11, 0) = 48
Size(10, 0) = 22
Size(9, 0) = 20
Size(8, 0) = 9

finish rows=12
----
uints
 ├── 00-01: x 04       # encoding: 4b
 ├── 01-04: x 000000   # padding (aligning to 32-bit boundary)
 ├── 04-08: x 00000000 # data[0] = 0
 ├── 08-12: x 00000000 # data[1] = 0
 ├── 12-16: x 00000000 # data[2] = 0
 ├── 16-20: x 00000000 # data[3] = 0
 ├── 20-24: x 00000000 # data[4] = 0
 ├── 24-28: x 0a000000 # data[5] = 10
 ├── 28-32: x 00000000 # data[6] = 0
 ├── 32-36: x 0a000000 # data[7] = 10
 ├── 36-40: x e8030000 # data[8] = 1000
 ├── 40-44: x ffff0000 # data[9] = 65535
 ├── 44-48: x 00000100 # data[10] = 65536
 └── 48-52: x ffffffff # data[11] = 4294967295

# 2^32 should trigger a 64-bit encoding.
#
write
12:4294967296
----

size rows=(13, 12, 11, 10, 9, 8)
----
Size(13, 0) = 112
Size(12, 0) = 52
Size(11, 0) = 48
Size(10, 0) = 22
Size(9, 0) = 20
Size(8, 0) = 9

finish rows=13
----
uints
 ├── 000-001: x 08               # encoding: 8b
 ├── 001-008: x 00000000000000   # padding (aligning to 64-bit boundary)
 ├── 008-016: x 0000000000000000 # data[0] = 0
 ├── 016-024: x 0000000000000000 # data[1] = 0
 ├── 024-032: x 0000000000000000 # data[2] = 0
 ├── 032-040: x 0000000000000000 # data[3] = 0
 ├── 040-048: x 0000000000000000 # data[4] = 0
 ├── 048-056: x 0a00000000000000 # data[5] = 10
 ├── 056-064: x 0000000000000000 # data[6] = 0
 ├── 064-072: x 0a00000000000000 # data[7] = 10
 ├── 072-080: x e803000000000000 # data[8] = 1000
 ├── 080-088: x ffff000000000000 # data[9] = 65535
 ├── 088-096: x 0000010000000000 # data[10] = 65536
 ├── 096-104: x ffffffff00000000 # data[11] = 4294967295
 └── 104-112: x 0000000001000000 # data[12] = 4294967296

# Repeat the above tests but with a zero default value, and without explicitly
# setting any of the zero values.

init default-zero
----

# At all row counts, the column should be encoded as a constant using the column
# type width.

size rows=(5, 4, 3, 2, 1, 0)
----
Size(5, 0) = 1
Size(4, 0) = 1
Size(3, 0) = 1
Size(2, 0) = 1
Size(1, 0) = 1
Size(0, 0) = 0

# Add a couple nonzero values. Size calls that include the new row count should
# increase, but the size calls that don't include the new row count should not.

write
5:10
7:10
----

size rows=(8, 7, 6, 5, 4, 3, 2, 1, 0)
----
Size(8, 0) = 9
Size(7, 0) = 8
Size(6, 0) = 7
Size(5, 0) = 1
Size(4, 0) = 1
Size(3, 0) = 1
Size(2, 0) = 1
Size(1, 0) = 1
Size(0, 0) = 0

# Finish the b8 so we can test 16-bit encoding.
finish rows=8
----
uints
 ├── 0-1: x 01 # encoding: 1b
 ├── 1-2: x 00 # data[0] = 0
 ├── 2-3: x 00 # data[1] = 0
 ├── 3-4: x 00 # data[2] = 0
 ├── 4-5: x 00 # data[3] = 0
 ├── 5-6: x 00 # data[4] = 0
 ├── 6-7: x 0a # data[5] = 10
 ├── 7-8: x 00 # data[6] = 0
 └── 8-9: x 0a # data[7] = 10

# Add 1000 which should force a 16-bit delta encoding.

write
8:1000
----

size rows=(9, 8)
----
Size(9, 0) = 20
Size(8, 0) = 9

# We should be able to write up to 2^16-1 without triggering a 32-bit encoding.

write
9:65535
----

size rows=(10, 9, 8)
----
Size(10, 0) = 22
Size(9, 0) = 20
Size(8, 0) = 9

finish rows=10
----
uints
 ├── 00-01: x 02   # encoding: 2b
 ├── 01-02: x 00   # padding (aligning to 16-bit boundary)
 ├── 02-04: x 0000 # data[0] = 0
 ├── 04-06: x 0000 # data[1] = 0
 ├── 06-08: x 0000 # data[2] = 0
 ├── 08-10: x 0000 # data[3] = 0
 ├── 10-12: x 0000 # data[4] = 0
 ├── 12-14: x 0a00 # data[5] = 10
 ├── 14-16: x 0000 # data[6] = 0
 ├── 16-18: x 0a00 # data[7] = 10
 ├── 18-20: x e803 # data[8] = 1000
 └── 20-22: x ffff # data[9] = 65535

# 2^16 should trigger a 32-bit encoding.

write
10:65536
----

size rows=(11, 10, 9, 8)
----
Size(11, 0) = 48
Size(10, 0) = 22
Size(9, 0) = 20
Size(8, 0) = 9

# We should be able to write up to 2^32-1 without triggering a 64-bit encoding.

write
11:4294967295
----

size rows=(12, 11, 10, 9, 8)
----
Size(12, 0) = 52
Size(11, 0) = 48
Size(10, 0) = 22
Size(9, 0) = 20
Size(8, 0) = 9

finish rows=12
----
uints
 ├── 00-01: x 04       # encoding: 4b
 ├── 01-04: x 000000   # padding (aligning to 32-bit boundary)
 ├── 04-08: x 00000000 # data[0] = 0
 ├── 08-12: x 00000000 # data[1] = 0
 ├── 12-16: x 00000000 # data[2] = 0
 ├── 16-20: x 00000000 # data[3] = 0
 ├── 20-24: x 00000000 # data[4] = 0
 ├── 24-28: x 0a000000 # data[5] = 10
 ├── 28-32: x 00000000 # data[6] = 0
 ├── 32-36: x 0a000000 # data[7] = 10
 ├── 36-40: x e8030000 # data[8] = 1000
 ├── 40-44: x ffff0000 # data[9] = 65535
 ├── 44-48: x 00000100 # data[10] = 65536
 └── 48-52: x ffffffff # data[11] = 4294967295

# 2^32 should trigger a 64-bit encoding.

write
12:4294967296
----

size rows=(13, 12, 11, 10, 9, 8)
----
Size(13, 0) = 112
Size(12, 0) = 52
Size(11, 0) = 48
Size(10, 0) = 22
Size(9, 0) = 20
Size(8, 0) = 9

finish rows=13
----
uints
 ├── 000-001: x 08               # encoding: 8b
 ├── 001-008: x 00000000000000   # padding (aligning to 64-bit boundary)
 ├── 008-016: x 0000000000000000 # data[0] = 0
 ├── 016-024: x 0000000000000000 # data[1] = 0
 ├── 024-032: x 0000000000000000 # data[2] = 0
 ├── 032-040: x 0000000000000000 # data[3] = 0
 ├── 040-048: x 0000000000000000 # data[4] = 0
 ├── 048-056: x 0a00000000000000 # data[5] = 10
 ├── 056-064: x 0000000000000000 # data[6] = 0
 ├── 064-072: x 0a00000000000000 # data[7] = 10
 ├── 072-080: x e803000000000000 # data[8] = 1000
 ├── 080-088: x ffff000000000000 # data[9] = 65535
 ├── 088-096: x 0000010000000000 # data[10] = 65536
 ├── 096-104: x ffffffff00000000 # data[11] = 4294967295
 └── 104-112: x 0000000001000000 # data[12] = 4294967296

# Test serializing a few columns using delta encoding.

init default-zero
----

write
0:1 2:92 3:1 7:86 20:221
----

size rows=5
----
Size(5, 0) = 6

get indices=(0, 1, 2, 3, 4, 5, 6, 7, 20)
----
b.Get(0) = 1
b.Get(1) = 0
b.Get(2) = 92
b.Get(3) = 1
b.Get(4) = 0
b.Get(5) = 0
b.Get(6) = 0
b.Get(7) = 86
b.Get(20) = 221

finish rows=5
----
uints
 ├── 0-1: x 01 # encoding: 1b
 ├── 1-2: x 01 # data[0] = 1
 ├── 2-3: x 00 # data[1] = 0
 ├── 3-4: x 5c # data[2] = 92
 ├── 4-5: x 01 # data[3] = 1
 └── 5-6: x 00 # data[4] = 0

# Test a situation where the most recently written value requirs a wider delta
# encoding, but we Finish with few enough rows that we should serialize using
# the smaller encoding.

init
----

write
0:0 1:29 2:595 3:2 4:2 5:9
----

size rows=(6)
----
Size(6, 0) = 14

write
6:70395
----

size rows=(7)
----
Size(7, 0) = 32

finish rows=6
----
uints
 ├── 00-01: x 02   # encoding: 2b
 ├── 01-02: x 00   # padding (aligning to 16-bit boundary)
 ├── 02-04: x 0000 # data[0] = 0
 ├── 04-06: x 1d00 # data[1] = 29
 ├── 06-08: x 5302 # data[2] = 595
 ├── 08-10: x 0200 # data[3] = 2
 ├── 10-12: x 0200 # data[4] = 2
 └── 12-14: x 0900 # data[5] = 9

finish rows=7
----
uints
 ├── 00-01: x 04       # encoding: 4b
 ├── 01-04: x 000000   # padding (aligning to 32-bit boundary)
 ├── 04-08: x 00000000 # data[0] = 0
 ├── 08-12: x 1d000000 # data[1] = 29
 ├── 12-16: x 53020000 # data[2] = 595
 ├── 16-20: x 02000000 # data[3] = 2
 ├── 20-24: x 02000000 # data[4] = 2
 ├── 24-28: x 09000000 # data[5] = 9
 └── 28-32: x fb120100 # data[6] = 70395

# Test the constant encoding.

init
----

write
0:1 1:1 2:1 3:1 4:1 5:1
----

size rows=(6)
----
Size(6, 0) = 7

finish rows=6
----
uints
 ├── 0-1: x 01 # encoding: 1b
 ├── 1-2: x 01 # data[0] = 1
 ├── 2-3: x 01 # data[1] = 1
 ├── 3-4: x 01 # data[2] = 1
 ├── 4-5: x 01 # data[3] = 1
 ├── 5-6: x 01 # data[4] = 1
 └── 6-7: x 01 # data[5] = 1

# Test 32-bit delta encoding.

init
----

write
0:1 1:63936 2:4294967296
----

size rows=(3) offset=1
----
Size(3, 1) = 24 [23 w/o offset]

finish rows=3 offset=1
----
uints
 ├── 00-01: x 00 # artificial start offset
 ├── 01-02: x 84               # encoding: 4b,delta
 ├── 02-10: x 0100000000000000 # 64-bit constant: 1
 ├── 10-12: x 0000             # padding (aligning to 32-bit boundary)
 ├── 12-16: x 00000000         # data[0] = 0 + 1 = 1
 ├── 16-20: x bff90000         # data[1] = 63935 + 1 = 63936
 └── 20-24: x ffffffff         # data[2] = 4294967295 + 1 = 4294967296

# Test serializing with zero rows. The representation should require zero bytes.

init
----

size rows=0 offset=0
----
Size(0, 0) = 0

finish rows=0 offset=0
----
uints

init default-zero
----

write
0:1000000
1:1000010
2:1000020
3:1000030
4:1000040
----

# The encoding pessimistically assumes that we may have a 0 value.
size rows=4 offset=0
----
Size(4, 0) = 20

# Write a row that changes the encoding.
write
5:44333222111
----

# Make sure the encoding hasn't changed.
size rows=4 offset=0
----
Size(4, 0) = 20

finish rows=4 offset=0
----
uints
 ├── 00-01: x 04       # encoding: 4b
 ├── 01-04: x 000000   # padding (aligning to 32-bit boundary)
 ├── 04-08: x 40420f00 # data[0] = 1000000
 ├── 08-12: x 4a420f00 # data[1] = 1000010
 ├── 12-16: x 54420f00 # data[2] = 1000020
 └── 16-20: x 5e420f00 # data[3] = 1000030


init default-zero
----

write
0:1 1:1 2:1 3:1 4:1
----

# Verify the case where the last rows have not been set.
finish rows=100
----
uints
 ├── 000-001: x 01 # encoding: 1b
 ├── 001-002: x 01 # data[0] = 1
 ├── 002-003: x 01 # data[1] = 1
 ├── 003-004: x 01 # data[2] = 1
 ├── 004-005: x 01 # data[3] = 1
 ├── 005-006: x 01 # data[4] = 1
 ├── 006-007: x 00 # data[5] = 0
 ├── 007-008: x 00 # data[6] = 0
 ├── 008-009: x 00 # data[7] = 0
 ├── 009-010: x 00 # data[8] = 0
 ├── 010-011: x 00 # data[9] = 0
 ├── 011-012: x 00 # data[10] = 0
 ├── 012-013: x 00 # data[11] = 0
 ├── 013-014: x 00 # data[12] = 0
 ├── 014-015: x 00 # data[13] = 0
 ├── 015-016: x 00 # data[14] = 0
 ├── 016-017: x 00 # data[15] = 0
 ├── 017-018: x 00 # data[16] = 0
 ├── 018-019: x 00 # data[17] = 0
 ├── 019-020: x 00 # data[18] = 0
 ├── 020-021: x 00 # data[19] = 0
 ├── 021-022: x 00 # data[20] = 0
 ├── 022-023: x 00 # data[21] = 0
 ├── 023-024: x 00 # data[22] = 0
 ├── 024-025: x 00 # data[23] = 0
 ├── 025-026: x 00 # data[24] = 0
 ├── 026-027: x 00 # data[25] = 0
 ├── 027-028: x 00 # data[26] = 0
 ├── 028-029: x 00 # data[27] = 0
 ├── 029-030: x 00 # data[28] = 0
 ├── 030-031: x 00 # data[29] = 0
 ├── 031-032: x 00 # data[30] = 0
 ├── 032-033: x 00 # data[31] = 0
 ├── 033-034: x 00 # data[32] = 0
 ├── 034-035: x 00 # data[33] = 0
 ├── 035-036: x 00 # data[34] = 0
 ├── 036-037: x 00 # data[35] = 0
 ├── 037-038: x 00 # data[36] = 0
 ├── 038-039: x 00 # data[37] = 0
 ├── 039-040: x 00 # data[38] = 0
 ├── 040-041: x 00 # data[39] = 0
 ├── 041-042: x 00 # data[40] = 0
 ├── 042-043: x 00 # data[41] = 0
 ├── 043-044: x 00 # data[42] = 0
 ├── 044-045: x 00 # data[43] = 0
 ├── 045-046: x 00 # data[44] = 0
 ├── 046-047: x 00 # data[45] = 0
 ├── 047-048: x 00 # data[46] = 0
 ├── 048-049: x 00 # data[47] = 0
 ├── 049-050: x 00 # data[48] = 0
 ├── 050-051: x 00 # data[49] = 0
 ├── 051-052: x 00 # data[50] = 0
 ├── 052-053: x 00 # data[51] = 0
 ├── 053-054: x 00 # data[52] = 0
 ├── 054-055: x 00 # data[53] = 0
 ├── 055-056: x 00 # data[54] = 0
 ├── 056-057: x 00 # data[55] = 0
 ├── 057-058: x 00 # data[56] = 0
 ├── 058-059: x 00 # data[57] = 0
 ├── 059-060: x 00 # data[58] = 0
 ├── 060-061: x 00 # data[59] = 0
 ├── 061-062: x 00 # data[60] = 0
 ├── 062-063: x 00 # data[61] = 0
 ├── 063-064: x 00 # data[62] = 0
 ├── 064-065: x 00 # data[63] = 0
 ├── 065-066: x 00 # data[64] = 0
 ├── 066-067: x 00 # data[65] = 0
 ├── 067-068: x 00 # data[66] = 0
 ├── 068-069: x 00 # data[67] = 0
 ├── 069-070: x 00 # data[68] = 0
 ├── 070-071: x 00 # data[69] = 0
 ├── 071-072: x 00 # data[70] = 0
 ├── 072-073: x 00 # data[71] = 0
 ├── 073-074: x 00 # data[72] = 0
 ├── 074-075: x 00 # data[73] = 0
 ├── 075-076: x 00 # data[74] = 0
 ├── 076-077: x 00 # data[75] = 0
 ├── 077-078: x 00 # data[76] = 0
 ├── 078-079: x 00 # data[77] = 0
 ├── 079-080: x 00 # data[78] = 0
 ├── 080-081: x 00 # data[79] = 0
 ├── 081-082: x 00 # data[80] = 0
 ├── 082-083: x 00 # data[81] = 0
 ├── 083-084: x 00 # data[82] = 0
 ├── 084-085: x 00 # data[83] = 0
 ├── 085-086: x 00 # data[84] = 0
 ├── 086-087: x 00 # data[85] = 0
 ├── 087-088: x 00 # data[86] = 0
 ├── 088-089: x 00 # data[87] = 0
 ├── 089-090: x 00 # data[88] = 0
 ├── 090-091: x 00 # data[89] = 0
 ├── 091-092: x 00 # data[90] = 0
 ├── 092-093: x 00 # data[91] = 0
 ├── 093-094: x 00 # data[92] = 0
 ├── 094-095: x 00 # data[93] = 0
 ├── 095-096: x 00 # data[94] = 0
 ├── 096-097: x 00 # data[95] = 0
 ├── 097-098: x 00 # data[96] = 0
 ├── 098-099: x 00 # data[97] = 0
 ├── 099-100: x 00 # data[98] = 0
 └── 100-101: x 00 # data[99] = 0

# Test a case where we must grow the array backing the column by doubling its
# size (its grown to at least 32 elements by default, so it's necessary to set
# an index >= 32).

init default-zero zero-struct
----

write
43:1
----

finish rows=44
----
uints
 ├── 00-01: x 01 # encoding: 1b
 ├── 01-02: x 00 # data[0] = 0
 ├── 02-03: x 00 # data[1] = 0
 ├── 03-04: x 00 # data[2] = 0
 ├── 04-05: x 00 # data[3] = 0
 ├── 05-06: x 00 # data[4] = 0
 ├── 06-07: x 00 # data[5] = 0
 ├── 07-08: x 00 # data[6] = 0
 ├── 08-09: x 00 # data[7] = 0
 ├── 09-10: x 00 # data[8] = 0
 ├── 10-11: x 00 # data[9] = 0
 ├── 11-12: x 00 # data[10] = 0
 ├── 12-13: x 00 # data[11] = 0
 ├── 13-14: x 00 # data[12] = 0
 ├── 14-15: x 00 # data[13] = 0
 ├── 15-16: x 00 # data[14] = 0
 ├── 16-17: x 00 # data[15] = 0
 ├── 17-18: x 00 # data[16] = 0
 ├── 18-19: x 00 # data[17] = 0
 ├── 19-20: x 00 # data[18] = 0
 ├── 20-21: x 00 # data[19] = 0
 ├── 21-22: x 00 # data[20] = 0
 ├── 22-23: x 00 # data[21] = 0
 ├── 23-24: x 00 # data[22] = 0
 ├── 24-25: x 00 # data[23] = 0
 ├── 25-26: x 00 # data[24] = 0
 ├── 26-27: x 00 # data[25] = 0
 ├── 27-28: x 00 # data[26] = 0
 ├── 28-29: x 00 # data[27] = 0
 ├── 29-30: x 00 # data[28] = 0
 ├── 30-31: x 00 # data[29] = 0
 ├── 31-32: x 00 # data[30] = 0
 ├── 32-33: x 00 # data[31] = 0
 ├── 33-34: x 00 # data[32] = 0
 ├── 34-35: x 00 # data[33] = 0
 ├── 35-36: x 00 # data[34] = 0
 ├── 36-37: x 00 # data[35] = 0
 ├── 37-38: x 00 # data[36] = 0
 ├── 38-39: x 00 # data[37] = 0
 ├── 39-40: x 00 # data[38] = 0
 ├── 40-41: x 00 # data[39] = 0
 ├── 41-42: x 00 # data[40] = 0
 ├── 42-43: x 00 # data[41] = 0
 ├── 43-44: x 00 # data[42] = 0
 └── 44-45: x 01 # data[43] = 1

init
----

finish rows=0
----
uints
