Packages
rocksdb
0.23.0
3.1.1
3.1.0
3.0.0
2.6.2
2.6.1
retired
2.6.0
retired
2.5.0
2.4.1
2.4.0
2.3.0
2.2.0
2.1.0
2.0.0
1.9.0
1.8.0
1.7.0
1.6.0
1.5.1
1.5.0
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.1
1.1.0
1.0.0
0.26.2
0.26.1
0.26.0
0.25.0
0.24.0
0.23.3
0.23.2
0.23.1
0.23.0
0.22.0
0.21.0
0.20.1
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
RocksDB for Erlang
Current section
Files
Jump to
Current section
Files
c_src/bitset_merge_operator.cc
// Copyright (c) 2018 Benoit Chesneau
//
// This file is provided to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <iostream>
#include <string>
#include <memory>
#include <list>
#include <algorithm>
#include <assert.h>
#include "rocksdb/slice.h"
#include "rocksdb/merge_operator.h"
#include "erl_nif.h"
#include "util.h"
#include "bitset_merge_operator.h"
static const std::size_t bits_per_char = 0x08; // 8 bits in 1 char(unsigned)
static const unsigned char bit_mask[bits_per_char] = {
0x80, //10000000
0x40, //01000000
0x20, //00100000
0x10, //00010000
0x08, //00001000
0x04, //00000100
0x02, //00000010
0x01 //00000001
};
namespace erocksdb {
BitsetMergeOperator::BitsetMergeOperator(unsigned int cap)
:cap_(cap) {
};
bool BitsetMergeOperator::Merge(
const rocksdb::Slice& key,
const rocksdb::Slice* existing_value,
const rocksdb::Slice& value,
std::string* new_value,
rocksdb::Logger* logger) const {
size_t size;
char* data = nullptr;
if (existing_value == nullptr) {
size = cap_ / bits_per_char;
new_value->reserve(size);
data = new cell_type[size];
std::fill_n(data, size, 0x00);
} else {
data = (char *)existing_value->data();
size = existing_value->size();
}
std::string s = value.ToString();
if (s.size() < 1) {
delete[] data;
return false;
}
int pos;
try {
pos = std::stoi(s.substr(1));
} catch(...) {
delete[] data;
return false;
}
int ofs = pos >> 3;
if (ofs > size) {
delete[] data;
return false;
}
//char bytemask = (1 << ((1 << 3)) - (pos & ((1 << 3)))));
if (value.starts_with(rocksdb::Slice("+"))) {
//data[(pos >> 3)] |= bytemask;
data[ofs] |= bit_mask[pos % bits_per_char];
} else if (value.starts_with(rocksdb::Slice("-"))) {
//data[(pos >> 3)] &= ~bytemask;
data[ofs] &= ~bit_mask[pos % bits_per_char];
} else {
delete[] data;
return false;
}
new_value->clear();
new_value->assign(data,size);
return true;
}
const char* BitsetMergeOperator::Name() const {
return "BitsetMergeOperator";
}
std::shared_ptr<BitsetMergeOperator> CreateBitsetMergeOperator(unsigned int cap) {
return std::make_shared<BitsetMergeOperator>(cap);
}
}