wavelet-matrix 2.2.2__tar.gz → 2.2.4__tar.gz

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.
Files changed (46) hide show
  1. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/.github/workflows/CI.yml +22 -26
  2. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/Cargo.lock +17 -27
  3. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/Cargo.toml +1 -2
  4. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/PKG-INFO +1 -1
  5. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/benchmarks/bench_disk_wavelet_matrix.py +11 -11
  6. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/pyproject.toml +1 -1
  7. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/disk_wavelet_matrix/disk_bit_vector.rs +63 -54
  8. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/disk_wavelet_matrix/disk_wavelet_matrix.rs +28 -14
  9. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/python/wavelet_matrix.rs +36 -4
  10. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/wavelet_matrix/wavelet_matrix.rs +12 -11
  11. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/.gitignore +0 -0
  12. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/LICENSE +0 -0
  13. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/README.md +0 -0
  14. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/benchmarks/__init__.py +0 -0
  15. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/benchmarks/bench_dynamic_wavelet_matrix.py +0 -0
  16. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/benchmarks/bench_wavelet_matrix.py +0 -0
  17. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/docs/index.html +0 -0
  18. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/docs/wavelet_matrix.html +0 -0
  19. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/pdoc_templates/error.html.jinja2 +0 -0
  20. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/pdoc_templates/frame.html.jinja2 +0 -0
  21. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/pdoc_templates/index.html.jinja2 +0 -0
  22. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/pdoc_templates/module.html.jinja2 +0 -0
  23. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/disk_wavelet_matrix/mod.rs +0 -0
  24. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/dynamic_wavelet_matrix/dynamic_bit_vector.rs +0 -0
  25. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/dynamic_wavelet_matrix/dynamic_wavelet_matrix.rs +0 -0
  26. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/dynamic_wavelet_matrix/mod.rs +0 -0
  27. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/lib.rs +0 -0
  28. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/python/dynamic_wavelet_matrix.rs +0 -0
  29. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/python/mod.rs +0 -0
  30. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/bit_vector/bit_vector.rs +0 -0
  31. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/bit_vector/dynamic_bit_vector.rs +0 -0
  32. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/bit_vector/mod.rs +0 -0
  33. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/mod.rs +0 -0
  34. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/utils/bit_select.rs +0 -0
  35. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/utils/bit_width.rs +0 -0
  36. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/utils/mod.rs +0 -0
  37. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/wavelet_matrix/dynamic_wavelet_matrix.rs +0 -0
  38. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/wavelet_matrix/mod.rs +0 -0
  39. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/traits/wavelet_matrix/wavelet_matrix.rs +0 -0
  40. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/wavelet_matrix/bit_vector.rs +0 -0
  41. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/src/wavelet_matrix/mod.rs +0 -0
  42. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/tests/__init__.py +0 -0
  43. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/tests/test_disk_wavelet_matrix.py +0 -0
  44. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/tests/test_dynamic_wavelet_matrix.py +0 -0
  45. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/tests/test_wavelet_matrix.py +0 -0
  46. {wavelet_matrix-2.2.2 → wavelet_matrix-2.2.4}/wavelet_matrix.pyi +0 -0
@@ -42,8 +42,8 @@ jobs:
42
42
  - runner: ubuntu-latest
43
43
  target: ppc64le
44
44
  steps:
45
- - uses: actions/checkout@v6
46
- - uses: actions/setup-python@v6
45
+ - uses: actions/checkout@v7
46
+ - uses: actions/setup-python@v7
47
47
  with:
48
48
  python-version: 3.x
49
49
  - name: Build wheels
@@ -55,7 +55,7 @@ jobs:
55
55
  manylinux: auto
56
56
  - name: Upload wheels
57
57
  if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
58
- uses: actions/upload-artifact@v6
58
+ uses: actions/upload-artifact@v7
59
59
  with:
60
60
  name: wheels-linux-${{ matrix.platform.target }}
61
61
  path: dist
@@ -75,8 +75,8 @@ jobs:
75
75
  - runner: ubuntu-latest
76
76
  target: armv7
77
77
  steps:
78
- - uses: actions/checkout@v6
79
- - uses: actions/setup-python@v6
78
+ - uses: actions/checkout@v7
79
+ - uses: actions/setup-python@v7
80
80
  with:
81
81
  python-version: 3.x
82
82
  - name: Build wheels
@@ -88,7 +88,7 @@ jobs:
88
88
  manylinux: musllinux_1_2
89
89
  - name: Upload wheels
90
90
  if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
91
- uses: actions/upload-artifact@v6
91
+ uses: actions/upload-artifact@v7
92
92
  with:
93
93
  name: wheels-musllinux-${{ matrix.platform.target }}
94
94
  path: dist
@@ -104,8 +104,8 @@ jobs:
104
104
  - runner: windows-latest
105
105
  target: x86
106
106
  steps:
107
- - uses: actions/checkout@v6
108
- - uses: actions/setup-python@v6
107
+ - uses: actions/checkout@v7
108
+ - uses: actions/setup-python@v7
109
109
  with:
110
110
  python-version: 3.x
111
111
  architecture: ${{ matrix.platform.target }}
@@ -117,7 +117,7 @@ jobs:
117
117
  sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
118
118
  - name: Upload wheels
119
119
  if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
120
- uses: actions/upload-artifact@v6
120
+ uses: actions/upload-artifact@v7
121
121
  with:
122
122
  name: wheels-windows-${{ matrix.platform.target }}
123
123
  path: dist
@@ -133,8 +133,8 @@ jobs:
133
133
  - runner: macos-latest
134
134
  target: aarch64
135
135
  steps:
136
- - uses: actions/checkout@v6
137
- - uses: actions/setup-python@v6
136
+ - uses: actions/checkout@v7
137
+ - uses: actions/setup-python@v7
138
138
  with:
139
139
  python-version: 3.x
140
140
  - name: Build wheels
@@ -145,7 +145,7 @@ jobs:
145
145
  sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
146
146
  - name: Upload wheels
147
147
  if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
148
- uses: actions/upload-artifact@v6
148
+ uses: actions/upload-artifact@v7
149
149
  with:
150
150
  name: wheels-macos-${{ matrix.platform.target }}
151
151
  path: dist
@@ -154,8 +154,8 @@ jobs:
154
154
  needs: [cargo-test, python-test]
155
155
  runs-on: ubuntu-latest
156
156
  steps:
157
- - uses: actions/checkout@v6
158
- - uses: actions/setup-python@v6
157
+ - uses: actions/checkout@v7
158
+ - uses: actions/setup-python@v7
159
159
  with:
160
160
  python-version: 3.x
161
161
  - name: Build sdist
@@ -165,7 +165,7 @@ jobs:
165
165
  args: --out dist
166
166
  - name: Upload sdist
167
167
  if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
168
- uses: actions/upload-artifact@v6
168
+ uses: actions/upload-artifact@v7
169
169
  with:
170
170
  name: wheels-sdist
171
171
  path: dist
@@ -173,7 +173,7 @@ jobs:
173
173
  cargo-test:
174
174
  runs-on: ubuntu-latest
175
175
  steps:
176
- - uses: actions/checkout@v6
176
+ - uses: actions/checkout@v7
177
177
  - uses: dtolnay/rust-toolchain@stable
178
178
  with:
179
179
  components: clippy
@@ -191,7 +191,7 @@ jobs:
191
191
  - name: Clippy check
192
192
  run: cargo clippy --all-targets --all-features -- -D warnings
193
193
  - name: Upload coverage reports to Codecov
194
- uses: codecov/codecov-action@v5
194
+ uses: codecov/codecov-action@v7
195
195
  with:
196
196
  fail_ci_if_error: true
197
197
  token: ${{ secrets.CODECOV_TOKEN }}
@@ -199,8 +199,8 @@ jobs:
199
199
  python-test:
200
200
  runs-on: ubuntu-latest
201
201
  steps:
202
- - uses: actions/checkout@v6
203
- - uses: actions/setup-python@v6
202
+ - uses: actions/checkout@v7
203
+ - uses: actions/setup-python@v7
204
204
  with:
205
205
  python-version: 3.x
206
206
  - name: Install packages
@@ -233,11 +233,11 @@ jobs:
233
233
  - "3.12"
234
234
  - "3.13"
235
235
  - "3.14"
236
- - "3.15.0-beta.3"
236
+ - "3.15-dev"
237
237
  - "pypy3.11"
238
238
  steps:
239
- - uses: actions/checkout@v6
240
- - uses: actions/setup-python@v6
239
+ - uses: actions/checkout@v7
240
+ - uses: actions/setup-python@v7
241
241
  with:
242
242
  python-version: ${{ matrix.python }}
243
243
  - name: Install packages
@@ -278,10 +278,6 @@ jobs:
278
278
  pattern: wheels-*
279
279
  path: dist
280
280
  merge-multiple: true
281
- - name: Generate artifact attestation
282
- uses: actions/attest-build-provenance@v3
283
- with:
284
- subject-path: 'dist/*'
285
281
  - name: Publish to PyPI
286
282
  if: ${{ startsWith(github.ref, 'refs/tags/') }}
287
283
  uses: pypa/gh-action-pypi-publish@release/v1
@@ -10,15 +10,15 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
10
10
 
11
11
  [[package]]
12
12
  name = "bitflags"
13
- version = "2.13.0"
13
+ version = "2.13.1"
14
14
  source = "registry+https://github.com/rust-lang/crates.io-index"
15
- checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
15
+ checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
16
16
 
17
17
  [[package]]
18
18
  name = "bytemuck"
19
- version = "1.25.0"
19
+ version = "1.25.2"
20
20
  source = "registry+https://github.com/rust-lang/crates.io-index"
21
- checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
21
+ checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797"
22
22
 
23
23
  [[package]]
24
24
  name = "cfg-if"
@@ -69,9 +69,9 @@ dependencies = [
69
69
 
70
70
  [[package]]
71
71
  name = "fastrand"
72
- version = "2.4.1"
72
+ version = "2.5.0"
73
73
  source = "registry+https://github.com/rust-lang/crates.io-index"
74
- checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
74
+ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
75
75
 
76
76
  [[package]]
77
77
  name = "getrandom"
@@ -90,20 +90,11 @@ version = "0.5.0"
90
90
  source = "registry+https://github.com/rust-lang/crates.io-index"
91
91
  checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
92
92
 
93
- [[package]]
94
- name = "itertools"
95
- version = "0.15.0"
96
- source = "registry+https://github.com/rust-lang/crates.io-index"
97
- checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc"
98
- dependencies = [
99
- "either",
100
- ]
101
-
102
93
  [[package]]
103
94
  name = "libc"
104
- version = "0.2.186"
95
+ version = "0.2.189"
105
96
  source = "registry+https://github.com/rust-lang/crates.io-index"
106
- checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
97
+ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
107
98
 
108
99
  [[package]]
109
100
  name = "linux-raw-sys"
@@ -156,15 +147,15 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
156
147
 
157
148
  [[package]]
158
149
  name = "portable-atomic"
159
- version = "1.13.1"
150
+ version = "1.14.0"
160
151
  source = "registry+https://github.com/rust-lang/crates.io-index"
161
- checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
152
+ checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3"
162
153
 
163
154
  [[package]]
164
155
  name = "proc-macro2"
165
- version = "1.0.106"
156
+ version = "1.0.107"
166
157
  source = "registry+https://github.com/rust-lang/crates.io-index"
167
- checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
158
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
168
159
  dependencies = [
169
160
  "unicode-ident",
170
161
  ]
@@ -230,9 +221,9 @@ dependencies = [
230
221
 
231
222
  [[package]]
232
223
  name = "quote"
233
- version = "1.0.46"
224
+ version = "1.0.47"
234
225
  source = "registry+https://github.com/rust-lang/crates.io-index"
235
- checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
226
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
236
227
  dependencies = [
237
228
  "proc-macro2",
238
229
  ]
@@ -278,9 +269,9 @@ dependencies = [
278
269
 
279
270
  [[package]]
280
271
  name = "syn"
281
- version = "2.0.118"
272
+ version = "2.0.119"
282
273
  source = "registry+https://github.com/rust-lang/crates.io-index"
283
- checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
274
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
284
275
  dependencies = [
285
276
  "proc-macro2",
286
277
  "quote",
@@ -314,10 +305,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
314
305
 
315
306
  [[package]]
316
307
  name = "wavelet-matrix"
317
- version = "2.2.2"
308
+ version = "2.2.4"
318
309
  dependencies = [
319
310
  "bytemuck",
320
- "itertools",
321
311
  "memmap2",
322
312
  "num-bigint",
323
313
  "num-integer",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "wavelet-matrix"
3
- version = "2.2.2"
3
+ version = "2.2.4"
4
4
  edition = "2024"
5
5
  readme = "README.md"
6
6
 
@@ -11,7 +11,6 @@ crate-type = ["cdylib"]
11
11
 
12
12
  [dependencies]
13
13
  bytemuck = "1.25.0"
14
- itertools = "0.15.0"
15
14
  memmap2 = "0.9.10"
16
15
  num-bigint = "0.4.6"
17
16
  num-integer = "0.1.46"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wavelet-matrix
3
- Version: 2.2.2
3
+ Version: 2.2.4
4
4
  Classifier: Intended Audience :: Developers
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: Intended Audience :: Information Technology
@@ -22,39 +22,39 @@ def random_disk_wavelet_matrix(random_data: list[int]) -> WaveletMatrix:
22
22
  @pytest.mark.parametrize("size", [500, 10000, 200000])
23
23
  @pytest.mark.parametrize("max_bit", [8, 32, 128])
24
24
  class BenchDiskWaveletMatrix:
25
- def bench_construction(self, benchmark, random_data):
25
+ def bench_disk_construction(self, benchmark, random_data):
26
26
  """Benchmark DiskWaveletMatrix construction"""
27
27
  benchmark(WaveletMatrix, random_data, on_disk=True)
28
28
 
29
- def bench_values(self, benchmark, random_disk_wavelet_matrix):
29
+ def bench_disk_values(self, benchmark, random_disk_wavelet_matrix):
30
30
  """Benchmark DiskWaveletMatrix values retrieval"""
31
31
  benchmark(random_disk_wavelet_matrix.values)
32
32
 
33
- def bench_access(self, benchmark, random_disk_wavelet_matrix, size):
33
+ def bench_disk_access(self, benchmark, random_disk_wavelet_matrix, size):
34
34
  """Benchmark DiskWaveletMatrix access"""
35
35
  index = random.randint(0, size - 1)
36
36
  benchmark(random_disk_wavelet_matrix.access, index)
37
37
 
38
- def bench_rank(self, benchmark, random_disk_wavelet_matrix, size):
38
+ def bench_disk_rank(self, benchmark, random_disk_wavelet_matrix, size):
39
39
  """Benchmark DiskWaveletMatrix rank"""
40
40
  value = random_disk_wavelet_matrix[random.randint(0, size - 1)]
41
41
  end = random.randint(0, size)
42
42
  benchmark(random_disk_wavelet_matrix.rank, value, end)
43
43
 
44
- def bench_select(self, benchmark, random_disk_wavelet_matrix, size):
44
+ def bench_disk_select(self, benchmark, random_disk_wavelet_matrix, size):
45
45
  """Benchmark DiskWaveletMatrix select"""
46
46
  value = random_disk_wavelet_matrix[random.randint(0, size - 1)]
47
47
  kth = random_disk_wavelet_matrix.rank(value, size)
48
48
  benchmark(random_disk_wavelet_matrix.select, value, kth)
49
49
 
50
- def bench_quantile(self, benchmark, random_disk_wavelet_matrix, size):
50
+ def bench_disk_quantile(self, benchmark, random_disk_wavelet_matrix, size):
51
51
  """Benchmark DiskWaveletMatrix quantile"""
52
52
  start = size // 4
53
53
  end = size * 3 // 4
54
54
  kth = random.randint(1, end - start)
55
55
  benchmark(random_disk_wavelet_matrix.quantile, start, end, kth)
56
56
 
57
- def bench_range_freq(self, benchmark, random_disk_wavelet_matrix, size, max_bit):
57
+ def bench_disk_range_freq(self, benchmark, random_disk_wavelet_matrix, size, max_bit):
58
58
  """Benchmark DiskWaveletMatrix range_freq"""
59
59
  start = size // 4
60
60
  end = size * 3 // 4
@@ -62,28 +62,28 @@ class BenchDiskWaveletMatrix:
62
62
  upper = (1 << max_bit) * 3 // 4
63
63
  benchmark(random_disk_wavelet_matrix.range_freq, start, end, lower, upper)
64
64
 
65
- def bench_range_maxk(self, benchmark, random_disk_wavelet_matrix, size):
65
+ def bench_disk_range_maxk(self, benchmark, random_disk_wavelet_matrix, size):
66
66
  """Benchmark DiskWaveletMatrix range_maxk"""
67
67
  start = size // 4
68
68
  end = size * 3 // 4
69
69
  k = 10
70
70
  benchmark(random_disk_wavelet_matrix.range_maxk, start, end, k)
71
71
 
72
- def bench_range_mink(self, benchmark, random_disk_wavelet_matrix, size):
72
+ def bench_disk_range_mink(self, benchmark, random_disk_wavelet_matrix, size):
73
73
  """Benchmark DiskWaveletMatrix range_mink"""
74
74
  start = size // 4
75
75
  end = size * 3 // 4
76
76
  k = 10
77
77
  benchmark(random_disk_wavelet_matrix.range_mink, start, end, k)
78
78
 
79
- def bench_prev_value(self, benchmark, random_disk_wavelet_matrix, size, max_bit):
79
+ def bench_disk_prev_value(self, benchmark, random_disk_wavelet_matrix, size, max_bit):
80
80
  """Benchmark DiskWaveletMatrix prev_value"""
81
81
  start = size // 4
82
82
  end = size * 3 // 4
83
83
  upper = 1 << (max_bit - 1)
84
84
  benchmark(random_disk_wavelet_matrix.prev_value, start, end, upper)
85
85
 
86
- def bench_next_value(self, benchmark, random_disk_wavelet_matrix, size, max_bit):
86
+ def bench_disk_next_value(self, benchmark, random_disk_wavelet_matrix, size, max_bit):
87
87
  """Benchmark DiskWaveletMatrix next_value"""
88
88
  start = size // 4
89
89
  end = size * 3 // 4
@@ -75,7 +75,7 @@ addopts = [
75
75
  "--strict-markers",
76
76
  "--tb=short",
77
77
  "--benchmark-columns=mean,stddev,min,max",
78
- "--benchmark-group-by=fullfunc",
78
+ "--benchmark-group-by=func",
79
79
  ]
80
80
 
81
81
  [tool.ruff]
@@ -30,29 +30,29 @@ pub(crate) struct DiskBitVector {
30
30
  impl DiskBitVector {
31
31
  pub(super) fn new(blocks: Mmap, blocks_file: fs::File, len: usize) -> PyResult<Self> {
32
32
  assert!(blocks.len().is_multiple_of(mem::size_of::<BlockType>()));
33
- let blocks_data: &[BlockType] = cast_slice(&blocks[..]);
33
+ let blocks_slice: &[BlockType] = cast_slice(&blocks[..]);
34
34
 
35
35
  // Build the rank index structure.
36
36
  let ranks_file = tempfile().map_err(PyRuntimeError::new_err)?;
37
37
  ranks_file
38
- .set_len((blocks_data.len() + 1) as u64 * mem::size_of::<usize>() as u64)
38
+ .set_len((blocks_slice.len() + 1) as u64 * mem::size_of::<usize>() as u64)
39
39
  .map_err(PyRuntimeError::new_err)?;
40
40
  #[allow(unsafe_code)]
41
41
  let mut ranks = unsafe { MmapMut::map_mut(&ranks_file).map_err(PyRuntimeError::new_err)? };
42
- let ranks_data: &mut [usize] = cast_slice_mut(&mut ranks[..]);
42
+ let ranks_slice: &mut [usize] = cast_slice_mut(&mut ranks[..]);
43
43
  iter::once(0usize)
44
- .chain(blocks_data.iter().scan(0usize, |acc, block| {
44
+ .chain(blocks_slice.iter().scan(0usize, |acc, block| {
45
45
  *acc += block.count_ones() as usize;
46
46
  Some(*acc)
47
47
  }))
48
48
  .enumerate()
49
- .for_each(|(index, rank)| ranks_data[index] = rank);
49
+ .for_each(|(index, rank)| ranks_slice[index] = rank);
50
50
 
51
51
  let select_index_file = [
52
52
  {
53
53
  let file = tempfile().map_err(PyRuntimeError::new_err)?;
54
54
  file.set_len(
55
- (((len - ranks_data.last().unwrap()) / SELECT_INDEX_INTERVAL + 2)
55
+ (((len - ranks_slice.last().unwrap()) / SELECT_INDEX_INTERVAL + 2)
56
56
  * mem::size_of::<usize>()) as u64,
57
57
  )
58
58
  .map_err(PyRuntimeError::new_err)?;
@@ -61,7 +61,7 @@ impl DiskBitVector {
61
61
  {
62
62
  let file = tempfile().map_err(PyRuntimeError::new_err)?;
63
63
  file.set_len(
64
- ((ranks_data.last().unwrap() / SELECT_INDEX_INTERVAL + 2)
64
+ ((ranks_slice.last().unwrap() / SELECT_INDEX_INTERVAL + 2)
65
65
  * mem::size_of::<usize>()) as u64,
66
66
  )
67
67
  .map_err(PyRuntimeError::new_err)?;
@@ -74,14 +74,14 @@ impl DiskBitVector {
74
74
  #[allow(unsafe_code)]
75
75
  let mut select_index_1 =
76
76
  unsafe { MmapMut::map_mut(&select_index_file[1]).map_err(PyRuntimeError::new_err)? };
77
- let select_index_data: [&mut [usize]; 2] = [
77
+ let select_index_slice: [&mut [usize]; 2] = [
78
78
  cast_slice_mut(&mut select_index_0[..]),
79
79
  cast_slice_mut(&mut select_index_1[..]),
80
80
  ];
81
- select_index_data[0][0] = 0;
82
- select_index_data[1][0] = 0;
81
+ select_index_slice[0][0] = 0;
82
+ select_index_slice[1][0] = 0;
83
83
  let mut count = [0usize, 0usize];
84
- for (index, bit) in blocks_data
84
+ for (index, bit) in blocks_slice
85
85
  .iter()
86
86
  .flat_map(|block| {
87
87
  (0..BlockType::BITS as usize)
@@ -93,11 +93,11 @@ impl DiskBitVector {
93
93
  count[bit] += 1;
94
94
  let (count_div, count_rem) = count[bit].div_rem(&SELECT_INDEX_INTERVAL);
95
95
  if count_rem.is_zero() {
96
- select_index_data[bit][count_div] = index;
96
+ select_index_slice[bit][count_div] = index;
97
97
  }
98
98
  }
99
- select_index_data[0][count[0] / SELECT_INDEX_INTERVAL + 1] = len;
100
- select_index_data[1][count[1] / SELECT_INDEX_INTERVAL + 1] = len;
99
+ select_index_slice[0][count[0] / SELECT_INDEX_INTERVAL + 1] = len;
100
+ select_index_slice[1][count[1] / SELECT_INDEX_INTERVAL + 1] = len;
101
101
 
102
102
  Ok(Self {
103
103
  len,
@@ -116,42 +116,47 @@ impl DiskBitVector {
116
116
  select_index_file,
117
117
  })
118
118
  }
119
- }
120
119
 
121
- impl Clone for DiskBitVector {
122
- fn clone(&self) -> Self {
123
- let ranks_file = tempfile().unwrap();
124
- ranks_file.set_len(self.ranks.len() as u64).unwrap();
120
+ pub(super) fn try_clone(&self) -> PyResult<Self> {
121
+ let ranks_file = tempfile().map_err(PyRuntimeError::new_err)?;
122
+ ranks_file
123
+ .set_len(self.ranks.len() as u64)
124
+ .map_err(PyRuntimeError::new_err)?;
125
125
  #[allow(unsafe_code)]
126
- let mut ranks = unsafe { MmapMut::map_mut(&ranks_file).unwrap() };
126
+ let mut ranks = unsafe { MmapMut::map_mut(&ranks_file).map_err(PyRuntimeError::new_err)? };
127
127
  ranks.copy_from_slice(&self.ranks[..]);
128
128
 
129
- let blocks_file = tempfile().unwrap();
130
- blocks_file.set_len(self.blocks.len() as u64).unwrap();
129
+ let blocks_file = tempfile().map_err(PyRuntimeError::new_err)?;
130
+ blocks_file
131
+ .set_len(self.blocks.len() as u64)
132
+ .map_err(PyRuntimeError::new_err)?;
131
133
  #[allow(unsafe_code)]
132
- let mut blocks = unsafe { MmapMut::map_mut(&blocks_file).unwrap() };
134
+ let mut blocks =
135
+ unsafe { MmapMut::map_mut(&blocks_file).map_err(PyRuntimeError::new_err)? };
133
136
  blocks.copy_from_slice(&self.blocks[..]);
134
137
 
135
138
  let select_index_file = [
136
139
  {
137
- let file = tempfile().unwrap();
138
- file.set_len(self.select_index[0].len() as u64).unwrap();
140
+ let file = tempfile().map_err(PyRuntimeError::new_err)?;
141
+ file.set_len(self.select_index[0].len() as u64)
142
+ .map_err(PyRuntimeError::new_err)?;
139
143
  file
140
144
  },
141
145
  {
142
- let file = tempfile().unwrap();
143
- file.set_len(self.select_index[1].len() as u64).unwrap();
146
+ let file = tempfile().map_err(PyRuntimeError::new_err)?;
147
+ file.set_len(self.select_index[1].len() as u64)
148
+ .map_err(PyRuntimeError::new_err)?;
144
149
  file
145
150
  },
146
151
  ];
147
152
  let mut select_index = [
148
153
  #[allow(unsafe_code)]
149
154
  unsafe {
150
- MmapMut::map_mut(&select_index_file[0]).unwrap()
155
+ MmapMut::map_mut(&select_index_file[0]).map_err(PyRuntimeError::new_err)?
151
156
  },
152
157
  #[allow(unsafe_code)]
153
158
  unsafe {
154
- MmapMut::map_mut(&select_index_file[1]).unwrap()
159
+ MmapMut::map_mut(&select_index_file[1]).map_err(PyRuntimeError::new_err)?
155
160
  },
156
161
  ];
157
162
  select_index[0].copy_from_slice(&self.select_index[0][..]);
@@ -159,18 +164,22 @@ impl Clone for DiskBitVector {
159
164
 
160
165
  let [select_index_0, select_index_1] = select_index;
161
166
 
162
- Self {
167
+ Ok(Self {
163
168
  len: self.len,
164
- ranks: ranks.make_read_only().unwrap(),
169
+ ranks: ranks.make_read_only().map_err(PyRuntimeError::new_err)?,
165
170
  ranks_file,
166
- blocks: blocks.make_read_only().unwrap(),
171
+ blocks: blocks.make_read_only().map_err(PyRuntimeError::new_err)?,
167
172
  blocks_file,
168
173
  select_index: [
169
- select_index_0.make_read_only().unwrap(),
170
- select_index_1.make_read_only().unwrap(),
174
+ select_index_0
175
+ .make_read_only()
176
+ .map_err(PyRuntimeError::new_err)?,
177
+ select_index_1
178
+ .make_read_only()
179
+ .map_err(PyRuntimeError::new_err)?,
171
180
  ],
172
181
  select_index_file,
173
- }
182
+ })
174
183
  }
175
184
  }
176
185
 
@@ -186,8 +195,8 @@ impl BitVectorTrait for DiskBitVector {
186
195
  return Err(PyIndexError::new_err("index out of bounds"));
187
196
  }
188
197
  let (block_index, bit_index) = index.div_rem(&(BlockType::BITS as usize));
189
- let blocks_data: &[BlockType] = cast_slice(&self.blocks[..]);
190
- Ok(((blocks_data[block_index] >> bit_index) & BlockType::one()).is_one())
198
+ let blocks_slice: &[BlockType] = cast_slice(&self.blocks[..]);
199
+ Ok(((blocks_slice[block_index] >> bit_index) & BlockType::one()).is_one())
191
200
  }
192
201
 
193
202
  #[inline]
@@ -203,11 +212,11 @@ impl BitVectorTrait for DiskBitVector {
203
212
  }
204
213
 
205
214
  let (block_index, bit_index) = end.div_rem(&(BlockType::BITS as usize));
206
- let ranks_data: &[usize] = cast_slice(&self.ranks[..]);
207
- let blocks_data: &[BlockType] = cast_slice(&self.blocks[..]);
208
- let mut rank = ranks_data[block_index];
209
- if block_index < blocks_data.len() {
210
- rank += (blocks_data[block_index]
215
+ let ranks_slice: &[usize] = cast_slice(&self.ranks[..]);
216
+ let blocks_slice: &[BlockType] = cast_slice(&self.blocks[..]);
217
+ let mut rank = ranks_slice[block_index];
218
+ if block_index < blocks_slice.len() {
219
+ rank += (blocks_slice[block_index]
211
220
  & ((BlockType::one() << bit_index) - BlockType::one()))
212
221
  .count_ones() as usize;
213
222
  }
@@ -223,25 +232,25 @@ impl BitVectorTrait for DiskBitVector {
223
232
  return Ok(None);
224
233
  }
225
234
 
226
- let select_index_data: [&[usize]; 2] = [
235
+ let select_index_slice: [&[usize]; 2] = [
227
236
  cast_slice(&self.select_index[0][..]),
228
237
  cast_slice(&self.select_index[1][..]),
229
238
  ];
230
- let ranks_data: &[usize] = cast_slice(&self.ranks[..]);
231
- let blocks_data: &[BlockType] = cast_slice(&self.blocks[..]);
239
+ let ranks_slice: &[usize] = cast_slice(&self.ranks[..]);
240
+ let blocks_slice: &[BlockType] = cast_slice(&self.blocks[..]);
232
241
 
233
242
  let block_index = {
234
- let mut left = select_index_data[bit as usize][(kth - 1) / SELECT_INDEX_INTERVAL]
243
+ let mut left = select_index_slice[bit as usize][(kth - 1) / SELECT_INDEX_INTERVAL]
235
244
  / (BlockType::BITS as usize);
236
- let mut right = select_index_data[bit as usize][kth / SELECT_INDEX_INTERVAL + 1]
245
+ let mut right = select_index_slice[bit as usize][kth / SELECT_INDEX_INTERVAL + 1]
237
246
  .div_ceil(BlockType::BITS as usize);
238
247
  debug_assert!(right <= self.blocks.len());
239
248
  while left + 1 < right {
240
249
  let mid = (left + right) / 2;
241
250
  let rank_at_mid = if bit {
242
- ranks_data[mid]
251
+ ranks_slice[mid]
243
252
  } else {
244
- mid * (BlockType::BITS as usize) - ranks_data[mid]
253
+ mid * (BlockType::BITS as usize) - ranks_slice[mid]
245
254
  };
246
255
  if rank_at_mid < kth {
247
256
  left = mid;
@@ -253,11 +262,11 @@ impl BitVectorTrait for DiskBitVector {
253
262
  };
254
263
 
255
264
  kth -= if bit {
256
- ranks_data[block_index]
265
+ ranks_slice[block_index]
257
266
  } else {
258
- block_index * (BlockType::BITS as usize) - ranks_data[block_index]
267
+ block_index * (BlockType::BITS as usize) - ranks_slice[block_index]
259
268
  };
260
- let index = blocks_data[block_index].bit_select(bit, kth).unwrap()
269
+ let index = blocks_slice[block_index].bit_select(bit, kth).unwrap()
261
270
  + block_index * (BlockType::BITS as usize);
262
271
 
263
272
  Ok(Some(index))
@@ -278,11 +287,11 @@ mod tests {
278
287
  .unwrap();
279
288
  #[allow(unsafe_code)]
280
289
  let mut blocks = unsafe { MmapMut::map_mut(&blocks_file).unwrap() };
281
- let blocks_data: &mut [BlockType] = cast_slice_mut(&mut blocks[..]);
290
+ let blocks_slice: &mut [BlockType] = cast_slice_mut(&mut blocks[..]);
282
291
  bits.chunks(BlockType::BITS as usize)
283
292
  .enumerate()
284
293
  .for_each(|(index, chunk)| {
285
- blocks_data[index] =
294
+ blocks_slice[index] =
286
295
  chunk
287
296
  .iter()
288
297
  .enumerate()
@@ -14,7 +14,6 @@ use crate::traits::{
14
14
  wavelet_matrix::wavelet_matrix::WaveletMatrixTrait,
15
15
  };
16
16
 
17
- #[derive(Clone)]
18
17
  pub(crate) struct DiskWaveletMatrix<NumberType> {
19
18
  layers: Vec<DiskBitVector>,
20
19
  zeros_count_per_layer: Vec<usize>,
@@ -34,8 +33,8 @@ where
34
33
 
35
34
  let mut values = data;
36
35
  let mut _values_file = data_file;
37
- let values_data: &[NumberType] = cast_slice(&values[..]);
38
- let height = values_data
36
+ let values_slice: &[NumberType] = cast_slice(&values[..]);
37
+ let height = values_slice
39
38
  .par_iter()
40
39
  .max()
41
40
  .map_or(0usize, |max| max.bit_width());
@@ -60,14 +59,14 @@ where
60
59
  );
61
60
  let current_layer_bits_data: &mut [BlockType] =
62
61
  cast_slice_mut(&mut current_layer_bits[..]);
63
- let values_data: &[NumberType] = cast_slice(&values[..]);
62
+ let values_slice: &[NumberType] = cast_slice(&values[..]);
64
63
  current_layer_bits_data
65
64
  .iter_mut()
66
65
  .enumerate()
67
66
  .for_each(|(block_index, block)| {
68
67
  let start = block_index * BlockType::BITS as usize;
69
68
  let end = (start + BlockType::BITS as usize).min(len);
70
- for (j, value) in values_data[start..end].iter().enumerate() {
69
+ for (j, value) in values_slice[start..end].iter().enumerate() {
71
70
  if ((value >> (height - i - 1)) & NumberType::one()).is_one() {
72
71
  *block |= BlockType::one() << j;
73
72
  }
@@ -104,7 +103,7 @@ where
104
103
  .map(move |i| ((block >> i) & BlockType::one()).is_one())
105
104
  })
106
105
  .take(len),
107
- values_data.iter(),
106
+ values_slice.iter(),
108
107
  ) {
109
108
  if bit {
110
109
  next_values_data[one_index] = *value;
@@ -139,6 +138,21 @@ where
139
138
  phantom: marker::PhantomData,
140
139
  })
141
140
  }
141
+
142
+ pub(crate) fn try_clone(&self) -> PyResult<Self> {
143
+ let layers = self
144
+ .layers
145
+ .par_iter()
146
+ .map(|layer| layer.try_clone())
147
+ .collect::<PyResult<Vec<_>>>()?;
148
+ Ok(Self {
149
+ layers,
150
+ zeros_count_per_layer: self.zeros_count_per_layer.clone(),
151
+ height: self.height,
152
+ len: self.len,
153
+ phantom: marker::PhantomData,
154
+ })
155
+ }
142
156
  }
143
157
 
144
158
  impl<NumberType> WaveletMatrixTrait<NumberType, DiskBitVector> for DiskWaveletMatrix<NumberType>
@@ -195,8 +209,8 @@ mod tests {
195
209
  .map_err(PyRuntimeError::new_err)
196
210
  .unwrap()
197
211
  };
198
- let mmap_data: &mut [u8] = cast_slice_mut(&mut mmap[..]);
199
- mmap_data.copy_from_slice(&elements);
212
+ let mmap_slice: &mut [u8] = cast_slice_mut(&mut mmap[..]);
213
+ mmap_slice.copy_from_slice(&elements);
200
214
  DiskWaveletMatrix::new(mmap, file).unwrap()
201
215
  }
202
216
 
@@ -211,8 +225,8 @@ mod tests {
211
225
  .map_err(PyRuntimeError::new_err)
212
226
  .unwrap()
213
227
  };
214
- let mmap_data: &mut [u128] = cast_slice_mut(&mut mmap[..]);
215
- mmap_data.copy_from_slice(&elements);
228
+ let mmap_slice: &mut [u128] = cast_slice_mut(&mut mmap[..]);
229
+ mmap_slice.copy_from_slice(&elements);
216
230
  DiskWaveletMatrix::new(mmap, file).unwrap()
217
231
  }
218
232
 
@@ -422,8 +436,8 @@ mod tests {
422
436
  .map_err(PyRuntimeError::new_err)
423
437
  .unwrap()
424
438
  };
425
- let mmap_u8_data: &mut [u8] = cast_slice_mut(&mut mmap_u8_max_value[..]);
426
- mmap_u8_data.fill(u8::MAX);
439
+ let mmap_u8_slice: &mut [u8] = cast_slice_mut(&mut mmap_u8_max_value[..]);
440
+ mmap_u8_slice.fill(u8::MAX);
427
441
  let wv_u8 = DiskWaveletMatrix::<u8>::new(mmap_u8_max_value, file).unwrap();
428
442
  assert_eq!(wv_u8.len(), 64);
429
443
  assert_eq!(wv_u8.height(), 8);
@@ -452,8 +466,8 @@ mod tests {
452
466
  .map_err(PyRuntimeError::new_err)
453
467
  .unwrap()
454
468
  };
455
- let mmap_u128_data: &mut [u128] = cast_slice_mut(&mut mmap_u128_max_value[..]);
456
- mmap_u128_data.fill(u128::MAX);
469
+ let mmap_u128_slice: &mut [u128] = cast_slice_mut(&mut mmap_u128_max_value[..]);
470
+ mmap_u128_slice.fill(u128::MAX);
457
471
  let wv_u128 = DiskWaveletMatrix::<u128>::new(mmap_u128_max_value, file).unwrap();
458
472
  assert_eq!(wv_u128.len(), 64);
459
473
  assert_eq!(wv_u128.height(), 128);
@@ -17,7 +17,6 @@ use crate::{
17
17
  wavelet_matrix::wavelet_matrix::WaveletMatrix,
18
18
  };
19
19
 
20
- #[derive(Clone)]
21
20
  enum WaveletMatrixEnum {
22
21
  U8(WaveletMatrix<u8>),
23
22
  U16(WaveletMatrix<u16>),
@@ -56,7 +55,6 @@ enum WaveletMatrixEnum {
56
55
  /// from wavelet_matrix import WaveletMatrix
57
56
  /// wm = WaveletMatrix([5, 4, 5, 5, 2, 1, 5, 6, 1, 3, 5, 0], on_disk=False) # in-memory
58
57
  /// ```
59
- #[derive(Clone)]
60
58
  #[pyclass(name = "WaveletMatrix", skip_from_py_object)]
61
59
  pub(crate) struct PyWaveletMatrix {
62
60
  inner: WaveletMatrixEnum,
@@ -289,11 +287,45 @@ impl PyWaveletMatrix {
289
287
  }
290
288
 
291
289
  fn __copy__(&self, py: Python<'_>) -> PyResult<Self> {
292
- py.detach(move || Ok(self.clone()))
290
+ py.detach(move || match &self.inner {
291
+ WaveletMatrixEnum::U8(wm) => Ok(PyWaveletMatrix {
292
+ inner: WaveletMatrixEnum::U8(wm.clone()),
293
+ }),
294
+ WaveletMatrixEnum::U16(wm) => Ok(PyWaveletMatrix {
295
+ inner: WaveletMatrixEnum::U16(wm.clone()),
296
+ }),
297
+ WaveletMatrixEnum::U32(wm) => Ok(PyWaveletMatrix {
298
+ inner: WaveletMatrixEnum::U32(wm.clone()),
299
+ }),
300
+ WaveletMatrixEnum::U64(wm) => Ok(PyWaveletMatrix {
301
+ inner: WaveletMatrixEnum::U64(wm.clone()),
302
+ }),
303
+ WaveletMatrixEnum::U128(wm) => Ok(PyWaveletMatrix {
304
+ inner: WaveletMatrixEnum::U128(wm.clone()),
305
+ }),
306
+ WaveletMatrixEnum::BigUint(wm) => Ok(PyWaveletMatrix {
307
+ inner: WaveletMatrixEnum::BigUint(wm.clone()),
308
+ }),
309
+ WaveletMatrixEnum::DiskU8(wm) => Ok(PyWaveletMatrix {
310
+ inner: WaveletMatrixEnum::DiskU8(wm.try_clone()?),
311
+ }),
312
+ WaveletMatrixEnum::DiskU16(wm) => Ok(PyWaveletMatrix {
313
+ inner: WaveletMatrixEnum::DiskU16(wm.try_clone()?),
314
+ }),
315
+ WaveletMatrixEnum::DiskU32(wm) => Ok(PyWaveletMatrix {
316
+ inner: WaveletMatrixEnum::DiskU32(wm.try_clone()?),
317
+ }),
318
+ WaveletMatrixEnum::DiskU64(wm) => Ok(PyWaveletMatrix {
319
+ inner: WaveletMatrixEnum::DiskU64(wm.try_clone()?),
320
+ }),
321
+ WaveletMatrixEnum::DiskU128(wm) => Ok(PyWaveletMatrix {
322
+ inner: WaveletMatrixEnum::DiskU128(wm.try_clone()?),
323
+ }),
324
+ })
293
325
  }
294
326
 
295
327
  fn __deepcopy__(&self, py: Python<'_>, _memo: &Bound<'_, PyAny>) -> PyResult<Self> {
296
- py.detach(move || Ok(self.clone()))
328
+ self.__copy__(py)
297
329
  }
298
330
 
299
331
  /// Return the entire sequence as a Python list.
@@ -1,6 +1,5 @@
1
1
  use std::{collections, hash, iter, ops};
2
2
 
3
- use itertools::Itertools;
4
3
  use num_bigint::ToBigUint;
5
4
  use num_traits::{One, Zero};
6
5
  use rayon::prelude::*;
@@ -47,8 +46,8 @@ where
47
46
  .par_iter()
48
47
  .map(|value| (value >> (height - i - 1) & NumberType::one()).is_one())
49
48
  .collect::<Vec<bool>>();
50
-
51
49
  let zeros_count = current_layer_bits.par_iter().filter(|&&b| !b).count();
50
+
52
51
  let mut next_values = vec![NumberType::one(); len];
53
52
  let mut zero_index = 0usize;
54
53
  let mut one_index = zeros_count;
@@ -63,17 +62,19 @@ where
63
62
  }
64
63
 
65
64
  let current_layer_blocks = current_layer_bits
66
- .into_iter()
65
+ .into_par_iter()
67
66
  .chunks(BlockType::BITS as usize)
68
- .into_iter()
69
67
  .map(|chunk| {
70
- chunk.enumerate().fold(BlockType::zero(), |acc, (j, b)| {
71
- if b {
72
- acc | (BlockType::one() << j)
73
- } else {
74
- acc
75
- }
76
- })
68
+ chunk
69
+ .iter()
70
+ .enumerate()
71
+ .fold(BlockType::zero(), |acc, (j, &b)| {
72
+ if b {
73
+ acc | (BlockType::one() << j)
74
+ } else {
75
+ acc
76
+ }
77
+ })
77
78
  })
78
79
  .collect::<Vec<_>>();
79
80
 
File without changes
File without changes