2017-07-12 06:48:49 +00:00
|
|
|
#include <popcntintrin.h>
|
|
|
|
|
2016-12-03 07:51:00 +00:00
|
|
|
#include "BitVector.hpp"
|
|
|
|
|
|
|
|
namespace xcdat {
|
|
|
|
|
|
|
|
// inspired by marisa-trie
|
|
|
|
constexpr uint8_t kSelectTable[9][256] = {
|
|
|
|
{
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
|
|
},
|
|
|
|
{
|
|
|
|
8, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
6, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
7, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
6, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
8, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
6, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
7, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
6, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
|
|
|
|
5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1
|
|
|
|
},
|
|
|
|
{
|
|
|
|
8, 8, 8, 2, 8, 3, 3, 2, 8, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
8, 5, 5, 2, 5, 3, 3, 2, 5, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
8, 6, 6, 2, 6, 3, 3, 2, 6, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
6, 5, 5, 2, 5, 3, 3, 2, 5, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
8, 7, 7, 2, 7, 3, 3, 2, 7, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
7, 5, 5, 2, 5, 3, 3, 2, 5, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
7, 6, 6, 2, 6, 3, 3, 2, 6, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
6, 5, 5, 2, 5, 3, 3, 2, 5, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
8, 8, 8, 2, 8, 3, 3, 2, 8, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
8, 5, 5, 2, 5, 3, 3, 2, 5, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
8, 6, 6, 2, 6, 3, 3, 2, 6, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
6, 5, 5, 2, 5, 3, 3, 2, 5, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
8, 7, 7, 2, 7, 3, 3, 2, 7, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
7, 5, 5, 2, 5, 3, 3, 2, 5, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
7, 6, 6, 2, 6, 3, 3, 2, 6, 4, 4, 2, 4, 3, 3, 2,
|
|
|
|
6, 5, 5, 2, 5, 3, 3, 2, 5, 4, 4, 2, 4, 3, 3, 2
|
|
|
|
},
|
|
|
|
{
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 3, 8, 8, 8, 4, 8, 4, 4, 3,
|
|
|
|
8, 8, 8, 5, 8, 5, 5, 3, 8, 5, 5, 4, 5, 4, 4, 3,
|
|
|
|
8, 8, 8, 6, 8, 6, 6, 3, 8, 6, 6, 4, 6, 4, 4, 3,
|
|
|
|
8, 6, 6, 5, 6, 5, 5, 3, 6, 5, 5, 4, 5, 4, 4, 3,
|
|
|
|
8, 8, 8, 7, 8, 7, 7, 3, 8, 7, 7, 4, 7, 4, 4, 3,
|
|
|
|
8, 7, 7, 5, 7, 5, 5, 3, 7, 5, 5, 4, 5, 4, 4, 3,
|
|
|
|
8, 7, 7, 6, 7, 6, 6, 3, 7, 6, 6, 4, 6, 4, 4, 3,
|
|
|
|
7, 6, 6, 5, 6, 5, 5, 3, 6, 5, 5, 4, 5, 4, 4, 3,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 3, 8, 8, 8, 4, 8, 4, 4, 3,
|
|
|
|
8, 8, 8, 5, 8, 5, 5, 3, 8, 5, 5, 4, 5, 4, 4, 3,
|
|
|
|
8, 8, 8, 6, 8, 6, 6, 3, 8, 6, 6, 4, 6, 4, 4, 3,
|
|
|
|
8, 6, 6, 5, 6, 5, 5, 3, 6, 5, 5, 4, 5, 4, 4, 3,
|
|
|
|
8, 8, 8, 7, 8, 7, 7, 3, 8, 7, 7, 4, 7, 4, 4, 3,
|
|
|
|
8, 7, 7, 5, 7, 5, 5, 3, 7, 5, 5, 4, 5, 4, 4, 3,
|
|
|
|
8, 7, 7, 6, 7, 6, 6, 3, 7, 6, 6, 4, 6, 4, 4, 3,
|
|
|
|
7, 6, 6, 5, 6, 5, 5, 3, 6, 5, 5, 4, 5, 4, 4, 3
|
|
|
|
},
|
|
|
|
{
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 5, 8, 8, 8, 5, 8, 5, 5, 4,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 6, 8, 8, 8, 6, 8, 6, 6, 4,
|
|
|
|
8, 8, 8, 6, 8, 6, 6, 5, 8, 6, 6, 5, 6, 5, 5, 4,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 7, 8, 7, 7, 4,
|
|
|
|
8, 8, 8, 7, 8, 7, 7, 5, 8, 7, 7, 5, 7, 5, 5, 4,
|
|
|
|
8, 8, 8, 7, 8, 7, 7, 6, 8, 7, 7, 6, 7, 6, 6, 4,
|
|
|
|
8, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 5, 8, 8, 8, 5, 8, 5, 5, 4,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 6, 8, 8, 8, 6, 8, 6, 6, 4,
|
|
|
|
8, 8, 8, 6, 8, 6, 6, 5, 8, 6, 6, 5, 6, 5, 5, 4,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 7, 8, 7, 7, 4,
|
|
|
|
8, 8, 8, 7, 8, 7, 7, 5, 8, 7, 7, 5, 7, 5, 5, 4,
|
|
|
|
8, 8, 8, 7, 8, 7, 7, 6, 8, 7, 7, 6, 7, 6, 6, 4,
|
|
|
|
8, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4
|
|
|
|
},
|
|
|
|
{
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 6, 8, 8, 8, 6, 8, 6, 6, 5,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 7, 8, 7, 7, 5,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 7, 8, 7, 7, 6,
|
|
|
|
8, 8, 8, 7, 8, 7, 7, 6, 8, 7, 7, 6, 7, 6, 6, 5,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 6, 8, 8, 8, 6, 8, 6, 6, 5,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 7, 8, 7, 7, 5,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 7, 8, 7, 7, 6,
|
|
|
|
8, 8, 8, 7, 8, 7, 7, 6, 8, 7, 7, 6, 7, 6, 6, 5
|
|
|
|
},
|
|
|
|
{
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 7, 8, 7, 7, 6,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 7, 8, 8, 8, 7, 8, 7, 7, 6
|
|
|
|
},
|
|
|
|
{
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7
|
|
|
|
},
|
|
|
|
{
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
uint32_t pop_count(uint32_t bits) {
|
2017-07-12 06:48:49 +00:00
|
|
|
#ifdef XCDAT_USE_POPCNT
|
|
|
|
return static_cast<uint32_t>(_mm_popcnt_u32(bits));
|
|
|
|
#else
|
2016-12-03 07:51:00 +00:00
|
|
|
bits = ((bits & 0xAAAAAAAA) >> 1) + (bits & 0x55555555);
|
|
|
|
bits = ((bits & 0xCCCCCCCC) >> 2) + (bits & 0x33333333);
|
|
|
|
bits = ((bits >> 4) + bits) & 0x0F0F0F0F;
|
|
|
|
bits += bits >> 8;
|
|
|
|
bits += bits >> 16;
|
|
|
|
return bits & 0x3F;
|
2017-07-12 06:48:49 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
BitVector::BitVector(std::istream& is) {
|
|
|
|
bits_ = Vector<uint32_t>(is);
|
|
|
|
rank_tips_ = Vector<RankTip>(is);
|
|
|
|
select_tips_ = Vector<id_type>(is);
|
|
|
|
size_ = read_value<size_t>(is);
|
|
|
|
num_1s_ = read_value<size_t>(is);
|
2016-12-03 07:51:00 +00:00
|
|
|
}
|
|
|
|
|
2017-11-04 14:06:08 +00:00
|
|
|
BitVector::BitVector(BitVectorBuilder& builder, bool rank_flag,
|
|
|
|
bool select_flag) {
|
2016-12-03 07:51:00 +00:00
|
|
|
if (!builder.size()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-12 06:48:49 +00:00
|
|
|
bits_ = Vector<uint32_t>(builder.bits_);
|
2016-12-03 07:51:00 +00:00
|
|
|
size_ = builder.size_;
|
2017-03-29 06:01:06 +00:00
|
|
|
num_1s_ = builder.num_1s_;
|
2016-12-03 07:51:00 +00:00
|
|
|
|
|
|
|
// builds rank_tips_
|
2017-03-29 06:01:06 +00:00
|
|
|
if (rank_flag) {
|
|
|
|
std::vector<RankTip> rank_tips(size_ / kBitsInR1 + 1);
|
|
|
|
id_type count = 0;
|
|
|
|
for (id_type i = 0; i < rank_tips.size(); ++i) {
|
|
|
|
auto& tip = rank_tips[i];
|
|
|
|
tip.L1 = count;
|
|
|
|
for (id_type offset = 0; offset < kR1PerR2; ++offset) {
|
|
|
|
tip.L2[offset] = static_cast<uint8_t>(count - tip.L1);
|
|
|
|
auto pos_in_bits = i * kR1PerR2 + offset;
|
|
|
|
if (pos_in_bits < bits_.size()) {
|
|
|
|
count += pop_count(bits_[pos_in_bits]);
|
|
|
|
}
|
2016-12-03 07:51:00 +00:00
|
|
|
}
|
|
|
|
}
|
2017-07-12 06:48:49 +00:00
|
|
|
rank_tips_ = Vector<RankTip>(rank_tips);
|
2016-12-03 07:51:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// builds select_tips_
|
2017-03-29 06:01:06 +00:00
|
|
|
if (rank_flag && select_flag) {
|
|
|
|
std::vector<id_type> select_tips{0};
|
|
|
|
auto count = kNum1sPerTip;
|
|
|
|
for (id_type i = 0; i < rank_tips_.size(); ++i) {
|
|
|
|
if (count < rank_tips_[i].L1) {
|
|
|
|
select_tips.push_back(i - 1);
|
|
|
|
count += kNum1sPerTip;
|
|
|
|
}
|
2016-12-03 07:51:00 +00:00
|
|
|
}
|
2017-03-29 06:01:06 +00:00
|
|
|
select_tips.push_back(static_cast<id_type>(rank_tips_.size() - 1));
|
2017-07-12 06:48:49 +00:00
|
|
|
select_tips_ = Vector<id_type>(select_tips);
|
2016-12-03 07:51:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-11 12:01:10 +00:00
|
|
|
id_type BitVector::rank(id_type i) const {
|
2016-12-03 07:51:00 +00:00
|
|
|
auto& hint = rank_tips_[i / kBitsInR1];
|
2017-03-29 06:01:06 +00:00
|
|
|
return hint.L1 + hint.L2[i / kBitsInR2 % kR1PerR2]
|
2016-12-03 07:51:00 +00:00
|
|
|
+ pop_count(bits_[i / 32] & ((1U << (i % 32)) - 1));
|
|
|
|
}
|
|
|
|
|
2017-11-11 12:01:10 +00:00
|
|
|
id_type BitVector::select(id_type i) const {
|
2017-03-29 06:01:06 +00:00
|
|
|
id_type left = 0, right = static_cast<id_type>(rank_tips_.size());
|
2016-12-03 07:51:00 +00:00
|
|
|
|
2017-03-29 06:01:06 +00:00
|
|
|
if (!select_tips_.is_empty()) {
|
2017-07-12 06:48:49 +00:00
|
|
|
auto select_tip_id = static_cast<id_type>(i / kNum1sPerTip);
|
2016-12-03 07:51:00 +00:00
|
|
|
left = select_tips_[select_tip_id];
|
|
|
|
right = select_tips_[select_tip_id + 1] + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (left + 1 < right) {
|
|
|
|
const auto center = (left + right) / 2;
|
2017-03-29 06:01:06 +00:00
|
|
|
if (i < rank_tips_[center].L1) {
|
2016-12-03 07:51:00 +00:00
|
|
|
right = center;
|
|
|
|
} else {
|
|
|
|
left = center;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
i += 1; // for i+1 th
|
2017-03-29 06:01:06 +00:00
|
|
|
i -= rank_tips_[left].L1;
|
2016-12-03 07:51:00 +00:00
|
|
|
|
|
|
|
uint32_t offset = 1;
|
|
|
|
for (; offset < kR1PerR2; ++offset) {
|
2017-03-29 06:01:06 +00:00
|
|
|
if (i <= rank_tips_[left].L2[offset]) {
|
2016-12-03 07:51:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-03-29 06:01:06 +00:00
|
|
|
i -= rank_tips_[left].L2[--offset];
|
2016-12-03 07:51:00 +00:00
|
|
|
|
|
|
|
auto ret = (left * kBitsInR1) + (offset * kBitsInR2);
|
|
|
|
auto bits = bits_[ret / 32];
|
|
|
|
|
|
|
|
{
|
|
|
|
auto _count = pop_count(bits % 65536);
|
|
|
|
if (_count < i) {
|
|
|
|
bits >>= 16;
|
|
|
|
ret += 16;
|
|
|
|
i -= _count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
auto _count = pop_count(bits % 256);
|
|
|
|
if (_count < i) {
|
|
|
|
bits >>= 8;
|
|
|
|
ret += 8;
|
|
|
|
i -= _count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret += kSelectTable[i][bits % 256];
|
|
|
|
return ret - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t BitVector::size_in_bytes() const {
|
|
|
|
size_t ret = 0;
|
2017-03-29 06:01:06 +00:00
|
|
|
ret += bits_.size_in_bytes();
|
|
|
|
ret += rank_tips_.size_in_bytes();
|
|
|
|
ret += select_tips_.size_in_bytes();
|
2016-12-03 07:51:00 +00:00
|
|
|
ret += sizeof(size_);
|
|
|
|
ret += sizeof(num_1s_);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BitVector::write(std::ostream& os) const {
|
2017-03-29 06:01:06 +00:00
|
|
|
bits_.write(os);
|
|
|
|
rank_tips_.write(os);
|
|
|
|
select_tips_.write(os);
|
2016-12-04 06:53:02 +00:00
|
|
|
write_value(size_, os);
|
|
|
|
write_value(num_1s_, os);
|
2016-12-03 07:51:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} //namespace - xcdat
|