Switch to BTreeMap index
parent
4aad43a939
commit
323a0c9a63
|
@ -17,11 +17,18 @@ Therefore, the "filesystem" code will just be a library that's simple a low-leve
|
||||||
|
|
||||||
## Performance
|
## Performance
|
||||||
I believe that this format should be fairly fast, but only implementation and testing will tell for sure.
|
I believe that this format should be fairly fast, but only implementation and testing will tell for sure.
|
||||||
|
Throughput is the main concern here, rather than latency. We can be asynchronous as wait for many requests to finish, rather than worrying about when they finish. This is also better for **SSD** performance.
|
||||||
1. Minimal data needs to read in - bit offsets can be used, and only fixed-size metadata must be known
|
1. Minimal data needs to read in - bit offsets can be used, and only fixed-size metadata must be known
|
||||||
2. `serde` is fairly optimized for deserialization/serialization
|
2. `serde` is fairly optimized for deserialization/serialization
|
||||||
3. `HighwayHash` is a very fast and well-optimized hashing algorithm
|
3. `HighwayHash` is a very fast and well-optimized hashing algorithm
|
||||||
4. Async and multithreading will allow for concurrent access, and splitting of resource-intensive tasks across threads
|
4. Async and multithreading will allow for concurrent access, and splitting of resource-intensive tasks across threads.
|
||||||
5. `hashbrown` is quite high-performance
|
5. `hashbrown` is quite high-performance
|
||||||
|
6. Batch processing increases throughput
|
||||||
|
|
||||||
|
### Buffering
|
||||||
|
The `kernel` will hold two read/write buffers in-memory and will queue reading & writing operations into them.
|
||||||
|
They can then be organized and batch processed, in order to optimize **HDD** speed (not having to move the head around), and **SSD** performance (minimizing operations).
|
||||||
|
|
||||||
|
|
||||||
## Filesystem Layout
|
## Filesystem Layout
|
||||||
|
|
||||||
|
@ -52,7 +59,7 @@ Small pieces that each partition is split into.
|
||||||
Contains fixed-length metadata (checksum, encryption flag, modification date, etc.) at the beginning, and then arbitrary data afterwards.
|
Contains fixed-length metadata (checksum, encryption flag, modification date, etc.) at the beginning, and then arbitrary data afterwards.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
const CHUNK_SIZE: u64 = 4096; // Example static chunk size
|
const CHUNK_SIZE: u64 = 4096; // Example static chunk size (in bytes)
|
||||||
|
|
||||||
struct ChunkHeader {
|
struct ChunkHeader {
|
||||||
checksum: u64,
|
checksum: u64,
|
||||||
|
@ -100,27 +107,24 @@ It's saved in the *Index Sector* (which is at a known offset & size), allowing i
|
||||||
It again simply uses `bincode` and compression.
|
It again simply uses `bincode` and compression.
|
||||||
|
|
||||||
While the index is not necessarily a fixed size, we read until we have enough data from the fixed sector size.
|
While the index is not necessarily a fixed size, we read until we have enough data from the fixed sector size.
|
||||||
|
The index is simly an `alloc::` [BTreeMap](https://doc.rust-lang.org/stable/alloc/collections/btree_map/struct.BTreeMap.html).
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use hashbrown::HashMap;
|
let mut index = BTreeMap::new();
|
||||||
|
|
||||||
let mut index = HashMap::new(); // Create the Uuid storage index
|
|
||||||
let mut free_index = HashMap::new(); // Create the freespace index
|
|
||||||
|
|
||||||
struct Location {
|
struct Location {
|
||||||
partition: Uuid, // Partition identified via Uuid
|
partition: Uuid, // Partition identified via Uuid
|
||||||
chunks: Vec<u64>, // Which chunk(s) in the partition it is
|
chunks: Vec<u64>, // Which chunk(s) in the partition it is
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_data = (Uuid::new(), b"data"); // Test data w/ an actor Uuid & bytes
|
|
||||||
let new_data_location = Location {
|
let new_data_location = Location {
|
||||||
partition: Uuid::new(),
|
partition: Uuid::new(),
|
||||||
chunks: vec![5, 8], // 5th & 8th chunk in that partition
|
chunks: vec![5, 8], // 5th & 8th chunk in that partition
|
||||||
};
|
}
|
||||||
|
|
||||||
index.insert(&new_data.0, &new_data_location); // Insert a new entry mapping a data Uuid to a location
|
index.insert(&actor.uuid, &new_data_location); // Insert an Actor's data & the location it's stored
|
||||||
|
index.contains_key(&actor.uuid); // Check if the index contains an Actor's data
|
||||||
let uuid_location = index.get(&new_data.0).unwrap(); // Get the location of a Uuid
|
index.get(&actor.uuid); // Get the Location of the actor
|
||||||
|
index.remove(&actor.uuid); // Remove an Actor's data from the index (e.g. on deletion)
|
||||||
```
|
```
|
||||||
|
|
||||||
This then allows the index to be searched easily to find the data location of a specific `Uuid`.
|
This then allows the index to be searched easily to find the data location of a specific `Uuid`.
|
||||||
|
@ -132,6 +136,7 @@ It also allows us to tell if an actor *hasn't* been saved yet, allowing us to kn
|
||||||
- Isolation
|
- Isolation
|
||||||
- Journaling
|
- Journaling
|
||||||
- Resizing
|
- Resizing
|
||||||
|
- Atomic Operations
|
||||||
|
|
||||||
## Executable Format
|
## Executable Format
|
||||||
Programs written in userspace will need to follow a specific format.
|
Programs written in userspace will need to follow a specific format.
|
||||||
|
|
Loading…
Reference in New Issue