@zio.dev/zio-blocks 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.md +426 -0
- package/package.json +6 -0
- package/path-interpolator.md +645 -0
- package/reference/binding.md +364 -0
- package/reference/chunk.md +576 -0
- package/reference/context.md +157 -0
- package/reference/docs.md +524 -0
- package/reference/dynamic-value.md +823 -0
- package/reference/formats.md +640 -0
- package/reference/json-schema.md +626 -0
- package/reference/json.md +979 -0
- package/reference/modifier.md +276 -0
- package/reference/optics.md +1613 -0
- package/reference/patch.md +631 -0
- package/reference/reflect-transform.md +387 -0
- package/reference/reflect.md +521 -0
- package/reference/registers.md +282 -0
- package/reference/schema-evolution.md +540 -0
- package/reference/schema.md +619 -0
- package/reference/syntax.md +409 -0
- package/reference/type-class-derivation-internals.md +632 -0
- package/reference/typeid.md +900 -0
- package/reference/validation.md +458 -0
- package/scope.md +627 -0
- package/sidebars.js +30 -0
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: chunk
|
|
3
|
+
title: "Chunk"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`Chunk[A]` is an immutable, indexed sequence optimized for high-performance operations. Unlike Scala's built-in collections, Chunk is designed for zero-allocation access patterns, efficient concatenation, and unboxed primitive storage.
|
|
7
|
+
|
|
8
|
+
## Why Chunk?
|
|
9
|
+
|
|
10
|
+
Chunk addresses several limitations of standard Scala collections:
|
|
11
|
+
|
|
12
|
+
| Feature | Chunk | Vector | Array |
|
|
13
|
+
|---------|-------|--------|-------|
|
|
14
|
+
| Immutable | ✓ | ✓ | ✗ |
|
|
15
|
+
| O(1) indexed access | ✓ | ~O(1) | ✓ |
|
|
16
|
+
| Unboxed primitives | ✓ | ✗ | ✓ |
|
|
17
|
+
| Efficient concatenation | ✓ | ✓ | ✗ |
|
|
18
|
+
| Safe functional interface | ✓ | ✓ | ✗ |
|
|
19
|
+
| Lazy slicing | ✓ | ✗ | ✗ |
|
|
20
|
+
|
|
21
|
+
Key advantages:
|
|
22
|
+
|
|
23
|
+
- **Zero-boxing for primitives**: `Chunk[Int]`, `Chunk[Double]`, etc. store values unboxed in specialized arrays
|
|
24
|
+
- **Lazy concatenation**: Uses balanced tree structures (based on Conc-Trees) for O(log n) concatenation
|
|
25
|
+
- **Efficient slicing**: `drop`, `take`, and `slice` create views without copying
|
|
26
|
+
- **Automatic materialization**: Deep operation chains are materialized when depth exceeds thresholds
|
|
27
|
+
- **Scala collections integration**: Implements `IndexedSeq` for seamless interoperability
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
Add the following to your `build.sbt`:
|
|
32
|
+
|
|
33
|
+
```scala
|
|
34
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-chunk" % "<version>"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For cross-platform projects (Scala.js):
|
|
38
|
+
|
|
39
|
+
```scala
|
|
40
|
+
libraryDependencies += "dev.zio" %%% "zio-blocks-chunk" % "<version>"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Supported Scala versions: 2.13.x and 3.x
|
|
44
|
+
|
|
45
|
+
## Creating Chunks
|
|
46
|
+
|
|
47
|
+
### From Varargs
|
|
48
|
+
|
|
49
|
+
```scala mdoc:compile-only
|
|
50
|
+
import zio.blocks.chunk.Chunk
|
|
51
|
+
|
|
52
|
+
val numbers = Chunk(1, 2, 3, 4, 5)
|
|
53
|
+
val strings = Chunk("hello", "world")
|
|
54
|
+
val empty = Chunk.empty[Int]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### From a Single Element
|
|
58
|
+
|
|
59
|
+
```scala mdoc:compile-only
|
|
60
|
+
import zio.blocks.chunk.Chunk
|
|
61
|
+
|
|
62
|
+
val single = Chunk.single(42)
|
|
63
|
+
val unit = Chunk.unit // Chunk(())
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### From Arrays
|
|
67
|
+
|
|
68
|
+
When you have an existing array, use `fromArray`. Note that the array should not be mutated after wrapping:
|
|
69
|
+
|
|
70
|
+
```scala mdoc:compile-only
|
|
71
|
+
import zio.blocks.chunk.Chunk
|
|
72
|
+
|
|
73
|
+
val arr = Array(1, 2, 3)
|
|
74
|
+
val chunk = Chunk.fromArray(arr)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### From Iterables and Iterators
|
|
78
|
+
|
|
79
|
+
```scala mdoc:compile-only
|
|
80
|
+
import zio.blocks.chunk.Chunk
|
|
81
|
+
|
|
82
|
+
val fromList = Chunk.fromIterable(List(1, 2, 3))
|
|
83
|
+
val fromVector = Chunk.fromIterable(Vector("a", "b"))
|
|
84
|
+
val fromIter = Chunk.fromIterator(Iterator.range(0, 10))
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### From Java Collections
|
|
88
|
+
|
|
89
|
+
```scala mdoc:compile-only
|
|
90
|
+
import zio.blocks.chunk.Chunk
|
|
91
|
+
import java.util
|
|
92
|
+
|
|
93
|
+
val javaList = new util.ArrayList[String]()
|
|
94
|
+
javaList.add("one")
|
|
95
|
+
javaList.add("two")
|
|
96
|
+
|
|
97
|
+
val chunk = Chunk.fromJavaIterable(javaList)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### From NIO Buffers
|
|
101
|
+
|
|
102
|
+
Chunk provides direct integration with Java NIO buffers:
|
|
103
|
+
|
|
104
|
+
```scala mdoc:compile-only
|
|
105
|
+
import zio.blocks.chunk.Chunk
|
|
106
|
+
import java.nio.ByteBuffer
|
|
107
|
+
|
|
108
|
+
val buffer = ByteBuffer.wrap(Array[Byte](1, 2, 3, 4))
|
|
109
|
+
val bytes = Chunk.fromByteBuffer(buffer)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Available buffer constructors:
|
|
113
|
+
- `Chunk.fromByteBuffer(ByteBuffer): Chunk[Byte]`
|
|
114
|
+
- `Chunk.fromCharBuffer(CharBuffer): Chunk[Char]`
|
|
115
|
+
- `Chunk.fromIntBuffer(IntBuffer): Chunk[Int]`
|
|
116
|
+
- `Chunk.fromLongBuffer(LongBuffer): Chunk[Long]`
|
|
117
|
+
- `Chunk.fromShortBuffer(ShortBuffer): Chunk[Short]`
|
|
118
|
+
- `Chunk.fromFloatBuffer(FloatBuffer): Chunk[Float]`
|
|
119
|
+
- `Chunk.fromDoubleBuffer(DoubleBuffer): Chunk[Double]`
|
|
120
|
+
|
|
121
|
+
### Generator Functions
|
|
122
|
+
|
|
123
|
+
```scala mdoc:compile-only
|
|
124
|
+
import zio.blocks.chunk.Chunk
|
|
125
|
+
|
|
126
|
+
val filled = Chunk.fill(5)("x") // Chunk("x", "x", "x", "x", "x")
|
|
127
|
+
val iterated = Chunk.iterate(1, 5)(_ * 2) // Chunk(1, 2, 4, 8, 16)
|
|
128
|
+
val unfolded = Chunk.unfold(0)(n => if (n < 5) Some((n, n + 1)) else None)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Core Operations
|
|
132
|
+
|
|
133
|
+
### Element Access
|
|
134
|
+
|
|
135
|
+
```scala mdoc:compile-only
|
|
136
|
+
import zio.blocks.chunk.Chunk
|
|
137
|
+
|
|
138
|
+
val chunk = Chunk(10, 20, 30, 40, 50)
|
|
139
|
+
|
|
140
|
+
val first = chunk(0) // 10
|
|
141
|
+
val second = chunk(1) // 20
|
|
142
|
+
val head = chunk.head // 10
|
|
143
|
+
val last = chunk.last // 50
|
|
144
|
+
val len = chunk.length // 5
|
|
145
|
+
|
|
146
|
+
val maybeHead = chunk.headOption // Some(10)
|
|
147
|
+
val maybeLast = chunk.lastOption // Some(50)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
For primitive chunks, specialized accessors avoid boxing:
|
|
151
|
+
|
|
152
|
+
```scala mdoc:compile-only
|
|
153
|
+
import zio.blocks.chunk.Chunk
|
|
154
|
+
|
|
155
|
+
val ints = Chunk(1, 2, 3)
|
|
156
|
+
val i: Int = ints.int(0) // unboxed access
|
|
157
|
+
|
|
158
|
+
val bytes = Chunk[Byte](1, 2, 3)
|
|
159
|
+
val b: Byte = bytes.byte(0) // unboxed access
|
|
160
|
+
|
|
161
|
+
val doubles = Chunk(1.0, 2.0, 3.0)
|
|
162
|
+
val d: Double = doubles.double(0) // unboxed access
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Transformations
|
|
166
|
+
|
|
167
|
+
```scala mdoc:compile-only
|
|
168
|
+
import zio.blocks.chunk.Chunk
|
|
169
|
+
|
|
170
|
+
val chunk = Chunk(1, 2, 3, 4, 5)
|
|
171
|
+
|
|
172
|
+
val doubled = chunk.map(_ * 2) // Chunk(2, 4, 6, 8, 10)
|
|
173
|
+
val filtered = chunk.filter(_ > 2) // Chunk(3, 4, 5)
|
|
174
|
+
val flatted = chunk.flatMap(n => Chunk(n, n)) // Chunk(1, 1, 2, 2, ...)
|
|
175
|
+
val collected = chunk.collect { case n if n % 2 == 0 => n * 10 } // Chunk(20, 40)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Concatenation
|
|
179
|
+
|
|
180
|
+
Concatenation is efficient—Chunk uses balanced tree structures to avoid copying:
|
|
181
|
+
|
|
182
|
+
```scala mdoc:compile-only
|
|
183
|
+
import zio.blocks.chunk.Chunk
|
|
184
|
+
|
|
185
|
+
val a = Chunk(1, 2, 3)
|
|
186
|
+
val b = Chunk(4, 5, 6)
|
|
187
|
+
|
|
188
|
+
val combined = a ++ b // Chunk(1, 2, 3, 4, 5, 6)
|
|
189
|
+
val appended = a :+ 4 // Chunk(1, 2, 3, 4)
|
|
190
|
+
val prepended = 0 +: a // Chunk(0, 1, 2, 3)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Slicing
|
|
194
|
+
|
|
195
|
+
Slicing operations create views and don't copy data:
|
|
196
|
+
|
|
197
|
+
```scala mdoc:compile-only
|
|
198
|
+
import zio.blocks.chunk.Chunk
|
|
199
|
+
|
|
200
|
+
val chunk = Chunk(1, 2, 3, 4, 5, 6, 7, 8)
|
|
201
|
+
|
|
202
|
+
val firstThree = chunk.take(3) // Chunk(1, 2, 3)
|
|
203
|
+
val lastThree = chunk.takeRight(3) // Chunk(6, 7, 8)
|
|
204
|
+
val dropped = chunk.drop(2) // Chunk(3, 4, 5, 6, 7, 8)
|
|
205
|
+
val sliced = chunk.slice(2, 5) // Chunk(3, 4, 5)
|
|
206
|
+
|
|
207
|
+
val (left, right) = chunk.splitAt(4) // (Chunk(1,2,3,4), Chunk(5,6,7,8))
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Conditional Operations
|
|
211
|
+
|
|
212
|
+
```scala mdoc:compile-only
|
|
213
|
+
import zio.blocks.chunk.Chunk
|
|
214
|
+
|
|
215
|
+
val chunk = Chunk(1, 2, 3, 4, 5, 6)
|
|
216
|
+
|
|
217
|
+
val takeWhileSmall = chunk.takeWhile(_ < 4) // Chunk(1, 2, 3)
|
|
218
|
+
val dropWhileSmall = chunk.dropWhile(_ < 4) // Chunk(4, 5, 6)
|
|
219
|
+
val takeUntilBig = chunk.takeWhile(_ <= 3) // Chunk(1, 2, 3)
|
|
220
|
+
val dropUntilBig = chunk.dropUntil(_ > 3) // Chunk(5, 6)
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Folding and Reduction
|
|
224
|
+
|
|
225
|
+
```scala mdoc:compile-only
|
|
226
|
+
import zio.blocks.chunk.Chunk
|
|
227
|
+
|
|
228
|
+
val chunk = Chunk(1, 2, 3, 4, 5)
|
|
229
|
+
|
|
230
|
+
val sum = chunk.foldLeft(0)(_ + _) // 15
|
|
231
|
+
val product = chunk.foldRight(1)(_ * _) // 120
|
|
232
|
+
val summed = chunk.reduce(_ + _) // 15
|
|
233
|
+
|
|
234
|
+
val runningSum = chunk.foldWhile(0)(_ < 10)(_ + _) // 10 (1+2+3+4)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Searching and Predicates
|
|
238
|
+
|
|
239
|
+
```scala mdoc:compile-only
|
|
240
|
+
import zio.blocks.chunk.Chunk
|
|
241
|
+
|
|
242
|
+
val chunk = Chunk(1, 2, 3, 4, 5)
|
|
243
|
+
|
|
244
|
+
val hasEven = chunk.exists(_ % 2 == 0) // true
|
|
245
|
+
val allSmall = chunk.forall(_ < 10) // true
|
|
246
|
+
val found = chunk.find(_ > 3) // Some(4)
|
|
247
|
+
val index = chunk.indexWhere(_ > 3) // 3
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Zipping
|
|
251
|
+
|
|
252
|
+
```scala mdoc:compile-only
|
|
253
|
+
import zio.blocks.chunk.Chunk
|
|
254
|
+
|
|
255
|
+
val as = Chunk("a", "b", "c")
|
|
256
|
+
val bs = Chunk(1, 2, 3)
|
|
257
|
+
|
|
258
|
+
val zipped = as.zip(bs) // Chunk(("a",1), ("b",2), ("c",3))
|
|
259
|
+
val withIndex = as.zipWithIndex // Chunk(("a",0), ("b",1), ("c",2))
|
|
260
|
+
val zipWith = as.zipWith(bs)(_ + _) // Chunk("a1", "b2", "c3")
|
|
261
|
+
val zipAll = as.zipAll(Chunk(1, 2)) // handles different lengths
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Updating Elements
|
|
265
|
+
|
|
266
|
+
Updates are immutable and use efficient buffering:
|
|
267
|
+
|
|
268
|
+
```scala mdoc:compile-only
|
|
269
|
+
import zio.blocks.chunk.Chunk
|
|
270
|
+
|
|
271
|
+
val chunk = Chunk(1, 2, 3, 4, 5)
|
|
272
|
+
val updated = chunk.updated(2, 100) // Chunk(1, 2, 100, 4, 5)
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Deduplication and Sorting
|
|
276
|
+
|
|
277
|
+
```scala mdoc:compile-only
|
|
278
|
+
import zio.blocks.chunk.Chunk
|
|
279
|
+
|
|
280
|
+
val withDupes = Chunk(1, 1, 2, 2, 2, 3, 3)
|
|
281
|
+
val deduped = withDupes.dedupe // Chunk(1, 2, 3) - removes adjacent duplicates
|
|
282
|
+
|
|
283
|
+
val unsorted = Chunk(3, 1, 4, 1, 5)
|
|
284
|
+
val sorted = unsorted.sorted // Chunk(1, 1, 3, 4, 5)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Splitting
|
|
288
|
+
|
|
289
|
+
```scala mdoc:compile-only
|
|
290
|
+
import zio.blocks.chunk.Chunk
|
|
291
|
+
|
|
292
|
+
val chunk = Chunk(1, 2, 3, 4, 5, 6)
|
|
293
|
+
|
|
294
|
+
val parts = chunk.split(3) // Chunk(Chunk(1,2), Chunk(3,4), Chunk(5,6))
|
|
295
|
+
val (before, after) = chunk.splitWhere(_ > 3) // splits at first element > 3
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### String Conversion
|
|
299
|
+
|
|
300
|
+
```scala mdoc:compile-only
|
|
301
|
+
import zio.blocks.chunk.Chunk
|
|
302
|
+
import java.nio.charset.StandardCharsets
|
|
303
|
+
|
|
304
|
+
val bytes = Chunk[Byte](72, 101, 108, 108, 111)
|
|
305
|
+
val str = bytes.asString // "Hello"
|
|
306
|
+
|
|
307
|
+
val chars = Chunk('H', 'e', 'l', 'l', 'o')
|
|
308
|
+
val str2 = chars.asString // "Hello"
|
|
309
|
+
|
|
310
|
+
val withCharset = bytes.asString(StandardCharsets.UTF_8) // "Hello"
|
|
311
|
+
val base64 = bytes.asBase64String // base64-encoded string
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Materialization
|
|
315
|
+
|
|
316
|
+
For complex operation chains, you can force materialization to an array-backed chunk:
|
|
317
|
+
|
|
318
|
+
```scala mdoc:compile-only
|
|
319
|
+
import zio.blocks.chunk.Chunk
|
|
320
|
+
|
|
321
|
+
val complex = Chunk(1, 2, 3) ++ Chunk(4, 5) ++ Chunk(6, 7)
|
|
322
|
+
val materialized = complex.materialize // backed by a single array
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## NonEmptyChunk
|
|
326
|
+
|
|
327
|
+
`NonEmptyChunk[A]` is a chunk guaranteed to contain at least one element. This enables safe use of operations like `head` and `reduce`:
|
|
328
|
+
|
|
329
|
+
```scala mdoc:compile-only
|
|
330
|
+
import zio.blocks.chunk.{Chunk, NonEmptyChunk}
|
|
331
|
+
|
|
332
|
+
val nec = NonEmptyChunk(1, 2, 3)
|
|
333
|
+
|
|
334
|
+
val first: Int = nec.head // always safe
|
|
335
|
+
val sum: Int = nec.reduce(_ + _) // always safe
|
|
336
|
+
|
|
337
|
+
val mapped: NonEmptyChunk[Int] = nec.map(_ * 2)
|
|
338
|
+
val flatMapped: NonEmptyChunk[Int] = nec.flatMap(n => NonEmptyChunk(n, n + 1))
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Creating NonEmptyChunk
|
|
342
|
+
|
|
343
|
+
```scala mdoc:compile-only
|
|
344
|
+
import zio.blocks.chunk.{Chunk, NonEmptyChunk}
|
|
345
|
+
|
|
346
|
+
val fromValues = NonEmptyChunk(1, 2, 3)
|
|
347
|
+
val single = NonEmptyChunk.single(42)
|
|
348
|
+
val fromCons = NonEmptyChunk.fromCons(::(1, List(2, 3)))
|
|
349
|
+
val fromIterable = NonEmptyChunk.fromIterable(1, List(2, 3))
|
|
350
|
+
|
|
351
|
+
val maybeNec: Option[NonEmptyChunk[Int]] = NonEmptyChunk.fromChunk(Chunk(1, 2))
|
|
352
|
+
val empty: Option[NonEmptyChunk[Int]] = NonEmptyChunk.fromChunk(Chunk.empty) // None
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Converting Between Chunk and NonEmptyChunk
|
|
356
|
+
|
|
357
|
+
```scala mdoc:compile-only
|
|
358
|
+
import zio.blocks.chunk.{Chunk, NonEmptyChunk}
|
|
359
|
+
|
|
360
|
+
val nec = NonEmptyChunk(1, 2, 3)
|
|
361
|
+
val chunk: Chunk[Int] = nec.toChunk
|
|
362
|
+
|
|
363
|
+
val chunk2 = Chunk(1, 2, 3)
|
|
364
|
+
chunk2.nonEmptyOrElse(0)(_.reduce(_ + _)) // 6 if non-empty, 0 if empty
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Operations That Preserve NonEmptiness
|
|
368
|
+
|
|
369
|
+
These operations return `NonEmptyChunk`:
|
|
370
|
+
- `map`, `flatMap`, `flatten`
|
|
371
|
+
- `append`, `prepend`, `++`
|
|
372
|
+
- `zip`, `zipWith`, `zipWithIndex`
|
|
373
|
+
- `sorted`, `sortBy`, `reverse`
|
|
374
|
+
- `distinct`, `materialize`
|
|
375
|
+
|
|
376
|
+
Operations that might produce empty results return `Chunk`:
|
|
377
|
+
- `filter`, `filterNot`
|
|
378
|
+
- `collect`
|
|
379
|
+
- `tail`, `init`
|
|
380
|
+
|
|
381
|
+
## ChunkBuilder
|
|
382
|
+
|
|
383
|
+
`ChunkBuilder` is a mutable builder for creating chunks efficiently. It's specialized for primitives to avoid boxing:
|
|
384
|
+
|
|
385
|
+
```scala mdoc:compile-only
|
|
386
|
+
import zio.blocks.chunk.{Chunk, ChunkBuilder}
|
|
387
|
+
|
|
388
|
+
val builder = ChunkBuilder.make[Int]()
|
|
389
|
+
builder.addOne(1)
|
|
390
|
+
builder.addOne(2)
|
|
391
|
+
builder.addAll(List(3, 4, 5))
|
|
392
|
+
val result: Chunk[Int] = builder.result() // Chunk(1, 2, 3, 4, 5)
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Specialized Builders
|
|
396
|
+
|
|
397
|
+
For primitives, use specialized builders for best performance:
|
|
398
|
+
|
|
399
|
+
```scala mdoc:compile-only
|
|
400
|
+
import zio.blocks.chunk.{Chunk, ChunkBuilder}
|
|
401
|
+
|
|
402
|
+
val intBuilder = new ChunkBuilder.Int
|
|
403
|
+
intBuilder.addOne(1)
|
|
404
|
+
intBuilder.addOne(2)
|
|
405
|
+
val ints: Chunk[Int] = intBuilder.result()
|
|
406
|
+
|
|
407
|
+
val byteBuilder = new ChunkBuilder.Byte
|
|
408
|
+
val longBuilder = new ChunkBuilder.Long
|
|
409
|
+
val doubleBuilder = new ChunkBuilder.Double
|
|
410
|
+
val boolBuilder = new ChunkBuilder.Boolean
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Available specialized builders: `Boolean`, `Byte`, `Char`, `Short`, `Int`, `Long`, `Float`, `Double`
|
|
414
|
+
|
|
415
|
+
## Bit Operations
|
|
416
|
+
|
|
417
|
+
Chunk provides efficient bit-level operations for working with binary data:
|
|
418
|
+
|
|
419
|
+
### Converting to Bits
|
|
420
|
+
|
|
421
|
+
```scala mdoc:compile-only
|
|
422
|
+
import zio.blocks.chunk.Chunk
|
|
423
|
+
|
|
424
|
+
val bytes = Chunk[Byte](0x0F, 0xF0.toByte)
|
|
425
|
+
val bits = bytes.asBitsByte // Chunk of 16 booleans
|
|
426
|
+
|
|
427
|
+
val ints = Chunk(0x12345678)
|
|
428
|
+
val intBits = ints.asBitsInt(Chunk.BitChunk.Endianness.BigEndian)
|
|
429
|
+
|
|
430
|
+
val longs = Chunk(0x123456789ABCDEF0L)
|
|
431
|
+
val longBits = longs.asBitsLong(Chunk.BitChunk.Endianness.BigEndian)
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Bitwise Operations
|
|
435
|
+
|
|
436
|
+
```scala mdoc:compile-only
|
|
437
|
+
import zio.blocks.chunk.Chunk
|
|
438
|
+
|
|
439
|
+
val a = Chunk(true, false, true, false)
|
|
440
|
+
val b = Chunk(true, true, false, false)
|
|
441
|
+
|
|
442
|
+
val andResult = a & b // Chunk(true, false, false, false)
|
|
443
|
+
val orResult = a | b // Chunk(true, true, true, false)
|
|
444
|
+
val xorResult = a ^ b // Chunk(false, true, true, false)
|
|
445
|
+
val negated = a.negate // Chunk(false, true, false, true)
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Packing Booleans
|
|
449
|
+
|
|
450
|
+
```scala mdoc:compile-only
|
|
451
|
+
import zio.blocks.chunk.Chunk
|
|
452
|
+
|
|
453
|
+
val bits = Chunk(true, false, true, false, true, true, true, true)
|
|
454
|
+
val packedBytes: Chunk[Byte] = bits.toPackedByte // Efficient byte representation
|
|
455
|
+
|
|
456
|
+
val packedInts: Chunk[Int] = bits.toPackedInt(Chunk.BitChunk.Endianness.BigEndian)
|
|
457
|
+
val packedLongs: Chunk[Long] = bits.toPackedLong(Chunk.BitChunk.Endianness.BigEndian)
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Binary String
|
|
461
|
+
|
|
462
|
+
```scala mdoc:compile-only
|
|
463
|
+
import zio.blocks.chunk.Chunk
|
|
464
|
+
|
|
465
|
+
val bits = Chunk(true, false, true, true)
|
|
466
|
+
val binary: String = bits.toBinaryString // "1011"
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## ChunkMap
|
|
470
|
+
|
|
471
|
+
`ChunkMap[K, V]` is an order-preserving immutable map backed by parallel chunks. It maintains insertion order during iteration:
|
|
472
|
+
|
|
473
|
+
```scala mdoc:compile-only
|
|
474
|
+
import zio.blocks.chunk.{Chunk, ChunkMap}
|
|
475
|
+
|
|
476
|
+
val map = ChunkMap("a" -> 1, "b" -> 2, "c" -> 3)
|
|
477
|
+
|
|
478
|
+
val value = map.get("b") // Some(2)
|
|
479
|
+
val updated = map.updated("d", 4)
|
|
480
|
+
val removed = map.removed("b")
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Creating ChunkMap
|
|
484
|
+
|
|
485
|
+
```scala mdoc:compile-only
|
|
486
|
+
import zio.blocks.chunk.{Chunk, ChunkMap}
|
|
487
|
+
|
|
488
|
+
val empty = ChunkMap.empty[String, Int]
|
|
489
|
+
val fromPairs = ChunkMap("x" -> 1, "y" -> 2)
|
|
490
|
+
val fromChunk = ChunkMap.fromChunk(Chunk(("a", 1), ("b", 2)))
|
|
491
|
+
val fromChunks = ChunkMap.fromChunks(Chunk("a", "b"), Chunk(1, 2))
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Indexed Access
|
|
495
|
+
|
|
496
|
+
ChunkMap provides O(1) positional access:
|
|
497
|
+
|
|
498
|
+
```scala mdoc:compile-only
|
|
499
|
+
import zio.blocks.chunk.{Chunk, ChunkMap}
|
|
500
|
+
|
|
501
|
+
val map = ChunkMap("z" -> 1, "a" -> 2, "m" -> 3)
|
|
502
|
+
|
|
503
|
+
val first = map.atIndex(0) // ("z", 1)
|
|
504
|
+
val key = map.keyAtIndex(1) // "a"
|
|
505
|
+
val value = map.valueAtIndex(2) // 3
|
|
506
|
+
|
|
507
|
+
val keys: Chunk[String] = map.keysChunk
|
|
508
|
+
val values: Chunk[Int] = map.valuesChunk
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### Optimized Lookup
|
|
512
|
+
|
|
513
|
+
For frequent lookups, create an indexed version with O(1) key access:
|
|
514
|
+
|
|
515
|
+
```scala mdoc:compile-only
|
|
516
|
+
import zio.blocks.chunk.ChunkMap
|
|
517
|
+
|
|
518
|
+
val map = ChunkMap("a" -> 1, "b" -> 2, "c" -> 3)
|
|
519
|
+
val indexed = map.indexed // O(1) lookups, extra memory for index
|
|
520
|
+
|
|
521
|
+
val value = indexed.get("b") // O(1) instead of O(n)
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
## Scala Collections Integration
|
|
525
|
+
|
|
526
|
+
Chunk implements `IndexedSeq` and integrates seamlessly with Scala collections:
|
|
527
|
+
|
|
528
|
+
```scala mdoc:compile-only
|
|
529
|
+
import zio.blocks.chunk.Chunk
|
|
530
|
+
|
|
531
|
+
val chunk = Chunk(1, 2, 3, 4, 5)
|
|
532
|
+
|
|
533
|
+
val list: List[Int] = chunk.toList
|
|
534
|
+
val vector: Vector[Int] = chunk.toVector
|
|
535
|
+
val array: Array[Int] = chunk.toArray
|
|
536
|
+
|
|
537
|
+
val fromSeq: Chunk[Int] = Chunk.from(Vector(1, 2, 3))
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
Standard collection operations work as expected:
|
|
541
|
+
|
|
542
|
+
```scala mdoc:compile-only
|
|
543
|
+
import zio.blocks.chunk.Chunk
|
|
544
|
+
|
|
545
|
+
val chunk = Chunk(1, 2, 3)
|
|
546
|
+
val result = chunk
|
|
547
|
+
.filter(_ > 1)
|
|
548
|
+
.map(_ * 2)
|
|
549
|
+
.flatMap(n => Chunk(n, n + 1))
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
## Performance Characteristics
|
|
553
|
+
|
|
554
|
+
| Operation | Time Complexity | Notes |
|
|
555
|
+
|-----------|-----------------|-------|
|
|
556
|
+
| `apply(i)` | O(1) | Direct array access for materialized chunks |
|
|
557
|
+
| `length` | O(1) | Cached |
|
|
558
|
+
| `head`, `last` | O(1) | |
|
|
559
|
+
| `++` | O(log n) | Balanced tree concatenation |
|
|
560
|
+
| `:+`, `+:` | O(1) amortized | Buffered appends |
|
|
561
|
+
| `take`, `drop`, `slice` | O(1) | Creates view |
|
|
562
|
+
| `map`, `filter`, `flatMap` | O(n) | |
|
|
563
|
+
| `updated` | O(1) amortized | Buffered updates |
|
|
564
|
+
| `materialize` | O(n) | Copies to array |
|
|
565
|
+
|
|
566
|
+
### When to Materialize
|
|
567
|
+
|
|
568
|
+
Chunk automatically materializes when:
|
|
569
|
+
- Tree depth exceeds internal thresholds
|
|
570
|
+
- You call `materialize` explicitly
|
|
571
|
+
- Converting to array with `toArray`
|
|
572
|
+
|
|
573
|
+
Consider explicit materialization when:
|
|
574
|
+
- Performing many random accesses on a deeply nested chunk
|
|
575
|
+
- Passing data to APIs that need arrays
|
|
576
|
+
- Optimizing a hot loop
|