I'm currently developping a little in-RAM storage driver for a project. I want to be able to represent a storage of several gigabytes even when there's not enough RAM for that.
In order to make this work, I represent the storage as a list of 256-bytes sector, which are not allocated in memory until they are used.
Here the current implementation:
When one wants to read a sector, if it's a None value a zeroed array. This means that, until a sector is written, it is not allocated in memory.
The problem is that, the way Rust's enums work, each entry in the vector takes 257 bytes, as the size of an enum is (approximately) the size of the largest field in it.
What I'd like is a way to store an array of 256 bytes which is by default not allocated in memory (so we can't access the data in it) but can be allocated whenever I want (and then we can access the data in it).
The main problem is that I don't want to use any unsafe code. The crate I'm working on has #[forbid(unsafe_code)] and I don't want to remove it just for this part.
So, is there any native way to achieve this without using unsafe code, and if possible without any external crate?
Thanks in advance for your help
EDIT 1 : I've thought about using a HashMap this way:
You could add a field called initialized that used one bit per sector to store if it's initialized or not. Note that with the current design, only the sectors at the end of the vector can be uninitialized without using up memory. Similarly resizing the vector will be expensive and involve a full copy that requires double the amount of memory of the size of the vector during the resize.
But the problem is that sectors will be disordered, which would result in very high latency.
And if I use a HashMap to store the sectors depending on their addresses, there will be a cost for both allocating new sectors and accessing them, which I'd like to avoid.