Add punch hole GC
This PR together with https://github.com/tikv/titan/pull/323 implements Titan's new GC solution: Punch hole.
Titan has implemented 2 types of GC methods:
- GC based on stats (when discardable ratio of blob files reach certain threshold)
- GC during RocksDB's compactions (a.k.a level merge)
The first approach introduces write amplification, since it needs to update references inside RocksDB to reflect blobs' new location, and due to this reason, the threshold has to be relatively high to minimize this impact. The second approach has no extra write amplification, however, it may result in space waste. Imagine large portions of some blob files have been moved, but not yet meet the threshold to be entirely replaced.
Punch hole is a file system API, accepts a file descriptor, a start position and a length, removes the data from the file at the desired location. To application, this part of the file is set to 0. To file system, if some the underlying storage blocks are fully covered by the removed part, file system can reclaim those space.
This project try to utilize the punch hole API, in-place delete blobs during GC, to avoid updating references inside RocksDB