https://github.com/splatlab/squeakr
Revision a4d4b0ebc64eec5f6862ddbff48ff1de891098ee authored by Prashant Pandey on 06 November 2018, 17:45:37 UTC, committed by Prashant Pandey on 06 November 2018, 17:45:37 UTC
Tip revision: a4d4b0ebc64eec5f6862ddbff48ff1de891098ee authored by Prashant Pandey on 06 November 2018, 17:45:37 UTC
merge
merge
Tip revision: a4d4b0e
gqf_cpp.h
/*
* ============================================================================
*
* Authors: Prashant Pandey <ppandey@cs.stonybrook.edu>
* Rob Johnson <robj@vmware.com>
* Rob Patro (rob.patro@cs.stonybrook.edu)
*
* ============================================================================
*/
#ifndef _CQF_H_
#define _CQF_H_
#include <iostream>
#include <cassert>
#include <unordered_set>
#include <inttypes.h>
#include <string.h>
#include <math.h>
#include <sys/mman.h>
#include "gqf/gqf.h"
#include "gqf/gqf_int.h"
#include "gqf/gqf_file.h"
#include "util.h"
#define NUM_HASH_BITS 24
#define NUM_Q_BITS 16
#define SEED 2038074761
enum readmode {
MMAP,
FREAD
};
template <class key_obj>
class CQF {
public:
CQF();
CQF(uint64_t q_bits, uint64_t key_bits, enum qf_hashmode hash, uint32_t seed);
CQF(std::string& filename, enum readmode flag);
CQF(const CQF<key_obj>& copy_cqf);
int insert(const key_obj& k, uint8_t flags);
/* Will return the count. */
uint64_t query(const key_obj& k, uint8_t flags);
uint64_t inner_prod(const CQF<key_obj>& in_cqf);
void serialize(std::string filename) {
qf_serialize(&cqf, filename.c_str());
}
void set_auto_resize(void) { qf_set_auto_resize(&cqf, true); }
int64_t get_unique_index(const key_obj& k, uint8_t flags) const {
return qf_get_unique_index(&cqf, k.key, k.value, flags);
}
bool is_exact(void);
const QF* get_cqf(void) const { return &cqf; }
__uint128_t range(void) const { return cqf.metadata->range; }
uint32_t seed(void) const { return cqf.metadata->seed; }
uint64_t numslots(void) const { return cqf.metadata->nslots; }
uint32_t keybits(void) const { return cqf.metadata->key_bits; }
uint64_t total_elts(void) const { return cqf.metadata->nelts; }
uint64_t dist_elts(void) const { return cqf.metadata->ndistinct_elts; }
//uint64_t set_size(void) const { return set.size(); }
void reset(void) { qf_reset(&cqf); }
void dump_metadata(void) const { qf_dump_metadata(&cqf); }
void drop_pages(uint64_t cur);
class Iterator {
public:
Iterator(QFi it);
key_obj operator*(void) const;
void operator++(void);
bool done(void) const;
key_obj get_cur_hash(void) const;
QFi iter;
private:
uint64_t end_hash;
};
Iterator begin(void) const;
Iterator end(void) const;
private:
QF cqf;
//std::unordered_set<uint64_t> set;
};
class KeyObject {
public:
KeyObject() : key(0), value(0), count(0) {};
KeyObject(uint64_t k, uint64_t v, uint64_t c) : key(k),
value(v), count(c) {};
KeyObject(const KeyObject& k) : key(k.key), value(k.value), count(k.count) {};
bool operator==(KeyObject k) { return key == k.key; }
uint64_t key;
uint64_t value;
uint64_t count;
};
template <class key_obj>
CQF<key_obj>::CQF() {
if (!qf_malloc(&cqf, 1ULL << NUM_Q_BITS, NUM_HASH_BITS, 0, QF_HASH_DEFAULT,
SEED)) {
ERROR("Can't allocate the CQF");
exit(EXIT_FAILURE);
}
}
template <class key_obj>
CQF<key_obj>::CQF(uint64_t q_bits, uint64_t key_bits, enum qf_hashmode hash,
uint32_t seed) {
if (!qf_malloc(&cqf, 1ULL << q_bits, key_bits, 0, hash, SEED)) {
ERROR("Can't allocate the CQF");
exit(EXIT_FAILURE);
}
}
template <class key_obj>
CQF<key_obj>::CQF(std::string& filename, enum readmode flag) {
uint64_t size = 0;
if (flag == MMAP)
size = qf_usefile(&cqf, filename.c_str(), PROT_READ);
else
size = qf_deserialize(&cqf, filename.c_str());
if (size == 0) {
ERROR("Can't read/deserialize the CQF");
exit(EXIT_FAILURE);
}
}
template <class key_obj> CQF<key_obj>::CQF(const CQF<key_obj>& copy_cqf) {
memcpy(reinterpret_cast<void*>(&cqf),
reinterpret_cast<void*>(const_cast<QF*>(©_cqf.cqf)), sizeof(QF));
}
template <class key_obj>
int CQF<key_obj>::insert(const key_obj& k, uint8_t flags) {
return qf_insert(&cqf, k.key, k.value, k.count, flags);
// To validate the CQF
//set.insert(k.key);
}
template <class key_obj>
uint64_t CQF<key_obj>::query(const key_obj& k, uint8_t flags) {
return qf_count_key_value(&cqf, k.key, k.value, flags);
}
template <class key_obj>
uint64_t CQF<key_obj>::inner_prod(const CQF<key_obj>& in_cqf) {
return qf_inner_product(&cqf, in_cqf.get_cqf());
}
template <class key_obj>
bool CQF<key_obj>::is_exact(void) {
if (cqf.metadata->hash_mode == QF_HASH_INVERTIBLE)
return true;
return false;
}
template <class key_obj>
CQF<key_obj>::Iterator::Iterator(QFi it)
: iter(it) {};
template <class key_obj>
key_obj CQF<key_obj>::Iterator::operator*(void) const {
uint64_t key = 0, value = 0, count = 0;
qfi_get_key(&iter, &key, &value, &count);
return key_obj(key, value, count);
}
template <class key_obj>
key_obj CQF<key_obj>::Iterator::get_cur_hash(void) const {
uint64_t key = 0, value = 0, count = 0;
qfi_get_hash(&iter, &key, &value, &count);
return key_obj(key, value, count);
}
template<class key_obj>
void CQF<key_obj>::Iterator::operator++(void) {
qfi_next(&iter);
}
/* Currently, the iterator only traverses forward. So, we only need to check
* the right side limit.
*/
template<class key_obj>
bool CQF<key_obj>::Iterator::done(void) const {
return qfi_end(&iter);
}
template<class key_obj>
typename CQF<key_obj>::Iterator CQF<key_obj>::begin(void) const {
QFi qfi;
qf_iterator_from_position(&this->cqf, &qfi, 0);
return Iterator(qfi);
}
template<class key_obj>
typename CQF<key_obj>::Iterator CQF<key_obj>::end(void) const {
QFi qfi;
qf_iterator_from_position(&this->cqf, &qfi, 0xffffffffffffffff);
return Iterator(qfi, UINT64_MAX);
}
#endif
Computing file changes ...