<lambda>null1 package shark
2
3 import kotlin.random.Random
4 import org.assertj.core.api.Assertions.assertThat
5 import org.junit.Test
6 import shark.internal.UnsortedByteEntries
7
8 class SortedBytesMapTest {
9
10 @Test fun writeAndReadLongValue() {
11 val unsortedEntries = UnsortedByteEntries(bytesPerValue = 8, longIdentifiers = false)
12 unsortedEntries.append(1)
13 .apply {
14 writeLong(Long.MIN_VALUE)
15 }
16
17 val array = unsortedEntries.moveToSortedMap()[1]!!
18 assertThat(array.readLong()).isEqualTo(Long.MIN_VALUE)
19 }
20
21 @Test fun writeAndReadTruncatedLongValue() {
22 val maxUnsigned3Bytes = 0x00000FFFL
23 val unsortedMap = UnsortedByteEntries(bytesPerValue = 3, longIdentifiers = false)
24 unsortedMap.append(1)
25 .apply {
26 writeTruncatedLong(maxUnsigned3Bytes, 3)
27 }
28
29 val array = unsortedMap.moveToSortedMap()[1]!!
30 assertThat(array.readTruncatedLong(3)).isEqualTo(maxUnsigned3Bytes)
31 }
32
33 @Test fun fourEntriesWithLongKey1ByteValueSorted() {
34 val unsortedEntries = UnsortedByteEntries(bytesPerValue = 1, longIdentifiers = true)
35 unsortedEntries.append(42)
36 .apply {
37 writeByte(4)
38 }
39 unsortedEntries.append(0)
40 .apply {
41 writeByte(3)
42 }
43 unsortedEntries.append(3)
44 .apply {
45 writeByte(20)
46 }
47 unsortedEntries.append(Long.MAX_VALUE)
48 .apply {
49 writeByte(127)
50 }
51 val sortedEntries = unsortedEntries.moveToSortedMap()
52 .entrySequence()
53 .toList()
54
55 assertThat(sortedEntries.map { it.first }).containsExactly(0, 3, 42, Long.MAX_VALUE)
56 assertThat(
57 sortedEntries.map {
58 byteArrayOf(
59 it.second.readByte()
60 )
61 }).containsExactly(
62 byteArrayOf(3), byteArrayOf(20), byteArrayOf(4),
63 byteArrayOf(127)
64 )
65 }
66
67 @Test fun fourEntriesWithLongKey3ByteValueSorted() {
68 val unsortedMap = UnsortedByteEntries(bytesPerValue = 3, longIdentifiers = true)
69 unsortedMap.append(42)
70 .apply {
71 writeByte(4)
72 writeByte(2)
73 writeByte(0)
74 }
75 unsortedMap.append(0)
76 .apply {
77 writeByte(3)
78 writeByte(2)
79 writeByte(1)
80 }
81 unsortedMap.append(3)
82 .apply {
83 writeByte(20)
84 writeByte(52)
85 writeByte(-17)
86 }
87 unsortedMap.append(Long.MAX_VALUE)
88 .apply {
89 writeByte(127)
90 writeByte(0)
91 writeByte(-128)
92 }
93 val sortedEntries = unsortedMap.moveToSortedMap()
94 .entrySequence()
95 .toList()
96
97 assertThat(sortedEntries.map { it.first }).containsExactly(0, 3, 42, Long.MAX_VALUE)
98 assertThat(
99 sortedEntries.map {
100 byteArrayOf(
101 it.second.readByte(), it.second.readByte(), it.second.readByte()
102 )
103 }).containsExactly(
104 byteArrayOf(3, 2, 1), byteArrayOf(20, 52, -17), byteArrayOf(4, 2, 0),
105 byteArrayOf(127, 0, -128)
106 )
107 }
108
109 class Entry(
110 val key: Long,
111 val value: ByteArray
112 ) : Comparable<Entry> {
113 override fun compareTo(other: Entry): Int = key.compareTo(other.key)
114 override fun equals(other: Any?): Boolean {
115 if (this === other) return true
116 if (javaClass != other?.javaClass) return false
117
118 other as Entry
119
120 if (key != other.key) return false
121 if (!value.contentEquals(other.value)) return false
122
123 return true
124 }
125
126 override fun toString(): String {
127 return "Entry(key=$key, value=${value.contentToString()})"
128 }
129 }
130
131 @Test fun largeRandomArrayIntKey3ByteValueSorted() {
132 val random = Random(Long.MAX_VALUE)
133
134 val bytesPerValue = 3
135 val longIdentifiers = false
136
137 val sourceEntryArray = Array(10000) {
138 Entry(random.nextInt().toLong(), random.nextBytes(bytesPerValue))
139 }
140
141 sortAndCompare(bytesPerValue, longIdentifiers, sourceEntryArray)
142 }
143
144 @Test fun largeRandomArrayLongKey3ByteValueSorted() {
145 val random = Random(42)
146
147 val bytesPerValue = 3
148 val longIdentifiers = true
149
150 val sourceEntryArray = Array(10000) {
151 Entry(random.nextLong(), random.nextBytes(bytesPerValue))
152 }
153
154 sortAndCompare(bytesPerValue, longIdentifiers, sourceEntryArray)
155 }
156
157 @Test fun largeRandomArrayLongKey7ByteValueSorted() {
158 val random = Random(Long.MIN_VALUE)
159
160 val bytesPerValue = 7
161 val longIdentifiers = true
162
163 val sourceEntryArray = Array(10000) {
164 Entry(random.nextLong(), random.nextBytes(bytesPerValue))
165 }
166
167 sortAndCompare(bytesPerValue, longIdentifiers, sourceEntryArray)
168 }
169
170 private fun sortAndCompare(
171 bytesPerValue: Int,
172 longIdentifiers: Boolean,
173 sourceEntryArray: Array<Entry>
174 ) {
175 val unsortedEntries =
176 UnsortedByteEntries(bytesPerValue = bytesPerValue, longIdentifiers = longIdentifiers)
177
178 sourceEntryArray.forEach { entry ->
179 val subArray = unsortedEntries.append(entry.key)
180 entry.value.forEach { subArray.writeByte(it) }
181 }
182
183 val sortedMap = unsortedEntries.moveToSortedMap()
184 sourceEntryArray.sort()
185
186 val sortedEntryArray = sortedMap.entrySequence()
187 .map {
188 val key = it.first
189 val value = it.second
190
191 val bytes = mutableListOf<Byte>()
192 for (i in 0 until bytesPerValue) {
193 bytes += value.readByte()
194 }
195 Entry(key, bytes.toByteArray())
196 }
197 .toList()
198 .toTypedArray()
199
200 assertThat(sortedEntryArray).isEqualTo(sourceEntryArray)
201 }
202 }
203