public void GetQueryBlocks_SingleCell() { var q1 = ZCurve.Encode(6, 4); // 52 var blocks1 = ZCurve.GetQueryBlocks(q1, q1); // single cell, all levels var expected1 = Blocks(52, 0); Assert.Equal(expected1, blocks1); var q2 = ZCurve.Encode(11, 11); // 207 var blocks2 = ZCurve.GetQueryBlocks(q2, q2); // single cell, all levels var expected2 = Blocks(207, 0); Assert.Equal(expected2, blocks2); var q3 = ZCurve.Encode(5, 1); // 19 var blocks3 = ZCurve.GetQueryBlocks(q3, q3, new[] { 2 }); // single cell, specific levels var expected3 = Blocks(16, 2); Assert.Equal(expected3, blocks3); var q4 = ZCurve.Encode(uint.MaxValue, uint.MaxValue); // ulong.MaxValue var blocks4 = ZCurve.GetQueryBlocks(q4, q4, new[] { 3 }); var expected4 = Blocks(ulong.MaxValue - 63, 3); Assert.Equal(expected4, blocks4); }
public void NextInsideBoxTest() { Assert.Equal(27UL, ZCurve.NextInsideBox(0, 27, 102)); Assert.Equal(74UL, ZCurve.NextInsideBox(58, 27, 102)); Assert.Equal(74UL, ZCurve.NextInsideBox(67, 27, 102)); Assert.Equal(96UL, ZCurve.NextInsideBox(79, 27, 102)); Assert.Equal(74UL, ZCurve.NextInsideBox(61, 27, 102)); // What if z is within box(qlo,qhi)? Drill down, cutting // off parts of the box, until a single cell remains. Assert.Equal(6UL, ZCurve.NextInsideBox(3, 3, 49)); Assert.Equal(11UL, ZCurve.NextInsideBox(9, 3, 49)); Assert.Equal(14UL, ZCurve.NextInsideBox(13, 3, 49)); Assert.Equal(19UL, ZCurve.NextInsideBox(18, 3, 49)); Assert.Equal(49UL, ZCurve.NextInsideBox(48, 3, 49)); Assert.Equal(0UL, ZCurve.NextInsideBox(49, 3, 49)); Assert.Equal(0UL, ZCurve.NextInsideBox(54, 54, 54)); // What if z > qhi? Only keys 000 or 100 or 101 can occur, // drilling down (possibly cutting off lower parts of the // query box) until the box is below and z is above the // dividing line (key 100) and we return the result so far, // which is zero (result's initial value). Assert.Equal(0UL, ZCurve.NextInsideBox(50, 3, 49, 5)); // x within, y beyond Assert.Equal(0UL, ZCurve.NextInsideBox(51, 3, 49, 5)); // x within, y beyond Assert.Equal(0UL, ZCurve.NextInsideBox(52, 3, 49, 5)); // x beyond, y within Assert.Equal(0UL, ZCurve.NextInsideBox(53, 3, 49, 5)); // x beyond, y within Assert.Equal(0UL, ZCurve.NextInsideBox(54, 3, 49, 5)); // both x and y beyond // Enumerate cells within query box qlo..qhi: var result = new List <ulong>(); var expected = new ulong[] { 3, 6, 7, 9, 11, 12, 13, 14, 15, 18, 19, 24, 25, 26, 27, 33, 36, 37, 48, 49 }; ulong qlo = ZCurve.Encode(1U, 1U); // 3 ulong qhi = ZCurve.Encode(5U, 4U); // 49 ulong cur = qlo; while (true) { result.Add(cur); cur += 1; if (cur > qhi) { break; } const int starti = 5; if (!ZCurve.IsInsideBox(cur, qlo, qhi)) { cur = ZCurve.NextInsideBox(cur, qlo, qhi, starti); } } Assert.Equal(expected, result); }
public void EncodeDecodeTest() { const uint ux = 0xFFFFFFFF; const uint uy = 0x5555AAAA; ulong uz = ZCurve.Encode(ux, uy); Assert.Equal(0x77777777DDDDDDDDUL, uz); Assert.Equal(ux, ZCurve.DecodeX(uz)); Assert.Equal(uy, ZCurve.DecodeY(uz)); Assert.Equal(0U, ZCurve.DecodeX(ZCurve.Encode(0, 0))); Assert.Equal(0U, ZCurve.DecodeY(ZCurve.Encode(0, 0))); Assert.Equal(123456789U, ZCurve.DecodeX(ZCurve.Encode(123456789, 999999))); Assert.Equal(999999U, ZCurve.DecodeY(ZCurve.Encode(12345689, 999999))); Assert.Equal(ulong.MaxValue, ZCurve.Encode(uint.MaxValue, uint.MaxValue)); }
public void GetQueryBlocks_AcrossBlock() { var qlo = ZCurve.Encode(7, 7); // 63 var qhi = ZCurve.Encode(8, 8); // 192 var blocks1 = ZCurve.GetQueryBlocks(qlo, qhi); // all levels var expected1 = Blocks(63, 0, 106, 0, 149, 0, 192, 0); Assert.Equal(expected1, blocks1); var blocks2 = ZCurve.GetQueryBlocks(qlo, qhi, new[] { 1, 2 }); var expected2 = Blocks(60, 1, 104, 1, 148, 1, 192, 1); Assert.Equal(expected2, blocks2); var blocks3 = ZCurve.GetQueryBlocks(qlo, qhi, new[] { 2 }); var expected3 = Blocks(48, 2, 96, 2, 144, 2, 192, 2); Assert.Equal(expected3, blocks3); }
public void GetQueryBlocks_WithinBlock() { var q = ZCurve.Encode(7, 10); // 157 var blocks1 = ZCurve.GetQueryBlocks(q, q, new[] { 0, 1, 2, 3 }); Assert.Equal(Blocks(157, 0), blocks1); var blocks2 = ZCurve.GetQueryBlocks(q, q, new[] { 1, 2, 3 }); Assert.Equal(Blocks(156, 1), blocks2); var blocks3 = ZCurve.GetQueryBlocks(q, q, new[] { 2, 3 }); Assert.Equal(Blocks(144, 2), blocks3); var blocks4 = ZCurve.GetQueryBlocks(q, q, new[] { 3 }); Assert.Equal(Blocks(128, 3), blocks4); }
public void IsInsideBoxTest() { ulong min = ZCurve.Encode(1U, 1U); // 3 ulong max = ZCurve.Encode(5U, 4U); // 49 Assert.False(ZCurve.IsInsideBox(0, min, max)); Assert.True(ZCurve.IsInsideBox(3, min, max)); Assert.True(ZCurve.IsInsideBox(19, min, max)); Assert.False(ZCurve.IsInsideBox(20, min, max)); Assert.False(ZCurve.IsInsideBox(8, min, max)); Assert.True(ZCurve.IsInsideBox(15, min, max)); Assert.True(ZCurve.IsInsideBox(49, min, max)); Assert.False(ZCurve.IsInsideBox(50, min, max)); min = ZCurve.Encode(int.MaxValue - 1, int.MaxValue - 1); max = ZCurve.Encode(int.MaxValue, int.MaxValue); Assert.False(ZCurve.IsInsideBox(ZCurve.Encode(int.MaxValue - 2, int.MaxValue - 2), min, max)); Assert.True(ZCurve.IsInsideBox(ZCurve.Encode(int.MaxValue - 1, int.MaxValue - 1), min, max)); Assert.True(ZCurve.IsInsideBox(ZCurve.Encode(int.MaxValue, int.MaxValue), min, max)); Assert.False(ZCurve.IsInsideBox(ZCurve.Encode(1U + int.MaxValue, 1U + int.MaxValue), min, max)); }
public void QueryBlocksTrial() { // Expect shortest ordered sequence of blocks covering query box // Query box: ulong qlo = ZCurve.Encode(1U, 1U); // 3 ulong qhi = ZCurve.Encode(5U, 4U); // 49 // Expected result: 3 6 7 9 11 (12..15) 18 19 (24..27) 33 36 37 48 49 var starts = new ulong[] { 3, 6, 7, 9, 11, 12, 18, 19, 24, 33, 36, 37, 48, 49 }; var levels = new[] { 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }; var expected = starts.Zip(levels, (s, l) => new ZCurve.Block(s, l)).ToList(); var actual = new List <ZCurve.Block>(); ulong first = ZCurve.FirstInBlock(qlo, 0); ulong last = ZCurve.FirstInBlock(qhi, 0); for (ulong cursor = first; ;) { int level = ZCurve.LargestLevel(cursor, last); ulong increment = ZCurve.CellsPerBlock(level); actual.Add(new ZCurve.Block(cursor, level)); cursor += increment; if (cursor > last) { break; } if (!ZCurve.IsInsideBox(cursor, first, last)) { cursor = ZCurve.NextInsideBox(cursor, first, last); } } Assert.Equal(expected, actual); }
public void NearestBelowTest() { Assert.Equal(0UL, ZCurve.NearestBelow(0, 0)); Assert.Equal(0UL, ZCurve.NearestBelow(0, 1)); Assert.Equal(1UL, ZCurve.NearestBelow(0, 2)); Assert.Equal(2UL, ZCurve.NearestBelow(0, 3)); Assert.Equal(0x2AAAAAAAUL, ZCurve.NearestBelow(0, 31)); Assert.Equal(0x2AAAAAAAAAAAAAAAUL, ZCurve.NearestBelow(0, 63)); // 55 = Z(7,5) // 0111b 0101b => 0011 0111b Assert.Equal(54UL, ZCurve.NearestBelow(55, 0)); Assert.Equal(53UL, ZCurve.NearestBelow(55, 1)); Assert.Equal(51UL, ZCurve.NearestBelow(55, 2)); Assert.Equal(55UL, ZCurve.NearestBelow(55, 3)); Assert.Equal(39UL, ZCurve.NearestBelow(55, 4)); Assert.Equal(31UL, ZCurve.NearestBelow(55, 5)); Assert.Equal(55UL, ZCurve.NearestBelow(55, 6)); Assert.Equal(63UL, ZCurve.NearestBelow(55, 7)); Assert.Equal(ZCurve.Encode(7, 0x7FFF), ZCurve.NearestBelow(55, 31)); Assert.Equal(ZCurve.Encode(7, int.MaxValue), ZCurve.NearestBelow(55, 63)); // TODO More }