Add a swap function.

This commit is contained in:
Davi de Castro Reis 2016-02-24 14:01:18 -05:00
parent 69f81ca7ba
commit 776ae2cbca
3 changed files with 48 additions and 20 deletions

View File

@ -43,10 +43,10 @@ MPHIndex::~MPHIndex() {
} }
void MPHIndex::clear() { void MPHIndex::clear() {
delete [] ranktable_; std::vector<uint32_t> empty_ranktable;
ranktable_ = NULL; ranktable_.swap(empty_ranktable);
ranktable_size_ = 0; dynamic_2bitset empty_g;
// TODO(davi) implement me g_.swap(empty_g);
} }
bool MPHIndex::GenerateQueue( bool MPHIndex::GenerateQueue(
@ -159,17 +159,14 @@ void MPHIndex::Assigning(
void MPHIndex::Ranking() { void MPHIndex::Ranking() {
uint32_t nbytes_total = static_cast<uint32_t>(ceil(n_ / 4.0)); uint32_t nbytes_total = static_cast<uint32_t>(ceil(n_ / 4.0));
uint32_t size = k_ >> 2U; uint32_t size = k_ >> 2U;
ranktable_size_ = static_cast<uint32_t>( uint32_t ranktable_size = static_cast<uint32_t>(
ceil(n_ / static_cast<double>(k_))); ceil(n_ / static_cast<double>(k_)));
delete [] ranktable_; vector<uint32_t> ranktable(ranktable_size);
ranktable_ = NULL;
uint32_t* ranktable = new uint32_t[ranktable_size_];
memset(ranktable, 0, ranktable_size_*sizeof(uint32_t));
uint32_t offset = 0; uint32_t offset = 0;
uint32_t count = 0; uint32_t count = 0;
uint32_t i = 1; uint32_t i = 1;
while (1) { while (1) {
if (i == ranktable_size_) break; if (i == ranktable.size()) break;
uint32_t nbytes = size < nbytes_total ? size : nbytes_total; uint32_t nbytes = size < nbytes_total ? size : nbytes_total;
for (uint32_t j = 0; j < nbytes; ++j) { for (uint32_t j = 0; j < nbytes; ++j) {
count += kBdzLookupIndex[g_.data()[offset + j]]; count += kBdzLookupIndex[g_.data()[offset + j]];
@ -179,11 +176,11 @@ void MPHIndex::Ranking() {
nbytes_total -= size; nbytes_total -= size;
++i; ++i;
} }
ranktable_ = ranktable; ranktable_.swap(ranktable);
} }
uint32_t MPHIndex::Rank(uint32_t vertex) const { uint32_t MPHIndex::Rank(uint32_t vertex) const {
if (!ranktable_size_) return 0; if (ranktable_.empty()) return 0;
uint32_t index = vertex >> b_; uint32_t index = vertex >> b_;
uint32_t base_rank = ranktable_[index]; uint32_t base_rank = ranktable_[index];
uint32_t beg_idx_v = index << b_; uint32_t beg_idx_v = index << b_;
@ -211,4 +208,22 @@ uint32_t MPHIndex::Rank(uint32_t vertex) const {
return base_rank; return base_rank;
} }
void MPHIndex::swap(std::vector<uint32_t>& params, dynamic_2bitset& g, std::vector<uint32_t>& ranktable) {
params.resize(12);
uint32_t rounded_c = c_ * 1000 * 1000;
std::swap(params[0], rounded_c);
c_ = static_cast<double>(rounded_c) / 1000 / 1000;
std::swap(params[1], m_);
std::swap(params[2], n_);
std::swap(params[3], k_);
uint32_t uint32_square = static_cast<uint32_t>(square_);
std::swap(params[4], uint32_square);
square_ = uint32_square;
std::swap(params[5], hash_seed_[0]);
std::swap(params[6], hash_seed_[1]);
std::swap(params[7], hash_seed_[2]);
g.swap(g_);
ranktable.swap(ranktable_);
}
} // namespace cxxmph } // namespace cxxmph

View File

@ -45,8 +45,7 @@ namespace cxxmph {
class MPHIndex { class MPHIndex {
public: public:
MPHIndex(bool square = false, double c = 1.23, uint8_t b = 7) : MPHIndex(bool square = false, double c = 1.23, uint8_t b = 7) :
c_(c), b_(b), m_(0), n_(0), k_(0), square_(square), r_(1), g_(8, true), c_(c), b_(b), m_(0), n_(0), k_(0), square_(square), r_(1), g_(8, true) {
ranktable_(NULL), ranktable_size_(0) {
nest_displacement_[0] = 0; nest_displacement_[0] = 0;
nest_displacement_[1] = r_; nest_displacement_[1] = r_;
nest_displacement_[2] = (r_ << 1); nest_displacement_[2] = (r_ << 1);
@ -72,6 +71,11 @@ class MPHIndex {
template <class SeededHashFcn, class Key> // must agree with Reset template <class SeededHashFcn, class Key> // must agree with Reset
uint32_t minimal_perfect_hash(const Key& x) const; uint32_t minimal_perfect_hash(const Key& x) const;
// Experimental api to use as a serialization building block.
// Since this signature exposes some implementation details, expect it to
// change.
void swap(std::vector<uint32_t>& params, dynamic_2bitset& g, std::vector<uint32_t>& ranktable);
private: private:
template <class SeededHashFcn, class ForwardIterator> template <class SeededHashFcn, class ForwardIterator>
bool Mapping(ForwardIterator begin, ForwardIterator end, bool Mapping(ForwardIterator begin, ForwardIterator end,
@ -107,8 +111,7 @@ class MPHIndex {
dynamic_2bitset g_; dynamic_2bitset g_;
uint8_t threebit_mod3[10]; // speed up mod3 calculation for 3bit ints uint8_t threebit_mod3[10]; // speed up mod3 calculation for 3bit ints
// The table used for the rank step of the minimal perfect hash function // The table used for the rank step of the minimal perfect hash function
const uint32_t* ranktable_; std::vector<uint32_t> ranktable_;
uint32_t ranktable_size_;
// The selected hash seed triplet for finding the edges in the minimal // The selected hash seed triplet for finding the edges in the minimal
// perfect hash function graph. // perfect hash function graph.
uint32_t hash_seed_[3]; uint32_t hash_seed_[3];
@ -142,7 +145,7 @@ bool MPHIndex::Reset(
std::vector<TriGraph::Edge> edges; std::vector<TriGraph::Edge> edges;
std::vector<uint32_t> queue; std::vector<uint32_t> queue;
while (1) { while (1) {
// cerr << "Iterations missing: " << iterations << endl; cerr << "Iterations missing: " << iterations << endl;
for (int i = 0; i < 3; ++i) hash_seed_[i] = random(); for (int i = 0; i < 3; ++i) hash_seed_[i] = random();
if (Mapping<SeededHashFcn>(begin, end, &edges, &queue)) break; if (Mapping<SeededHashFcn>(begin, end, &edges, &queue)) break;
else --iterations; else --iterations;

View File

@ -34,6 +34,16 @@ int main(int argc, char** argv) {
sort(ids.begin(), ids.end()); sort(ids.begin(), ids.end());
for (vector<int>::size_type i = 0; i < ids.size(); ++i) assert(ids[i] == static_cast<vector<int>::value_type>(i)); for (vector<int>::size_type i = 0; i < ids.size(); ++i) assert(ids[i] == static_cast<vector<int>::value_type>(i));
// Test serialization
vector<uint32_t> params;
dynamic_2bitset g;
vector<uint32_t> ranktable;
mph_index.swap(params, g, ranktable);
assert(mph_index.size() == 0);
mph_index.swap(params, g, ranktable);
assert(mph_index.size() == ids.size());
for (vector<int>::size_type i = 0; i < ids.size(); ++i) assert(ids[i] == static_cast<vector<int>::value_type>(i));
FlexibleMPHIndex<false, true, int64_t, seeded_hash<std::hash<int64_t>>::hash_function> square_empty; FlexibleMPHIndex<false, true, int64_t, seeded_hash<std::hash<int64_t>>::hash_function> square_empty;
auto id = square_empty.index(1); auto id = square_empty.index(1);
FlexibleMPHIndex<false, false, int64_t, seeded_hash<std::hash<int64_t>>::hash_function> unordered_empty; FlexibleMPHIndex<false, false, int64_t, seeded_hash<std::hash<int64_t>>::hash_function> unordered_empty;