@@ -20,6 +20,7 @@ import kotlin.jvm.JvmField
20
20
import kotlin.jvm.JvmName
21
21
import kotlin.jvm.JvmOverloads
22
22
import kotlin.jvm.JvmStatic
23
+ import kotlin.math.min
23
24
24
25
/* *
25
26
* An immutable sequence of bytes.
@@ -137,6 +138,98 @@ internal constructor(data: ByteArray) : Comparable<ByteString> {
137
138
138
139
override fun compareTo (other : ByteString ): Int
139
140
141
+ /* *
142
+ * Projects this value to the range `[0..size)` using linear interpolation. This is equivalent to
143
+ * a sorted partitioning of all possible byte strings across [size] equally-sized buckets and
144
+ * returning the index of the bucket that this byte string fits in.
145
+ *
146
+ * For example, the byte string `8000` is the median of all 2-element byte strings, and calling
147
+ * `toIndex(100)` on it returns 50. Some other examples:
148
+ *
149
+ * | Byte String (hex) | `toIndex(100)` | `toIndex(256)` | `toIndex(Int.MAX_VALUE)` |
150
+ * | :----------------- | -------------: | -------------: | -----------------------: |
151
+ * | (empty) | 0 | 0 | 0 |
152
+ * | 00 | 0 | 0 | 0 |
153
+ * | 0000 | 0 | 0 | 0 |
154
+ * | 000000 | 0 | 0 | 0 |
155
+ * | 0000000001 | 0 | 0 | 0 |
156
+ * | 00000001 | 0 | 0 | 0 |
157
+ * | 00000002 | 0 | 0 | 0 |
158
+ * | 00000003 | 0 | 0 | 1 |
159
+ * | 01 | 0 | 1 | 8388607 |
160
+ * | 02 | 0 | 2 | 16777215 |
161
+ * | 03 | 1 | 3 | 25165823 |
162
+ * | 80 | 50 | 128 | 1073741823 |
163
+ * | 8000 | 50 | 128 | 1073741823 |
164
+ * | 80000000 | 50 | 128 | 1073741823 |
165
+ * | 81 | 50 | 129 | 1082130431 |
166
+ * | 81ffffff | 50 | 129 | 1090519038 |
167
+ * | 82 | 50 | 130 | 1090519039 |
168
+ * | 83 | 51 | 131 | 1098907647 |
169
+ * | ff | 99 | 255 | 2139095039 |
170
+ * | ffff | 99 | 255 | 2147450879 |
171
+ * | ffffffff | 99 | 255 | 2147483646 |
172
+ * | ffffffffffff | 99 | 255 | 2147483646 |
173
+ *
174
+ * This interprets the bytes in this byte string as **unsigned**. This behavior is consistent with
175
+ * [compareTo]. The returned value is also consistent with [compareTo] though the dynamic range
176
+ * is compressed. For two byte strings `a` and `b`, if `a < b`, then
177
+ * `a.toIndex(n) <= b.toIndex(n)` for all sizes `n`.
178
+ *
179
+ * This examines at most the first 4 bytes of this byte string. Data beyond the first 4 bytes is
180
+ * not used to compute the result.
181
+ *
182
+ * @param size a positive integer.
183
+ * @return a value that is greater than or equal to `0` and less than [size].
184
+ */
185
+ fun toIndex (size : Int ): Int
186
+
187
+ /* *
188
+ * Projects this value to the range `[0.0..1.0)` using linear interpolation. This is equivalent to
189
+ * sorting all possible byte strings and returning the fraction that precede this byte string.
190
+ *
191
+ * For example, the byte string `8000` is the median of all 2-element byte strings, and calling
192
+ * `toFraction()` on it returns 0.5. Some other examples:
193
+ *
194
+ * | Byte String (hex) | `toFraction()` |
195
+ * | :----------------- | :----------------- |
196
+ * | (empty) | 0.0 |
197
+ * | 00 | 0.0 |
198
+ * | 0000 | 0.0 |
199
+ * | 000000 | 0.0 |
200
+ * | 00000000000001 | 0.0 |
201
+ * | 00000000000007 | 0.0 |
202
+ * | 00000000000008 | 0.0000000000000001 |
203
+ * | 0000000001 | 0.0000000000009094 |
204
+ * | 00000001 | 0.0000000002328306 |
205
+ * | 01 | 0.00390625 |
206
+ * | 02 | 0.0078125 |
207
+ * | 03 | 0.01171875 |
208
+ * | 80 | 0.5 |
209
+ * | 8000 | 0.5 |
210
+ * | 80000000000000 | 0.5 |
211
+ * | 81 | 0.50390625 |
212
+ * | 81ffffff | 0.5078124997671694 |
213
+ * | 82 | 0.5078125 |
214
+ * | 83 | 0.51171875 |
215
+ * | ff | 0.99609375 |
216
+ * | ffff | 0.9999847412109375 |
217
+ * | ffffffff | 0.9999999997671694 |
218
+ * | ffffffffffff | 0.9999999999999964 |
219
+ * | ffffffffffffff | 0.9999999999999999 |
220
+ *
221
+ * This interprets the bytes in this byte string as **unsigned**. This behavior is consistent with
222
+ * [compareTo]. The returned value is also consistent with [compareTo] though the dynamic range
223
+ * is compressed. For two byte strings `a` and `b`, if `a < b`, then
224
+ * `a.toFraction() <= b.toFraction()`.
225
+ *
226
+ * This examines at most the first 7 bytes of this byte string. Data beyond the first 7 bytes is
227
+ * not used to compute the result.
228
+ *
229
+ * @return a value that is greater than or equal to `0.0` and less than `1.0`.
230
+ */
231
+ fun toFraction (): Double
232
+
140
233
/* *
141
234
* Returns a human-readable string that describes the contents of this byte string. Typically this
142
235
* is a string like `[text=Hello]` or `[hex=0000ffff]`.
0 commit comments