fork of https://github.com/oxigraph/rocksdb and https://github.com/facebook/rocksdb for nextgraph and oxigraph
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
2.6 KiB
111 lines
2.6 KiB
13 years ago
|
/**
|
||
|
* Copyright 2012 Facebook
|
||
|
* @author Tudor Bosman (tudorb@fb.com)
|
||
|
*/
|
||
|
|
||
|
#ifndef THRIFT_LIB_CPP_PROTOCOL_NEUTRONIUM_UTILS_H_
|
||
|
#define THRIFT_LIB_CPP_PROTOCOL_NEUTRONIUM_UTILS_H_
|
||
|
|
||
|
#include <cstddef>
|
||
|
#include <cstdint>
|
||
|
#include <cassert>
|
||
|
#include <algorithm>
|
||
|
|
||
|
namespace apache {
|
||
|
namespace thrift {
|
||
|
namespace protocol {
|
||
|
namespace neutronium {
|
||
|
|
||
|
// Helper functions for using an array of uint8_t values as a bitset
|
||
|
|
||
|
// byte index
|
||
|
constexpr inline size_t byteIndex(size_t bit) {
|
||
|
return bit / 8;
|
||
|
}
|
||
|
|
||
|
// offset within byte
|
||
|
constexpr inline size_t bitOffset(size_t bit) {
|
||
|
return bit % 8;
|
||
|
}
|
||
|
|
||
|
// number of bytes needed to represent bitCount bits (round up)
|
||
|
constexpr inline size_t byteCount(size_t bitCount) {
|
||
|
return bitCount / 8 + (bitCount % 8 != 0);
|
||
|
}
|
||
|
|
||
|
// set bit
|
||
|
inline void setBit(uint8_t* p, size_t bit) {
|
||
|
p[byteIndex(bit)] |= (1 << bitOffset(bit));
|
||
|
}
|
||
|
|
||
|
inline void setBits(uint8_t* p, size_t bit, size_t count, uint32_t value) {
|
||
|
assert(value < (1 << count));
|
||
|
while (count) {
|
||
|
size_t index = byteIndex(bit);
|
||
|
size_t offset = bitOffset(bit);
|
||
|
size_t countInThisByte = std::min(count, 8 - offset);
|
||
|
// Extract "countInThisByte" bits from value
|
||
|
uint8_t mask = (1 << countInThisByte) - 1;
|
||
|
uint8_t v = value & mask;
|
||
|
// Wipe out these bits, then set them to the new value
|
||
|
p[index] = (p[index] & ~(mask << offset)) | (v << offset);
|
||
|
|
||
|
value >>= countInThisByte;
|
||
|
bit += countInThisByte;
|
||
|
count -= countInThisByte;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline uint32_t getBits(uint8_t* p, size_t bit, size_t count) {
|
||
|
uint32_t value = 0;
|
||
|
size_t shift = 0;
|
||
|
while (count) {
|
||
|
size_t index = byteIndex(bit);
|
||
|
size_t offset = bitOffset(bit);
|
||
|
size_t countInThisByte = std::min(count, 8 - offset);
|
||
|
uint8_t mask = (1 << countInThisByte) - 1;
|
||
|
uint8_t v = (p[index] & (mask << offset)) >> offset;
|
||
|
|
||
|
value |= (v << shift);
|
||
|
shift += countInThisByte;
|
||
|
bit += countInThisByte;
|
||
|
count -= countInThisByte;
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
// clear bit
|
||
|
inline void clearBit(uint8_t* p, size_t bit) {
|
||
|
p[byteIndex(bit)] &= ~(1 << bitOffset(bit));
|
||
|
}
|
||
|
|
||
|
// test bit
|
||
|
inline bool testBit(const uint8_t* p, size_t bit) {
|
||
|
return p[byteIndex(bit)] & (1 << bitOffset(bit));
|
||
|
}
|
||
|
|
||
|
// Overloads for vector<uint8_t>, array<uint8_t>, or anything else that has
|
||
|
// a working operator[]
|
||
|
template <class T>
|
||
|
inline void setBit(T& p, size_t bit) {
|
||
|
setBit(&p[0], bit);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
inline void clearBit(T& p, size_t bit) {
|
||
|
clearBit(&p[0], bit);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
inline bool testBit(const T& p, size_t bit) {
|
||
|
return testBit(&p[0], bit);
|
||
|
}
|
||
|
|
||
|
} // namespace neutronium
|
||
|
} // namespace protocol
|
||
|
} // namespace thrift
|
||
|
} // namespace apache
|
||
|
|
||
|
#endif /* THRIFT_LIB_CPP_PROTOCOL_NEUTRONIUM_UTILS_H_ */
|
||
|
|