DigitBinIndex
A DigitBinIndex is a tree-based data structure designed for efficient weighted random selection and removal from large collections of items. It is optimized for scenarios involving millions of items where quantized weights or probabilities are acceptable and high performance is critical, including independent event simulation, Wallenius' noncentral hypergeometric distribution, Fisher's noncentral hypergeometric distribution, and fixed-size PPS sampling.
This library provides high-performance solutions for four complementary weighted sampling designs:
- Independent Event Sampling (Bernoulli): Modeled by
select_bernoulli_manyandselect_bernoulli_many_and_remove, where each weight is an absolute event probability and the sample size is random. - Sequential Sampling (Wallenius'): Modeled by
select_and_remove, where items are selected and removed one at a time. - Simultaneous Sampling (Fisher's): Modeled by
select_many_and_remove, where a batch of unique items is selected and removed together. - Marginal Inclusion Sampling (PPS): Modeled by
select_pps_manyandselect_pps_many_and_remove, where weights specify desired first-order inclusion probabilities in a fixed-size sample.
The Core Problem
In simulations, forecasts, or statistical models (e.g., mortality models, Monte Carlo simulations, or machine learning sampling), managing a large, dynamic set of probabilities is common. A key task is to randomly select items based on their weights, often removing them afterward, and repeat this process efficiently. For datasets with millions of items, achieving high performance while maintaining reasonable accuracy is a significant challenge, especially for complex distributions like Wallenius' or Fisher's.
How It Works
DigitBinIndex is a radix tree that organizes items into bins based on the decimal digits of their rescaled probabilities, enabling fast weighted random selection and updates.
-
Digit-based Tree Structure: Each level of the tree corresponds to a decimal place of the rescaled weight. For example, a weight of
0.543at precision 3 is rescaled to543and placed by traversing the path:root -> child[5] -> child[4] -> child[3]. -
Selectable Bin Storage: Leaf nodes store IDs in
Vec<u32>,RoaringBitmap, orRoaringTreemap. A capacity hint selects a backend from expected average occupancy; explicitly choose a backend for highly skewed weights or when fullu64IDs are required. -
Accumulated Value Index: Each node tracks the
accumulated_value(sum of weights beneath it), supporting O(P) weighted random selection, where P is the configured precision (number of decimal places). -
Exact Binned Bernoulli Sampling: Each occupied bin draws its selected count from a binomial distribution using the bin's quantized probability, then samples that many IDs uniformly. This is exactly equivalent to an independent Bernoulli trial per item while avoiding a population-wide probability check.
-
Adaptive Exact Fisher Sampling: Batch draws operate on occupied weight bins rather than expanding the population. Small draws use weighted proposals conditioned on all IDs being unique. Larger draws sample exponentially tilted binomial counts for each occupied bin and condition their sum on the requested sample size. Both paths produce Fisher's noncentral hypergeometric law for the quantized weights.
-
Fixed-Size PPS Sampling: PPS draws water-fill certainty items, randomly order the remaining occupied bins, and use exact integer systematic rounding to allocate the requested sample size. Uniform sampling without replacement inside each bin gives every item its requested marginal inclusion probability under the quantized weights.
-
Persistent Sequential Sampling: Each index seeds a fast
WyRandgenerator once and reuses it for sequential convenience methods. Rust callers can provide their own generator throughselect_with_rngandselect_and_remove_with_rng.select_wallenius_many_and_removeperforms many sequential removals in one call, avoiding repeated Python/Rust boundary crossings while preserving Wallenius' law. -
Lazy Mass-Optimal Child Scans: Internal nodes keep direct digit lookup for updates and a separate scan order sorted by descending accumulated mass. Mutations invalidate ordering cheaply; only nodes reached by a later selection sort their at-most-ten active children. Selection removals maintain the visited path locally.
Features
- High Performance: Outperforms general-purpose data structures like Fenwick Trees for both sequential and simultaneous weighted sampling.
- Four Explicit Sampling Designs: Independent Bernoulli events (
select_bernoulli_many), optimized sequential Wallenius draws (select_and_remove), exact Fisher draws over quantized weights (select_many_and_remove), and fixed-size PPS draws with exact first-order inclusion probabilities (select_pps_many). - Bounded Tree Traversal: Radix traversal is O(P), where P is the fixed precision. Explicit
Vec-leaf removal is linear in that leaf's occupancy, and exact Fisher batches also depend on occupied bins. - Memory Efficiency: Combines a sparse radix tree with Roaring Bitmaps for efficient storage, especially for sparse or clustered weight distributions.
- Python Integration: Seamless Python bindings via
pyo3for cross-language support.
Choosing the Selection Model
Choose a method from how the events are generated, not from what happens to the selected IDs afterward. In particular, a weight is not automatically an absolute event probability.
| Question being modeled | Method | Simple example |
|---|---|---|
| Who wins one weighted draw? | select or select_and_remove |
Choose one job from a queue, with urgency as its relative weight. Remove it if the job must not be chosen again. |
Who wins each of k independent draws when the same item may appear repeatedly? |
Call select() k times without changing the index |
Allocate k ad impressions independently; the resulting per-item counts follow a multinomial law. |
Who fills k places awarded one at a time? |
select_wallenius_many_and_remove(k) |
Award k appointments sequentially. At each step, every remaining person's chance is proportional to their priority weight. |
Which k independent binary events occurred, given that their total is k? |
select_many(k) or select_many_and_remove(k) (Fisher) |
Components fail independently with different probabilities; after learning that exactly k failed, sample their identities. Use failure odds, p / (1 - p), as relative weights. |
| Who belongs to a fixed cohort when marginal inclusion chances must be proportional to size? | select_pps_many(k) or select_pps_many_and_remove(k) |
Audit exactly k invoices, giving an invoice with twice the value twice the marginal chance of inclusion. |
| Does each item independently experience an event during this period? | select_bernoulli_many() or select_bernoulli_many_and_remove() |
Simulate whether each person dies or moves using that person's period probability. The number of events remains random. |
The versions without and_remove leave the index unchanged. The versions with
and_remove use the same sampling law and then remove the selected IDs.
Repeated calls to select() already provide weighted sampling with replacement;
a native batch wrapper would improve call overhead but would not introduce a
new distribution. Equal weights reduce the fixed-size methods to their ordinary
unweighted counterparts. In survey-sampling terminology, independent Bernoulli
inclusion is also called Poisson sampling,
where independent selections produce a random sample size.
Mortality Over Time
Suppose person i has probability p_i(t) of dying during period t. When
the model treats people as conditionally independent given those probabilities,
Bernoulli selection performs one trial per living person using the index's
quantized probabilities:
deaths = mortality_index.select_bernoulli_many_and_remove()
The index accepts probabilities strictly between zero and one. Leave p=0
items out of the selectable index and handle p=1 events deterministically.
The number of deaths is random, with expected value equal to the sum of the quantized probabilities. A fixed-size method should not replace this draw: PPS would force a chosen total and rescale the marginal probabilities, while Fisher and Wallenius would impose different dependence between people.
There are two related mortality models that do use this library:
- If an external model fixes the period total at exactly
kdeaths, and the desired model is independent deaths conditioned on that total, use Fisher'sselect_many_and_remove(k). Convert each probability to oddsp_i / (1 - p_i), then multiply all odds by the same positive constant so the largest index weight is below one. Common scaling does not change the Fisher law. - In a continuous-time, event-driven model with instantaneous mortality hazards
h_i(t),select_and_removecan choose the identity of the next death using hazards as relative weights. Scale all hazards by the same positive constant if needed to fit the index's weight range. Calendar time is a separate draw: while hazards are constant, the waiting time is exponential with ratesum(h_i). Update hazards whenever the simulated state or time changes.
Fisher's distribution is the conditional distribution of independent binomial variates given their sum; see Fog, “Noncentral hypergeometric distributions”.
Migration Over Time
Use the same rule for migration because the subject matter does not determine the sampling law:
- If
p_i(t)is personi's probability of moving during the period, useselect_bernoulli_many()orselect_bernoulli_many_and_remove(). The number of movers is random. - If exactly
kindependent move decisions are known to have occurred, use Fisher with oddsp_i / (1 - p_i). - If
kscarce relocation places are filled sequentially from a changing pool, use Wallenius with relative priority or propensity weights. - If exactly
kpeople must be included and the requirement is that marginal inclusion chances be proportional to a risk, exposure, or policy score, use PPS.
For both mortality and migration, removal only describes the state update. A death is removed from the population; a mover is normally removed from the origin index and added to a destination index. It does not by itself determine which sampling distribution is appropriate.
Performance
DigitBinIndex trades a small, controllable amount of precision by binning
weights or probabilities to achieve significant performance gains. The
Criterion suite compares Bernoulli selection with an item-level probability
scan and compares the fixed-size designs with general-purpose weighted data
structures in high-churn simulations.
The churn benchmarks start with a large population (1M or 10M items), then simulate a high volume of activity:
- Churn: A significant number of items are selected and removed.
- Acquisition: New items are added to the population.
The historical churn tables were measured on a desktop with an Intel i7, 16 GB RAM, and Rust 1.75. Newer local-development measurements are labeled as such and should be rerun on the documented release hardware before publication.
Independent Bernoulli Draw
For a bin containing n items with quantized probability p, Bernoulli
selection draws K ~ Binomial(n, p) and then chooses a uniform K-subset of
the bin. Every particular subset therefore has the same probability it would
have under independent item-level Bernoulli trials. Counts are drawn
independently across bins.
select_bernoulli_many() leaves the index unchanged;
select_bernoulli_many_and_remove() removes the events. Both return a
random-size sample, and an empty vector is a normal successful result. For
quantized probabilities p_i:
expected_sample_size = sum(p_i)
sample_size_variance = sum(p_i * (1 - p_i))
The one-million-item Criterion workload uses probabilities from the smallest positive bin through 5% and includes removal of selected IDs:
| Precision | Binned Bernoulli | Item-level scan | Result |
|---|---|---|---|
| 3 | 0.56 ms | 1.22 ms | 2.2x faster |
| 5 | 1.88 ms | 1.16 ms | 1.6x slower |
At p=3, only 50 probability bins are occupied and binomial aggregation avoids almost all item-level trials. At p=5, roughly 5,000 bins are occupied, so bin traversal and distribution setup cost more than a tight item scan. These are local development measurements and show why p=3 or p=4 should remain the default unless finer probability resolution is material.
Wallenius' Draw (Sequential Churn)
This benchmark simulates sequential selection by removing 100,000 items one-by-one, then adding 110,000 new items. This is a common pattern in agent-based models or iterative simulations. DigitBinIndex's O(P) complexity gives it a decisive advantage as the population scales.
| Scenario (N items) | DigitBinIndex Time |
FenwickTree Time |
Speedup Factor |
|---|---|---|---|
| 1 Million Items (p=3) | ~27.5 ms | ~82.2 ms | ~3.0x faster |
| 1 Million Items (p=5) | ~39.7 ms | ~77.7 ms | ~2.0x faster |
| 10 Million Items (p=3) | ~551.0 ms | ~1723.1 ms | ~3.1x faster |
- Key Takeaway:
DigitBinIndexis over 3.0 times faster than theFenwickTreefor sequential operations on large datasets. Its performance is dependent on precision (P) and not the number of items (N), allowing it to scale far more effectively.
These are historical v0.4.2 measurements. The current implementation reuses RNG state, propagates integer weights through the hot path, removes runtime selection/removal branching, and scans children in descending accumulated-mass order. Updated numbers should replace this table after rerunning the Criterion suite on the documented hardware. The suite now includes a heavily skewed workload whose dominant mass occupies a low-digit branch.
Fisher's Draw (Batch Churn)
Batch sampling now implements the exact Fisher law for the quantized weights. It uses two adaptive engines:
- Small samples: weighted item proposals conditioned on uniqueness. Expected work is close to O(kP) while collision probability is low.
- Larger samples: conditional binomial sampling over the B occupied weight bins, followed by uniform sampling within each selected bin. High-bin-count workloads use partial convolution blocks so each exact-sum proposal samples block totals rather than every individual bin. Runtime depends on B rather than population size N. Draws over half the population sample the smaller complement with reciprocal weights.
The previous Fisher timing table measured the earlier capped-multinomial approximation and is not comparable to the exact implementation. The Criterion suite retains 1M and 10M batch scenarios at precision 3 and 5; updated numbers should be published after benchmarking the exact sampler on the documented hardware. Precision 3 has at most 999 positive-weight bins and is expected to remain the strongest large-batch configuration. High precision with many occupied bins is intentionally covered as a stress case.
Fixed-Size PPS Draw
PPS sampling answers a different question from Fisher or Wallenius. In Fisher and Wallenius draws, weights are odds that determine a joint distribution. In PPS sampling, weights are size measures that determine each item's marginal probability of appearing in a fixed-size sample. This is useful when selecting an audit, inspection, or evaluation cohort where an item with twice the exposure should have twice the inclusion probability.
For a requested sample size k, the PPS methods target
inclusion_probability_i = min(1, lambda * quantized_weight_i)
where lambda is chosen so that the inclusion probabilities sum to k.
Items whose probability reaches one are certainty items; their slots and mass
are removed before lambda is recomputed for the remaining population. This is
the standard feasibility treatment required when a strictly proportional
probability would exceed one.
select_pps_many(k) returns k unique IDs without changing the index.
select_pps_many_and_remove(k) uses the same design and removes them. The
implementation randomly orders occupied equal-weight bins, applies systematic
rounding with an exact integer random start, and samples uniformly without
replacement inside each bin. Consequently:
- the sample size is always exactly
k; - every returned ID is unique;
- first-order inclusion probabilities are exact for the index's quantized weights;
- the joint law is the documented randomized systematic PPS design, not Fisher's or Wallenius' law.
In the Criterion suite's 1-million-item churn scenario (select and remove 100,000, then add 110,000), the binned PPS implementation avoids expanding and shuffling the full population:
| Precision | DigitBinIndex PPS |
Item-level systematic PPS baseline | Speedup |
|---|---|---|---|
| 3 | 16.9 ms | 42.9 ms | 2.5x |
| 5 | 25.1 ms | 43.5 ms | 1.7x |
These are local development measurements and should be treated as hardware-dependent; the benchmark source is included for reproducibility.
Systematic unequal-probability sampling with a random start is a longstanding fixed-size PPS design; see Hartley (1966), “Systematic Sampling with Unequal Probability and without Replacement”. Applications that require design-based variance estimates must also account for the design's second-order inclusion probabilities rather than treating selected items as independent.
When to Choose DigitBinIndex
Use DigitBinIndex when:
- You need to simulate many independent binary events from quantized per-item probabilities without scanning every item.
- You need high-performance sampling for Wallenius' or Fisher's distributions.
- You need a fixed-size PPS cohort whose marginal inclusion probabilities are proportional to an exposure, value, or risk measure.
- Your dataset is large (N > 100,000).
- Probabilities are approximate, as is common in empirical data, simulations, or machine learning models.
- Performance is more critical than perfect precision.
Consider a Fenwick Tree if you require exact precision and your weights differ only at high decimal places (e.g., 0.12345 vs. 0.12346), though this comes at the cost of O(log N) complexity and higher memory usage for large datasets.
Choosing a Precision
The precision parameter controls the radix tree's depth, balancing accuracy, performance, and memory. Higher precision improves sampling accuracy but increases memory usage (up to 10x per additional level) and slightly impacts runtime.
The Rule of Thumb
A precision of 3 or 4 (default: 3) is recommended for most applications. This captures sufficient detail for typical weight distributions while maintaining excellent performance and low memory usage.
The Mathematical Intuition
Each decimal place contributes exponentially less to a weight’s value. For a weight of 0.12345:
- 1st digit (
1):0.1 - 2nd digit (
2):0.02 - 3rd digit (
3):0.003 - 4th digit (
4):0.0004
Rounding to 3 digits limits the error per item to at most 0.0005, except at the positive boundaries where values are clamped to the smallest or largest representable bin.
Guidance
| Precision | Typical Use Case | Trade-offs |
|---|---|---|
| 1-2 | Maximum performance, minimal memory usage. | Best for coarse weights (e.g., 0.1, 0.5). Loses accuracy with fine-grained data. |
| 3-4 | Recommended Default. Optimal for most scenarios. | Captures sufficient detail for simulation or model data. Negligible performance/memory cost. |
| 5+ | High-fidelity scenarios with very close weights. | Distinguishes weights like 0.12345 vs. 0.12346. Increases memory (up to 10x per level) and slightly impacts performance. |
Mutation Contract and Capacity
Weights must be finite and strictly between zero and one. Rust mutation methods
return Result; Python raises ValueError for invalid weights and duplicates,
and OverflowError for an ID that does not fit the selected backend. Batch
addition validates the complete input before changing the tree. Batch removal
is ordered and partially mutating when a valid (ID, weight) pair is missing.
Counts and scaled-weight sums use u64 and are checked before growth. At
precision 9, repeatedly adding weights near one reaches the scaled-mass limit at
roughly 18.4 billion items; the insertion that would exceed the limit returns an
error rather than wrapping.
Internal Storage and Capacity
The DigitBinIndex is designed to handle a vast range of use cases, from a few thousand items to trillions, by automatically selecting the most appropriate internal storage engine.
Item Capacity
The index accepts u64 item IDs. Small and Medium return an error for IDs above u32::MAX; Large supports the complete u64 range. IDs are unique across the complete index, including across different weight bins.
To provide the best balance of performance and memory usage, the library's DigitBinIndex is an enum that automatically switches between three different backends (Small, Medium, and Large) when you use the with_precision_and_capacity() constructor or the explicit constructors small(), medium(), and large().
The selection is based on a simple heuristic: the average number of items expected per bin, which is calculated as capacity / 10^precision.
The capacity hint cannot infer ID width or weight skew. Use large whenever an
ID may exceed u32::MAX. If many items share a small number of weights, compare
small and medium with representative data; the Criterion suite includes a
single-bin backend benchmark for this case.
-
Small(Vec<u32>):- Constructor:
small(precision: u8). - Backend Datatype:
u32(max 4 billion). - Capacity Trigger: Low average items per bin (<= 1,000).
- Best for: Small to medium-sized problems where
select_and_removespeed is the absolute priority (O(1)swap_remove). - Warning: Rejects IDs above
u32::MAX. Explicit removal is linear in the selected leaf's occupancy.
- Constructor:
-
Medium(RoaringBitmap):- Constructor:
medium(precision: u8). - Backend Datatype:
u32(max 4 billion). - Capacity Trigger: Medium to large average items per bin (> 1,000).
- Best for: Large-scale problems where IDs fit within
u32, especially heavily occupied or clustered bins. - Warning: Rejects IDs above
u32::MAX.
- Constructor:
-
Large(RoaringTreemap):- Constructor:
large(precision: u8). - Backend Datatype:
u64(max 18 quintillion = 18 billion billions). - Capacity Trigger: Extremely large average items per bin (> 1,000,000,000). This is used as a heuristic to detect that full
u64support is required. - Best for: Massive-scale simulations or any dataset that requires the full 64-bit ID space.
- Constructor:
Examples of Engine Selection
Here are some practical examples of how calling with_precision_and_capacity translates into a specific internal engine.
Example 1: Small (Vec<u32>) is Chosen
You are simulating a population of 100,000 individuals with u32 IDs.
// Expecting 100,000 items with 3-digit precision
let index = DigitBinIndex::with_precision_and_capacity(3, 100_000);
- Calculation: The number of bins is
10^3 = 1,000. The average items per bin is100,000 / 1,000 = 100. - Result: Since 100 <= 1,000, the
Smallvariant is chosen. IDs aboveu32::MAXwill be rejected rather than truncated.
Example 2: Medium (RoaringBitmap) is Chosen
You need to index 50 million product IDs, all of which fit within u32.
// Expecting 50 million items with 3-digit precision
let index = DigitBinIndex::with_precision_and_capacity(3, 50_000_000);
- Calculation: The average items per bin is
50,000,000 / 1,000 = 50,000. - Result: This is > 1,000. The
Mediumvariant is selected, usingRoaringBitmap; IDs aboveu32::MAXwill be rejected.
Example 3: Large (RoaringTreemap) is Chosen
You are working with a massive dataset where item IDs are 64-bit, and you expect trillions of entries.
// Expecting 5 trillion items with 3-digit precision
let index = DigitBinIndex::with_precision_and_capacity(3, 5_000_000_000_000);
- Calculation: The average items per bin is
5_000_000_000_000 / 1,000 = 5,000,000,000. - Result: This is > 1,000,000,000. The
Largevariant is chosen. The heuristic correctly identifies this as au64-scale problem and selects the only backend,RoaringTreemap, that provides full 64-bit ID support.
Usage & Installation
DigitBinIndex is available as a Python library on PyPI or as a Rust crate on Crates.io. The Python bindings require Python 3.8+.
For Python 🐍
Install from PyPI:
pip install digit-bin-index
Example usage:
from digit_bin_index import DigitBinIndex
def main():
# Create an index with precision 3 (default).
index = DigitBinIndex()
# With custom precision
index_5 = DigitBinIndex.with_precision(5)
# With custom precision and capacity hint for large datasets
# This might choose a more memory-efficient internal storage.
index_3_xl = DigitBinIndex.with_precision_and_capacity(3, 10_000_000)
# Add items with IDs and weights.
index.add(id=101, weight=0.123) # Low weight
index.add(id=202, weight=0.800) # High weight
index.add(id=303, weight=0.755) # High weight
index.add(id=404, weight=0.110) # Low weight
# Independent Bernoulli draw: each stored weight is the item's absolute
# event probability. The result size is random; the index is unchanged.
period_events = index.select_bernoulli_many()
print(f"Bernoulli events: {period_events}")
# Sequential (Wallenius') Draw: Select and remove one item.
# Higher-weighted items (202, 303) are more likely.
selected_item = index.select_and_remove()
if selected_item:
# The returned weight is a float, representing the bin's average weight
item_id, weight = selected_item
print(f"Wallenius draw: ID {item_id}, Weight ~{weight:.3f}")
print(f"Items remaining: {index.count()}") # 3
# For many sequential Wallenius draws, use one native batch call:
# churned_items = index.select_wallenius_many_and_remove(100_000)
# Fixed-size PPS draw: weights control marginal inclusion probabilities.
# This returns unique IDs without changing the index.
pps_items = index.select_pps_many(2)
if pps_items:
print(f"PPS draw: {pps_items}")
# Simultaneous (Fisher's) Draw: Select and remove 2 unique items.
selected_items = index.select_many_and_remove(2)
if selected_items:
print(f"Fisher's draw: {selected_items}")
print(f"Items remaining: {index.count()}") # 1
if __name__ == "__main__":
main()
For Rust 🦀
Add to your Cargo.toml:
[dependencies]
digit-bin-index = "0.4.2" # Replace with the latest version from crates.io
Example usage:
use digit_bin_index::DigitBinIndex;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create an index with precision 3.
let mut index = DigitBinIndex::with_precision(3);
// Add items with IDs and f64 weights.
index.add(101, 0.123)?; // Low weight
index.add(202, 0.800)?; // High weight
index.add(303, 0.755)?; // High weight
index.add(404, 0.110)?; // Low weight
// Independent Bernoulli draw: each weight is an absolute event
// probability. The result size is random; the index is unchanged.
let period_events = index.select_bernoulli_many().unwrap();
println!("Bernoulli events: {:?}", period_events);
// Sequential (Wallenius') Draw: Select and remove one item.
if let Some((id, weight)) = index.select_and_remove() {
println!("Wallenius draw: ID {}, Weight ~{}", id, weight);
}
println!("Items remaining: {}", index.count()); // 3
// For repeated sequential draws, reuse the index RNG in one call:
// let churned_items = index.select_wallenius_many_and_remove(100_000);
// Fixed-size PPS draw: weights control marginal inclusion probabilities.
// The index is not changed.
if let Some(items) = index.select_pps_many(2) {
println!("PPS draw: {:?}", items);
}
// Simultaneous (Fisher's) Draw: Select and remove 2 unique items.
if let Some(items) = index.select_many_and_remove(2) {
println!("Fisher's draw: {:?}", items);
}
println!("Items remaining: {}", index.count()); // 1
Ok(())
}
License
This project is licensed under the MIT License, a permissive open-source license allowing free use, modification, and distribution.
Release files for digit-bin-index 0.4.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| digit_bin_index-0.4.3.tar.gz | 70.2 kB | Details |
Built distributions (wheels)
Total release size: 6.1 MB
Release files / digit_bin_index-0.4.3.tar.gz
| Download URL | digit_bin_index-0.4.3.tar.gz |
|---|---|
| Size | 70.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
31665ca2df652f327872e49d1e34ed2e09e2e9d63263813099dbd8497dff6794
|
|
BLAKE2b-256 checksum How to use checksums |
9ce14c0cecc326b5384f06246bd37d5f227c002508702a9d5f2f4a3f6dd9630e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-win_amd64.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 257.3 kB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
22daa089a9eb758fffbd6cc2bdb4e7596812edecdad3c59b48a149f79bfbb4eb
|
|
BLAKE2b-256 checksum How to use checksums |
67f6643cbb010a31c8b53a0626309a85624d2faa8226141ae0aaeeeca8d653d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-win32.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-win32.whl |
|---|---|
| Size | 254.5 kB |
| Tags | CPython 3.8 Windows x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
142bf38048165568f6fd8fba6877b0581fd1f47fe6483ad7707db531a184e2d0
|
|
BLAKE2b-256 checksum How to use checksums |
a993ae9330378ab6b9131ddeaa1ff8dd8bbe4051271ff79e5e6b9a8cebf7cc29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-musllinux_1_2_x86_64.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 583.3 kB |
| Tags | CPython 3.8 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
45cb4c097cccf9fb86dcd0e8693e94831143a72ae2f366aa674c82e2aa6e15fa
|
|
BLAKE2b-256 checksum How to use checksums |
b5e055e2b8f16061478db19076e5c8167932af1ff01112ab7e5eaf0827d081b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-musllinux_1_2_i686.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-musllinux_1_2_i686.whl |
|---|---|
| Size | 623.4 kB |
| Tags | CPython 3.8 Linux musl 1.2+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
6a5b441dfa6e3600c849f3d50595c12f533acd995c06c03f7520e2db58a3e8ee
|
|
BLAKE2b-256 checksum How to use checksums |
0171e88ca7cd950a843ee1b7a613b1c09ffab76bdab018de76576138ec9eabe2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-musllinux_1_2_armv7l.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-musllinux_1_2_armv7l.whl |
|---|---|
| Size | 666.3 kB |
| Tags | CPython 3.8 Linux musl 1.2+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
76a224a411c6c3ded51cba8198a92a620d7c35dc6aa483bb66f8d5e81639e912
|
|
BLAKE2b-256 checksum How to use checksums |
9da72ee94589247eb9276f9999f53dd7f2a0a5f19fc56e7fb186fef354e2309f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-musllinux_1_2_aarch64.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 537.1 kB |
| Tags | CPython 3.8 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
518a18be6044f358e875627d35f541a754f06ee205a7ea720cbbcd96a9d8a50c
|
|
BLAKE2b-256 checksum How to use checksums |
43336475da7376265b19eb9e7b08f619c49af858a9a4ce326a007285e2075bd7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 372.5 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
bc5cdb9eb3ee6e9f0e25c32a0b82d10b712f117a9d7b331e0a5a3eb1c26fd598
|
|
BLAKE2b-256 checksum How to use checksums |
5713e1e3dddeb99e8428628156dd1ecc68ddc4a59bad5a2ab40706c39f25367b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl |
|---|---|
| Size | 418.1 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ IBM System/390x abi3 |
|
SHA-256 checksum How to use checksums |
e99e41dd151c1120d5e11ebe60f30e68264c74e73cd0410e10640c20da378478
|
|
BLAKE2b-256 checksum How to use checksums |
ae3ab90c6b2b2ec861108393cf40e726ba48dbad3dc2b9b2b6238db2298497d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl |
|---|---|
| Size | 422.1 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ PowerPC 64-le abi3 |
|
SHA-256 checksum How to use checksums |
0ebe3a30da3d734a57f307482ef2bebddaa701bafb93d5c25109997fd2aaa4f9
|
|
BLAKE2b-256 checksum How to use checksums |
6f973b7a474e3b66d69e3bd406320e15031aafdd394f741ecda3adf9347eda7c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl |
|---|---|
| Size | 391.6 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
7c1a3443eb3df7758134b5bba0e99c008ce8024771d7a96e09d87ba51c897739
|
|
BLAKE2b-256 checksum How to use checksums |
2cbb2a0418fe53a73701f02986191be3e13319a690f8622e4e329e6b656ded54
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 359.8 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
ffbdd4007389beb3c1a6c850b461d00f7608508c47b8415ff5ac43b6113fac3a
|
|
BLAKE2b-256 checksum How to use checksums |
d9c241896104635844fff1e78204dddcbff731078f8704d8e7306b2517593667
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl |
|---|---|
| Size | 407.3 kB |
| Tags | CPython 3.8 Linux glibc 2.5+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
ee3f3e69005535ee664bd18bb2c4618903f2dd67df94a6b994883a7da803e371
|
|
BLAKE2b-256 checksum How to use checksums |
21f7d9bd953371c73d084a5bad8be4cea44864b383cd48c2e5c8ec0ae2400049
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 337.4 kB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
c1f1c851bd97e123ab0ca025983a03cb47d36aedb7ee549e1282e7ae4f312061
|
|
BLAKE2b-256 checksum How to use checksums |
5029c7c404d2e15de74338ca5a415d87946d4e9f15c18190d62e9cfd1e4318a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|
Release files / digit_bin_index-0.4.3-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | digit_bin_index-0.4.3-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 353.8 kB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
1a6add00090814fa1bff7ee9f463c5391f638b4a92d98ef6bb6acb43b4dbd314
|
|
BLAKE2b-256 checksum How to use checksums |
a008be264fb50973b6f5809cf6affd984c37ae83cf123c1d83948f57e694c444
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.14.1
|