Skip to content

API Reference

C API (aqf.h)

#include "aqf.h"

Lifecycle

bool aqf_malloc(QF *qf, uint64_t nslots, uint64_t key_bits,
                uint64_t value_bits, enum qf_hashmode hash, uint32_t seed);
void aqf_free(QF *qf);

Core operations

int aqf_insert(QF *qf, uint64_t key, uint64_t count,
               qf_insert_result *result, uint8_t flags);

Inserts key (or increments its count). result returns the minirun ID and rank used by the reverse map. Returns 0 on success and a negative value on error.

int aqf_bulk_insert(QF *qf, uint64_t *keys, uint64_t numKeys, uint8_t flags);

Inserts an array of keys using the configured hash mode. This low-level helper does not perform reverse-map insertion; applications using the C API must keep the filter and reverse map synchronized themselves.

int aqf_query(const QF *qf, uint64_t key, uint64_t *ret_hash,
              uint8_t *ret_minirun_rank, uint8_t flags);

Returns the count if found, or 0 if not found. A positive result may still be a false positive. ret_hash and ret_minirun_rank identify the matching fingerprint and rank for callers that need to adapt the filter.

int aqf_adapt(QF *qf, uint64_t orig_key, uint64_t fp_key,
              uint64_t minirun_rank, uint8_t flags);

Extends the fingerprint of orig_key so fp_key is no longer a false positive. The C layer does not perform the reverse-map lookup. The application must use the fingerprint and rank from the query result to retrieve orig_key from its reverse map, then pass both keys and the rank to aqf_adapt.

Returns 1 when an extension is made, 0 when no extension is made, and a negative value on failure, such as when the filter has no space.

Metadata

uint64_t aqf_get_noccupied_slots(const QF *qf);
uint64_t aqf_get_nslots(const QF *qf);
uint64_t aqf_get_total_size_in_bytes(const QF *qf);
void     aqf_dump_metadata(const QF *qf);
void     aqf_dump(const QF *qf);

Flags

Flag Value Meaning
QF_NO_LOCK 0x01 Skip locking (caller must synchronize)
QF_TRY_ONCE_LOCK 0x02 Return an error if the lock is unavailable immediately
QF_WAIT_FOR_LOCK 0x04 Wait until the lock is available
QF_KEY_IS_HASH 0x08 key is already a hash (skip hashing)

Hash modes

Mode Description
QF_HASH_DEFAULT MurmurHash64A
QF_HASH_INVERTIBLE Invertible hash
QF_HASH_NONE Caller input is treated as a precomputed hash; skewed inputs can cause poor performance

C++ Wrapper (aqf_wrapper.hpp)

#include "aqf_wrapper.hpp"

Templated on a reverse map implementation.

template <typename ReverseMap>
class AdaptiveQF {
public:
  int init(QFilterConfig cfg);
  int initializeForCapacity(uint64_t numExpectedElements, size_t rbits,
                            double max_load_factor, int hash_mode,
                            ReverseMapConfig reverse_map = {});
  int initializeWithQBits(size_t qbits, size_t rbits,
                          double max_load_factor, int hash_mode,
                          ReverseMapConfig reverse_map = {});
  int bulkInsert(uint64_t *keys, uint64_t numKeys);
  int queryFilter(uint64_t key, QFilterQueryResult *result);
  int adapt(uint64_t key, QFilterQueryResult *result);
  int adaptOnce(uint64_t key, QFilterQueryResult *result);
  int close();

  // Accessors
  double loadFactor();
  uint64_t sizeInBytes();
  void dumpMetadata();
  void dump();
  QF *getQF();
  ReverseMap *getReverseMap();
};

init takes a fully-specified QFilterConfig, where qbits is the log2 of the number of slots. initializeForCapacity derives qbits from the expected number of elements and the max load factor; initializeWithQBits sets the number of slots directly to 1 << qbits. Both construct the filter so callers do not need to manage the config struct manually.

adapt corrects the false positive for key and returns 0 on success or a negative value on failure. adaptOnce performs a single extension and exposes the lower-level operation result. Both take a QFilterQueryResult (e.g. from queryFilter) describing the current false positive.

bulkInsert inserts each key into the filter and then populates the reverse map. queryFilter returns 0 and writes the query result to QFilterQueryResult. The caller must determine whether a positive result is actually a false positive; the filter does not know the complete original key set. adaptOnce returns a positive value when it extends a fingerprint, 0 when no extension is made, and a negative value on failure. close releases the filter and reverse-map resources.

Unlike the C API, the C++ wrapper performs the reverse-map lookup inside adaptOnce before calling the underlying C adaptation function.

For a negative query, callers should use key_present and should not rely on count being initialized by the current implementation.

QFilterConfig

struct QFilterConfig {
  size_t qbits;            // log2 of number of slots
  size_t rbits;            // remainder bits
  double max_load_factor;  // adapt returns -1 when exceeded
  int hash_mode;           // QF_HASH_DEFAULT, _INVERTIBLE, or _NONE
  ReverseMapConfig reverse_map;
};

ReverseMapConfig

struct ReverseMapConfig {
  std::string storage_path;       // file path for persistent stores
  uint64_t cache_size_bytes;      // memory budget for caching
  bool overwrite;                 // delete existing data on init
};

The current wrapper does not propagate every reverse-map failure. In particular, init does not check the return value of ReverseMap::init, and ReverseMap::bulkInsert returns void, so its individual insertion failures cannot be reported through AdaptiveQF::bulkInsert.


Reverse Maps

The ReverseMap template parameter must implement:

struct ReverseMap {
  int  init(ReverseMapConfig config, int base_fingerprint_bits);
  int  insert(uint64_t fingerprint, uint64_t rank, uint64_t key);
  void bulkInsert(uint64_t *keys, uint64_t *fingerprints,
                  uint64_t *ranks, uint64_t numKeys);
  int  getFingerprint(uint64_t fingerprint, int rank, uint64_t *value);
  int  close();
};
Implementation File Storage Persistence
LocalMap reverse_maps/localmap/localmap_db.hpp std::unordered_map None (volatile)
SplinterDB reverse_maps/splinterdb/splinter_reverse_map.hpp SplinterDB Disk-backed