17 #ifndef JUBATUS_CORE_STORAGE_BIT_VECTOR_HPP_
18 #define JUBATUS_CORE_STORAGE_BIT_VECTOR_HPP_
25 #include <msgpack.hpp>
26 #include "jubatus/util/lang/cast.h"
27 #include "../common/assert.hpp"
28 #include "../common/exception.hpp"
29 #include "../common/big_endian.hpp"
41 bits = (bits & 0x55) + (bits >> 1 & 0x55);
42 bits = (bits & 0x33) + (bits >> 2 & 0x33);
43 return (bits & 0x0f) + (bits >> 4 & 0x0f);
49 bits = (bits & 0x5555U) + (bits >> 1 & 0x5555U);
50 bits = (bits & 0x3333U) + (bits >> 2 & 0x3333U);
51 bits = (bits & 0x0f0fU) + (bits >> 4 & 0x0f0fU);
52 return (bits & 0x00ffU) + (bits >> 8 & 0x00ffU);
58 bits = (bits & 0x55555555LU) + (bits >> 1 & 0x55555555LU);
59 bits = (bits & 0x33333333LU) + (bits >> 2 & 0x33333333LU);
60 bits = (bits & 0x0f0f0f0fLU) + (bits >> 4 & 0x0f0f0f0fLU);
61 bits = (bits & 0x00ff00ffLU) + (bits >> 8 & 0x00ff00ffLU);
62 return (bits & 0x0000ffffLU) + (bits >>16 & 0x0000ffffLU);
68 bits = (bits & 0x5555555555555555LLU) + (bits >> 1 & 0x5555555555555555LLU);
69 bits = (bits & 0x3333333333333333LLU) + (bits >> 2 & 0x3333333333333333LLU);
70 bits = (bits & 0x0f0f0f0f0f0f0f0fLLU) + (bits >> 4 & 0x0f0f0f0f0f0f0f0fLLU);
71 bits = (bits & 0x00ff00ff00ff00ffLLU) + (bits >> 8 & 0x00ff00ff00ff00ffLLU);
72 bits = (bits & 0x0000ffff0000ffffLLU) + (bits >>16 & 0x0000ffff0000ffffLLU);
73 return (bits & 0x00000000ffffffffLLU) + (bits >>32 & 0x00000000ffffffffLLU);
79 inline int fast_bitcount(
unsigned bits) {
80 return __builtin_popcount(bits);
83 inline int fast_bitcount(
unsigned long bits) {
84 return __builtin_popcountl(bits);
87 inline int fast_bitcount(
unsigned long long bits) {
88 return __builtin_popcountll(bits);
96 return fast_bitcount(bits);
125 const char*
what()
const throw() {
133 template <
typename bit_base>
160 if (orig.
bits_ == NULL) {
206 if (orig.
bits_ == NULL) {
235 if (static_cast<size_t>(
bit_num_) < pos) {
237 "set_bit(): invalid posison " +
238 jubatus::util::lang::lexical_cast<std::string>(pos) +
240 jubatus::util::lang::lexical_cast<std::string>(
bit_num_));
250 "reverse_bit(): invalid posison " +
251 jubatus::util::lang::lexical_cast<std::string>(pos) +
253 jubatus::util::lang::lexical_cast<std::string>(
bit_num_));
269 for (
size_t i = 0; i <
bit_num_; ++i) {
279 "calc_hamming_similarity(): bit_vector length unmatch! " +
280 jubatus::util::lang::lexical_cast<std::string>(
bit_num()) +
" with " +
281 jubatus::util::lang::lexical_cast<std::string>(bv.
bit_num()));
290 size_t match_num = 0;
291 for (
size_t i = 0; i <
used_bytes() /
sizeof(bit_base); ++i) {
301 for (int64_t i = (
used_bytes() /
sizeof(bit_base)) - 1; i >= 0; --i) {
320 return ((((bit_width + 7) / 8) + BLOCKSIZE - 1) / BLOCKSIZE) *
BLOCKSIZE;
325 os <<
"(unallocated)";
328 for (uint64_t i = 0; i <
used_bytes() * 8; ++i) {
329 if ((
bits_[i / (
sizeof(bit_base) * 8)] >> (i % (
sizeof(bit_base) * 8))) &
344 os <<
"(unallocated)" <<
" owns_" <<
own_;
347 os << (
own_ ?
"[own]" :
"[other]") << std::endl;
350 template <
typename packable>
351 void pack(packable& buffer)
const {
352 msgpack::pack(buffer, *
this);
354 template<
typename Buffer>
356 packer.pack_array(2);
357 packer.pack(static_cast<uint64_t>(
bit_num_));
361 for (
size_t i = 0; i < n; ++i) {
364 packer.pack_raw_body(buf, BLOCKSIZE);
369 packer.pack_raw_body(&c, 1);
374 if (o.type != msgpack::type::ARRAY || o.via.array.size != 2) {
375 throw msgpack::type_error();
377 const msgpack::object*
objs = o.via.array.ptr;
378 const uint64_t
bit_num = objs[0].as<uint64_t>();
379 const msgpack::type::raw_ref data = objs[1].as<msgpack::type::raw_ref>();
382 "msgpack_unpack(): invalid length of packed data: "
384 jubatus::util::lang::lexical_cast<std::string>(
bit_num_) +
386 jubatus::util::lang::lexical_cast<std::string>(data.size));
388 std::vector<bit_base> buf;
389 for (
size_t i = 0; i < data.size; i +=
BLOCKSIZE) {
390 buf.push_back(common::read_big_endian<bit_base>(&data.ptr[i]));
418 "failed copy bit vector from " +
419 jubatus::util::lang::lexical_cast<std::string>(orig.
bit_num_) +
421 jubatus::util::lang::lexical_cast<std::string>(
bit_num_));
439 #endif // JUBATUS_CORE_STORAGE_BIT_VECTOR_HPP_
void debug_print(std::ostream &os) const
uint64_t calc_hamming_distance(const bit_vector_base &bv) const
void clear_bit(size_t pos)
static const size_t BASE_BITS
~bit_vector_unmatch_exception()
static size_t memory_size(size_t bit_width)
void resize_and_clear(uint64_t bit_num)
bool operator==(const bit_vector_base &rhs) const
const char * what() const
friend std::ostream & operator<<(std::ostream &os, const bit_vector_base &bv)
void reverse_bit(size_t pos)
bit_vector_unmatch_exception(const std::string &msg)
bit_vector_base(const bit_vector_base &orig)
void pack(packable &buffer) const
bit_base * raw_data_unsafe()
#define JUBATUS_ASSERT(expr)
void write_big_endian(uint32_t x, char *buf)
void status(std::ostream &os) const
void msgpack_pack(msgpack::packer< Buffer > &packer) const
int bitcount(unsigned bits)
void swap(weighted_point &p1, weighted_point &p2)
bool operator!=(const bit_vector_base &rhs) const
void duplicate(const bit_vector_base &orig)
int bitcount_dispatcher(T bits)
msgpack::packer< jubatus_packer > packer
bit_vector_base< uint64_t > bit_vector
bit_vector_base(int bit_num)
vector< msgpack::object > objs
bit_vector_base(const bit_base *bits, size_t bit_num)
void msgpack_unpack(msgpack::object o)
bool get_bit(size_t pos) const
bit_vector_base & operator=(const bit_vector_base &orig)
uint64_t calc_hamming_similarity(const bit_vector_base &bv) const
size_t used_bytes() const
void swap(bit_vector_base &x)
friend void swap(bit_vector_base &l, bit_vector_base &r)
static const size_t BLOCKSIZE
const bit_base * raw_data_unsafe() const