beyond-all-reason / beyond-all-reason/RecoilEngine
Investigate alternative Rapid on-disk storage format
- Dominant language
- C++
- Stars
- 679
- Forks
- 290
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 40
Description
#### Problem
[Rapid format](https://springrts.com/wiki/Rapid) is serving us relatively well because it provides good incremental updates support.
The major disadvantage of the current Rapid *on-disk* storage format is that it's rather slow for the game load performance:
1. All files are compressed using gzip
Currently in BAR the load cost because of gzip is ~2s on my tests from some time ago: https://discord.com/channels/549281623154229250/724924957074915358/1132367444837683240
2. Every single archive file is stored on disc separately
BAR has over 10000 files. There is high overhead because of all the syscalls and it's especially terrible on Windows. BAR has workarounds that open and close all pool files in lobby to reduce the load times by prewarming OS caches and triggering Antivirus on-open scans.
This issue is to investigate more performant solutions that still offer good support for incremental updates.
#### Compression
For the compression: zstd and l4 are great options. zstd has the compression ratios very similar to gzip, but a _much_ faster decompression. lz4 decompression is in order of GB/s so it's close to transparent, and it makes it more feasible for software like pr-downloader to re-compress objects on the fly while downloading, without changing the content distribution format.
#### Many small files
For the many small files issue, we can investigate using an embeded key-value store databases like LevelDB, RocksDB, and LMDB. By storing the files in the embedded database, they can provide optimized storage access, and fully incremental changes just like we offer at the moment.
[LMDB](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database) focuses on the read performance, supports out of the box concurrent access from multiple independent processes (pretty rare for embedded databases, and is important for the existing API usage and engine <-> pr-downloader interaction), has great platform support, small code base, and [modern C++ bindings](https://github.com/hoytech/lmdbxx/) if we want.
The main unknowns in this approach are:
- Storage size overhead.
- Whatever performance will be good for the both small and large files.
Storing large files separately in the filesystem is an option, but it adds implementation complexity
Contributor guide
Research direction
No implementation file, test, or entry point is named. Start by locating the current Rapid on-disk storage path and reviewing how the engine and pr-downloader access pool files. Compare gzip with zstd or lz4 and evaluate LevelDB, RocksDB, and LMDB for small and large files, incremental updates, storage overhead, and concurrent access; done means a documented recommendation supported by measurements.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- databases, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100