|
1 | 1 | use crate::common::{ |
2 | | - Engine, PREFIX_SIZE, Pre, PreBytes, RESERVED_ID_CNT, RawKey, RawValue, |
| 2 | + Engine, GB, PREFIX_SIZE, Pre, PreBytes, RESERVED_ID_CNT, RawKey, RawValue, |
3 | 3 | vsdb_get_base_dir, vsdb_set_base_dir, |
4 | 4 | }; |
5 | 5 | use fjall::{CompressionType, Config, Keyspace, Partition, PartitionCreateOptions}; |
@@ -68,9 +68,42 @@ impl Engine for FjallEngine { |
68 | 68 | // Ensure base dir exists |
69 | 69 | fs::create_dir_all(&base_dir).c(d!())?; |
70 | 70 |
|
| 71 | + let total_mem_budget = if cfg!(target_os = "linux") { |
| 72 | + let memsiz = fs::read_to_string("/proc/meminfo") |
| 73 | + .c(d!())? |
| 74 | + .lines() |
| 75 | + .find(|l| l.contains("MemAvailable")) |
| 76 | + .c(d!())? |
| 77 | + .replace(|ch: char| !ch.is_numeric(), "") |
| 78 | + .parse::<u64>() |
| 79 | + .c(d!())? |
| 80 | + * 1024; |
| 81 | + alt!((16 * GB) < memsiz, memsiz / 4, GB) |
| 82 | + } else { |
| 83 | + GB |
| 84 | + }; |
| 85 | + |
| 86 | + // NOTE: |
| 87 | + // The current `get_shard_idx` implementation uses the most significant byte (MSB) |
| 88 | + // of the Big-Endian prefix. Since `alloc_prefix` increments a counter sequentially |
| 89 | + // starting from a small number, the MSB will remain 0 for practically forever |
| 90 | + // (until 2^56 collections are created). |
| 91 | + // This means effectively ONLY Shard 0 is used. |
| 92 | + // If we divide memory by SHARD_CNT (16), we starve the only active shard. |
| 93 | + // Therefore, we oversubscribe memory significantly, assuming that in practice |
| 94 | + // only a few shards (likely just one) will ever be active. |
| 95 | + // We set the budget per shard to half of the total available budget. |
| 96 | + let per_shard_budget = total_mem_budget / 2; |
| 97 | + let write_buffer_size = per_shard_budget / 4; |
| 98 | + let cache_size = per_shard_budget - write_buffer_size; |
| 99 | + |
71 | 100 | for i in 0..SHARD_CNT { |
72 | 101 | let dir = base_dir.join(format!("shard_{}", i)); |
73 | | - let ks = Config::new(dir).open().c(d!())?; |
| 102 | + let ks = Config::new(dir) |
| 103 | + .max_write_buffer_size(write_buffer_size) |
| 104 | + .cache_size(cache_size) |
| 105 | + .open() |
| 106 | + .c(d!())?; |
74 | 107 |
|
75 | 108 | let mut parts = Vec::with_capacity(DATA_SET_NUM); |
76 | 109 | for j in 0..DATA_SET_NUM { |
|
0 commit comments