Expand description
§Prime Data
Onto the actual data structure for storing prime numbers.
The structure contains two fields. data and range.
§data: Vec<PrimeByte>
The data is straightforward. It’s simply a vector of prime bytes. However,
let’s say we want to store the primes up to 1 million. We can’t exactly divide that into our data
because 1_000_000 % 30 = 10. So we’ll end up using 33_334 bytes, but that last byte will not
contain the full information about primes in the range (999_990, 1_000_020).
Therefore, this data would produce undefined behaviour if we tried to retrieve the primes in that last byte of data. In order for us to rigorously make sure to return an error when it happens, we need to store a range.
§range: RangeInclusive<u64>
An inclusive range will determine what are the exact bounds of the given data. For example, if we had only one byte of data, and the range was (33..=58), we can infer that the byte of data represents prime candidates from (30..60), however, the first bit is not part of the data, as it represents 31. Same goes for the last bit of data, which represents 59. Trying to access those bits should result in an error.
The range start is especially important because it also determines the byte offset we discussed in the introduction. The offset is basically the range start divided by 30. If the range starts at 0, 20, or anything below 30, the first byte corresponds to (0..30). As soon as the range starts at 30, this means the first byte corresponds to (30..60) instead.
The range will also be an important factor for expanding data. But in order to expand data, we need to understand how to iterate over them.