tx 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +1 -0
- data/ext/Makefile +163 -0
- data/ext/depend +6 -0
- data/ext/extconf.rb +15 -0
- data/ext/ssv.cpp +355 -0
- data/ext/ssv.hpp +93 -0
- data/ext/swig.patch +192 -0
- data/ext/tx.cpp +442 -0
- data/ext/tx.hpp +62 -0
- data/ext/tx_swig.cpp +164 -0
- data/ext/tx_swig.h +93 -0
- data/ext/tx_swig.i +17 -0
- data/ext/tx_swig_wrap.cxx +9884 -0
- data/lib/i386-msvcrt/tx_core.so +0 -0
- data/lib/tx.rb +219 -0
- data/test/test_tx.rb +169 -0
- metadata +86 -0
data/README.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
See http://gimite.net/en/index.php?tx-ruby
|
data/ext/Makefile
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
|
2
|
+
SHELL = /bin/sh
|
3
|
+
|
4
|
+
#### Start of system configuration section. ####
|
5
|
+
|
6
|
+
srcdir = .
|
7
|
+
topdir = /usr/local/lib/ruby/1.8/i686-linux
|
8
|
+
hdrdir = $(topdir)
|
9
|
+
VPATH = $(srcdir):$(topdir):$(hdrdir)
|
10
|
+
exec_prefix = $(prefix)
|
11
|
+
prefix = $(DESTDIR)/usr/local
|
12
|
+
sharedstatedir = $(prefix)/com
|
13
|
+
mandir = $(datarootdir)/man
|
14
|
+
psdir = $(docdir)
|
15
|
+
oldincludedir = $(DESTDIR)/usr/include
|
16
|
+
localedir = $(datarootdir)/locale
|
17
|
+
bindir = $(exec_prefix)/bin
|
18
|
+
libexecdir = $(exec_prefix)/libexec
|
19
|
+
sitedir = $(libdir)/ruby/site_ruby
|
20
|
+
htmldir = $(docdir)
|
21
|
+
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
22
|
+
includedir = $(prefix)/include
|
23
|
+
infodir = $(datarootdir)/info
|
24
|
+
vendorlibdir = $(vendordir)/$(ruby_version)
|
25
|
+
sysconfdir = $(prefix)/etc
|
26
|
+
libdir = $(exec_prefix)/lib
|
27
|
+
sbindir = $(exec_prefix)/sbin
|
28
|
+
rubylibdir = $(libdir)/ruby/$(ruby_version)
|
29
|
+
docdir = $(datarootdir)/doc/$(PACKAGE)
|
30
|
+
dvidir = $(docdir)
|
31
|
+
vendordir = $(libdir)/ruby/vendor_ruby
|
32
|
+
datarootdir = $(prefix)/share
|
33
|
+
pdfdir = $(docdir)
|
34
|
+
archdir = $(rubylibdir)/$(arch)
|
35
|
+
sitearchdir = $(sitelibdir)/$(sitearch)
|
36
|
+
datadir = $(datarootdir)
|
37
|
+
localstatedir = $(prefix)/var
|
38
|
+
sitelibdir = $(sitedir)/$(ruby_version)
|
39
|
+
|
40
|
+
CC = gcc
|
41
|
+
LIBRUBY = $(LIBRUBY_A)
|
42
|
+
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
43
|
+
LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir)
|
44
|
+
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
|
45
|
+
|
46
|
+
RUBY_EXTCONF_H =
|
47
|
+
CFLAGS = -fPIC -g -O2 $(cflags)
|
48
|
+
INCFLAGS = -I. -I. -I/usr/local/lib/ruby/1.8/i686-linux -I.
|
49
|
+
DEFS = -D_FILE_OFFSET_BITS=64
|
50
|
+
CPPFLAGS = -D_FILE_OFFSET_BITS=64
|
51
|
+
CXXFLAGS = $(CFLAGS)
|
52
|
+
ldflags = -L. -rdynamic -Wl,-export-dynamic
|
53
|
+
dldflags =
|
54
|
+
archflag =
|
55
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
|
56
|
+
LDSHARED = $(CC) -shared
|
57
|
+
AR = ar
|
58
|
+
EXEEXT =
|
59
|
+
|
60
|
+
RUBY_INSTALL_NAME = ruby
|
61
|
+
RUBY_SO_NAME = ruby
|
62
|
+
arch = i686-linux
|
63
|
+
sitearch = i686-linux
|
64
|
+
ruby_version = 1.8
|
65
|
+
ruby = /usr/local/bin/ruby
|
66
|
+
RUBY = $(ruby)
|
67
|
+
RM = rm -f
|
68
|
+
MAKEDIRS = mkdir -p
|
69
|
+
INSTALL = /usr/bin/install -c
|
70
|
+
INSTALL_PROG = $(INSTALL) -m 0755
|
71
|
+
INSTALL_DATA = $(INSTALL) -m 644
|
72
|
+
COPY = cp
|
73
|
+
|
74
|
+
#### End of system configuration section. ####
|
75
|
+
|
76
|
+
preload =
|
77
|
+
|
78
|
+
libpath = . $(libdir)
|
79
|
+
LIBPATH = -L. -L$(libdir) -Wl,-R$(libdir)
|
80
|
+
DEFFILE =
|
81
|
+
|
82
|
+
CLEANFILES = mkmf.log
|
83
|
+
DISTCLEANFILES =
|
84
|
+
|
85
|
+
extout =
|
86
|
+
extout_prefix =
|
87
|
+
target_prefix =
|
88
|
+
LOCAL_LIBS =
|
89
|
+
LIBS = -lstdc++ -lrt -ldl -lcrypt -lm -lc
|
90
|
+
SRCS = tx_swig_wrap.cxx tx.cpp tx_swig.cpp ssv.cpp
|
91
|
+
OBJS = tx_swig_wrap.o tx.o tx_swig.o ssv.o
|
92
|
+
TARGET = tx_core
|
93
|
+
DLLIB = $(TARGET).so
|
94
|
+
EXTSTATIC =
|
95
|
+
STATIC_LIB =
|
96
|
+
|
97
|
+
BINDIR = $(bindir)
|
98
|
+
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
99
|
+
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
100
|
+
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
101
|
+
|
102
|
+
TARGET_SO = $(DLLIB)
|
103
|
+
CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
|
104
|
+
CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
|
105
|
+
|
106
|
+
all: $(DLLIB)
|
107
|
+
static: $(STATIC_LIB)
|
108
|
+
|
109
|
+
clean:
|
110
|
+
@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
|
111
|
+
|
112
|
+
distclean: clean
|
113
|
+
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
114
|
+
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
115
|
+
|
116
|
+
realclean: distclean
|
117
|
+
install: install-so install-rb
|
118
|
+
|
119
|
+
install-so: $(RUBYARCHDIR)
|
120
|
+
install-so: $(RUBYARCHDIR)/$(DLLIB)
|
121
|
+
$(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
|
122
|
+
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
123
|
+
install-rb: pre-install-rb install-rb-default
|
124
|
+
install-rb-default: pre-install-rb-default
|
125
|
+
pre-install-rb: Makefile
|
126
|
+
pre-install-rb-default: Makefile
|
127
|
+
$(RUBYARCHDIR):
|
128
|
+
$(MAKEDIRS) $@
|
129
|
+
|
130
|
+
site-install: site-install-so site-install-rb
|
131
|
+
site-install-so: install-so
|
132
|
+
site-install-rb: install-rb
|
133
|
+
|
134
|
+
.SUFFIXES: .c .m .cc .cxx .cpp .C .o
|
135
|
+
|
136
|
+
.cc.o:
|
137
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
138
|
+
|
139
|
+
.cxx.o:
|
140
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
141
|
+
|
142
|
+
.cpp.o:
|
143
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
144
|
+
|
145
|
+
.C.o:
|
146
|
+
$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
|
147
|
+
|
148
|
+
.c.o:
|
149
|
+
$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
|
150
|
+
|
151
|
+
$(DLLIB): $(OBJS) Makefile
|
152
|
+
@-$(RM) $@
|
153
|
+
$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
###
|
158
|
+
ssv.o: ssv.cpp ssv.hpp
|
159
|
+
tx_core.o: tx.cpp tx.hpp ssv.hpp
|
160
|
+
tx_swig.o: tx_swig.cpp tx_swig.h
|
161
|
+
tx_swig_wrap.o: tx_swig_wrap.cxx tx_swig.h tx.hpp ssv.hpp
|
162
|
+
tx_swig_wrap.cxx: tx_swig.i tx_swig.h
|
163
|
+
swig -c++ -ruby -initname tx_core tx_swig.i
|
data/ext/depend
ADDED
data/ext/extconf.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rbconfig"
|
2
|
+
require "mkmf"
|
3
|
+
|
4
|
+
if Config::CONFIG["sitearch"] == "i386-msvcrt" && !arg_config("--force-build")
|
5
|
+
# Pre-built binary exists. No need to compile.
|
6
|
+
# Cheats on mkmf.rb not to claim about missing Makefile.
|
7
|
+
$makefile_created= true
|
8
|
+
else
|
9
|
+
if have_library("stdc++")
|
10
|
+
create_makefile("tx_core")
|
11
|
+
else
|
12
|
+
$stderr.puts("-lstdc++ is required")
|
13
|
+
exit(1)
|
14
|
+
end
|
15
|
+
end
|
data/ext/ssv.cpp
ADDED
@@ -0,0 +1,355 @@
|
|
1
|
+
#include "ssv.hpp"
|
2
|
+
|
3
|
+
namespace tx_tool{
|
4
|
+
|
5
|
+
ssv::ssv(const uint _size):
|
6
|
+
B(NULL),size(0),oneNum(0),levelL(NULL),levelM(NULL), no_delete(false){
|
7
|
+
if (resize(_size) == -1) return;
|
8
|
+
}
|
9
|
+
|
10
|
+
ssv::ssv(std::vector<bool>& bv):
|
11
|
+
B(NULL),size(0),oneNum(0),levelL(NULL),levelM(NULL), no_delete(false){
|
12
|
+
if (resize((uint)bv.size()) == -1) return;
|
13
|
+
for (uint i = 0; i < (uint)bv.size(); i++){
|
14
|
+
setBit(i,bv[i]);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
int ssv::resize(const uint _size){
|
19
|
+
free();
|
20
|
+
size = _size;
|
21
|
+
blockSize = size/SSV_BLOCK + 1;
|
22
|
+
isBuild = false;
|
23
|
+
B = new uint [blockSize];
|
24
|
+
if (B == NULL){
|
25
|
+
return -1;
|
26
|
+
}
|
27
|
+
memset(B,0,sizeof(uint)*blockSize);
|
28
|
+
|
29
|
+
LBlockSize = size / SSV_LBLOCK + 1;
|
30
|
+
MBlockSize = size / SSV_MBLOCK + 1;
|
31
|
+
|
32
|
+
levelL = new uint [LBlockSize];
|
33
|
+
levelM = new uchar [MBlockSize];
|
34
|
+
return 0;
|
35
|
+
}
|
36
|
+
|
37
|
+
void ssv::free(){
|
38
|
+
if (!no_delete){
|
39
|
+
if (B){
|
40
|
+
delete[] B;
|
41
|
+
B=NULL;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
if (levelL){
|
45
|
+
delete[] levelL;
|
46
|
+
levelL=NULL;
|
47
|
+
}
|
48
|
+
if (levelM){
|
49
|
+
delete[] levelM;
|
50
|
+
levelM=NULL;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
ssv::~ssv(){
|
55
|
+
free();
|
56
|
+
}
|
57
|
+
|
58
|
+
uint ssv::getBits(const uint pos, uint width) const{
|
59
|
+
assert(width <=32);
|
60
|
+
assert(pos+width <= size);
|
61
|
+
if (width == 0) return 0;
|
62
|
+
|
63
|
+
//---: block version
|
64
|
+
const uint endPos = pos+width-1;
|
65
|
+
const uint blockPos_1 = pos / SSV_BLOCK;
|
66
|
+
const uint blockPos_2 = endPos / SSV_BLOCK;
|
67
|
+
const uint offset_1 = pos % SSV_BLOCK;
|
68
|
+
|
69
|
+
if (blockPos_1 == blockPos_2){
|
70
|
+
if (width == 32){
|
71
|
+
return B[blockPos_1]; //avoid 1U << 32
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
return (B[blockPos_1] >> offset_1) & ((1U << width) - 1);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
else {
|
78
|
+
const uint offset_2 = endPos % SSV_BLOCK;
|
79
|
+
return (B[blockPos_1] >> offset_1) + ((B[blockPos_2] & ((1U << (offset_2+1U))-1U)) << (32U-offset_1));
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
void ssv::setBits(const uint pos, const uint width, const uint x){
|
84
|
+
assert(width <= 32);
|
85
|
+
assert(pos+width <= size);
|
86
|
+
if (width == 0) return;
|
87
|
+
|
88
|
+
//---: block version ----
|
89
|
+
const uint endPos = pos+width-1;
|
90
|
+
const uint blockPos_1 = pos / SSV_BLOCK;
|
91
|
+
const uint blockPos_2 = endPos / SSV_BLOCK;
|
92
|
+
const uint offset_1 = pos % SSV_BLOCK;
|
93
|
+
|
94
|
+
if (blockPos_1 == blockPos_2){
|
95
|
+
if (width == 32){
|
96
|
+
B[blockPos_1] = x;
|
97
|
+
}
|
98
|
+
else {
|
99
|
+
B[blockPos_1] &= ~(((1U << width)-1) << offset_1); // |1111110000000111111|
|
100
|
+
B[blockPos_1] |= (x << offset_1); // xxxxxxx
|
101
|
+
}
|
102
|
+
}
|
103
|
+
else {
|
104
|
+
const uint offset_2 = endPos % SSV_BLOCK;
|
105
|
+
B[blockPos_1] &= ((1U << offset_1)-1U);
|
106
|
+
B[blockPos_1] |= (x << offset_1);
|
107
|
+
B[blockPos_2] &= ~((1U << (offset_2+1U))-1U);
|
108
|
+
B[blockPos_2] |= (x >> (32-offset_1));
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
|
113
|
+
uint ssv::rank(uint pos, const uint bit) const{
|
114
|
+
pos++;
|
115
|
+
if (bit == 0) return pos-_rank1(pos);
|
116
|
+
else return _rank1(pos);
|
117
|
+
}
|
118
|
+
|
119
|
+
uint ssv::select(const uint pos, const uint bit) const{
|
120
|
+
if (bit) return _select1(pos);
|
121
|
+
else return _select0(pos);
|
122
|
+
}
|
123
|
+
|
124
|
+
void ssv::setBit(uint pos, uint x){
|
125
|
+
if (!x) B[pos / SSV_BLOCK] &= (~(1U << (pos % SSV_BLOCK)));
|
126
|
+
else B[pos / SSV_BLOCK] |= (1U << (pos % SSV_BLOCK));
|
127
|
+
}
|
128
|
+
|
129
|
+
uint ssv::getAllocate() const{
|
130
|
+
uint sum = size;
|
131
|
+
if (isBuild){
|
132
|
+
sum += LBlockSize * 32 + MBlockSize * 8;
|
133
|
+
}
|
134
|
+
return sum;
|
135
|
+
}
|
136
|
+
|
137
|
+
void ssv::build(){
|
138
|
+
oneNum = rankBuild(size);
|
139
|
+
isBuild = true;
|
140
|
+
}
|
141
|
+
|
142
|
+
uint ssv::rankBuild(const uint t_size){
|
143
|
+
uint sum = 0;
|
144
|
+
for (uint il = 0; il <= t_size ;il += SSV_LBLOCK){
|
145
|
+
levelL[il/SSV_LBLOCK] = sum;
|
146
|
+
for (uint im = 0; im < SSV_LBLOCK && il+im <= t_size; im += SSV_MBLOCK){
|
147
|
+
levelM[(il+im)/SSV_MBLOCK] = sum - levelL[il/SSV_LBLOCK];
|
148
|
+
for (uint is = 0; is < SSV_MBLOCK && (il+im+is) <= t_size; is += SSV_BLOCK){
|
149
|
+
sum += popCount(B[(il+im+is)/SSV_BLOCK]);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
return sum;
|
154
|
+
}
|
155
|
+
|
156
|
+
|
157
|
+
int ssv::write(FILE* outfp){
|
158
|
+
if (fwrite(&size,sizeof(uint),1,outfp) != 1){
|
159
|
+
return -1;
|
160
|
+
}
|
161
|
+
if (fwrite(B,sizeof(uint),blockSize,outfp) != blockSize){
|
162
|
+
return -1;
|
163
|
+
}
|
164
|
+
if (fwrite(levelL,sizeof(uint),LBlockSize,outfp) != LBlockSize){
|
165
|
+
return -1;
|
166
|
+
}
|
167
|
+
if (fwrite(levelM,sizeof(uchar),MBlockSize,outfp) != MBlockSize){
|
168
|
+
return -1;
|
169
|
+
}
|
170
|
+
return 0;
|
171
|
+
}
|
172
|
+
|
173
|
+
int ssv::read(FILE* infp){
|
174
|
+
if (fread(&size,sizeof(uint),1,infp) != 1){
|
175
|
+
return -1;
|
176
|
+
}
|
177
|
+
if (resize(size) == -1){
|
178
|
+
return -1;
|
179
|
+
}
|
180
|
+
|
181
|
+
if (fread(B,sizeof(uint),blockSize,infp) != blockSize){
|
182
|
+
return -1;
|
183
|
+
}
|
184
|
+
isBuild = true;
|
185
|
+
|
186
|
+
if (fread(levelL,sizeof(uint),LBlockSize,infp) != LBlockSize){
|
187
|
+
return -1;
|
188
|
+
}
|
189
|
+
if (fread(levelM,sizeof(uchar),MBlockSize,infp) != MBlockSize){
|
190
|
+
return -1;
|
191
|
+
}
|
192
|
+
return 0;
|
193
|
+
}
|
194
|
+
|
195
|
+
size_t ssv::set_array(void* ptr){
|
196
|
+
size = *(uint*)(ptr);
|
197
|
+
|
198
|
+
blockSize = size/SSV_BLOCK + 1;
|
199
|
+
isBuild = false;
|
200
|
+
LBlockSize = size / SSV_LBLOCK + 1;
|
201
|
+
MBlockSize = size / SSV_MBLOCK + 1;
|
202
|
+
|
203
|
+
B = ((uint*)ptr + 1);
|
204
|
+
levelL = ((uint*)ptr + 1 + blockSize);
|
205
|
+
levelM = ((uchar*)ptr + sizeof(uint)*(1 + blockSize + LBlockSize));
|
206
|
+
|
207
|
+
no_delete = true;
|
208
|
+
return sizeof(uint)*(1 + blockSize + LBlockSize) + MBlockSize;
|
209
|
+
}
|
210
|
+
|
211
|
+
|
212
|
+
uint ssv::getBlock(const uint blockPos) const {
|
213
|
+
return B[blockPos];
|
214
|
+
}
|
215
|
+
|
216
|
+
void ssv::setBlock(const uint blockPos, const uint x) {
|
217
|
+
B[blockPos] = x;
|
218
|
+
}
|
219
|
+
|
220
|
+
uint ssv::getSize() const {
|
221
|
+
return size;
|
222
|
+
}
|
223
|
+
|
224
|
+
uint ssv::getBlockSize() const {
|
225
|
+
return blockSize;
|
226
|
+
}
|
227
|
+
|
228
|
+
uint ssv::popCount(uint r) const{
|
229
|
+
r = ((r & 0xAAAAAAAA) >> 1) + (r & 0x55555555);
|
230
|
+
r = ((r & 0xCCCCCCCC) >> 2) + (r & 0x33333333);
|
231
|
+
r = ((r >> 4) + r) & 0x0F0F0F0F;
|
232
|
+
r = (r>>8) + r;
|
233
|
+
return ((r>>16) + r) & 0x3F;
|
234
|
+
}
|
235
|
+
|
236
|
+
uint ssv::_rank1(const uint pos) const{
|
237
|
+
if (pos > size){
|
238
|
+
fprintf(stderr,"_rank1 range error pos:%d size:%d\n",pos,size);
|
239
|
+
return (uint)-1;
|
240
|
+
}
|
241
|
+
//printf("pos:%d size:%d lr:%d lp:%d mr:%d \n",pos,size,levelL[pos >> SSV_LBLOCK_SHIFT],pos >> SSV_LBLOCK_SHIFT,levelM[pos >> SSV_MBLOCK_SHIFT]);
|
242
|
+
return levelL[pos >> SSV_LBLOCK_SHIFT] +
|
243
|
+
levelM[pos >> SSV_MBLOCK_SHIFT] +
|
244
|
+
popCount((B[pos >> SSV_BLOCK_SHIFT] & ((1U << (pos % SSV_BLOCK))-1)));
|
245
|
+
}
|
246
|
+
|
247
|
+
uint ssv::_select0(uint x) const{
|
248
|
+
uint left = 0;
|
249
|
+
uint right = LBlockSize;
|
250
|
+
while (left < right){
|
251
|
+
uint mid = (left+right)/2;
|
252
|
+
if (SSV_LBLOCK * mid - levelL[mid] < x) left = mid+1;
|
253
|
+
else right = mid;
|
254
|
+
}
|
255
|
+
uint posL = (left != 0) ? left-1: 0;
|
256
|
+
|
257
|
+
// sequential search over levelB
|
258
|
+
uint posM = posL * (SSV_LBLOCK/SSV_MBLOCK);
|
259
|
+
x -= (SSV_LBLOCK*posL - levelL[posL]);
|
260
|
+
|
261
|
+
uint mstep = SSV_LBLOCK/SSV_MBLOCK;
|
262
|
+
while ((posM+1 < MBlockSize) && (((posM+1)%mstep) != 0) && (SSV_MBLOCK*((posM+1)%mstep)-levelM[posM+1] < x)){
|
263
|
+
posM++;
|
264
|
+
}
|
265
|
+
|
266
|
+
x -= (SSV_MBLOCK*(posM % mstep) - levelM[posM]);
|
267
|
+
|
268
|
+
uint ret = posM * SSV_MBLOCK;
|
269
|
+
uint posB = posM * (SSV_MBLOCK/SSV_BLOCK);
|
270
|
+
uint rank32 = 32- popCount(B[posB]);
|
271
|
+
if (rank32 < x){
|
272
|
+
posB++;
|
273
|
+
ret += SSV_BLOCK;
|
274
|
+
x -= rank32;
|
275
|
+
}
|
276
|
+
|
277
|
+
uint curB = B[posB];
|
278
|
+
uint rank16 = 16-popCount(curB & ((1U<<16)-1));
|
279
|
+
if (rank16 < x){
|
280
|
+
curB >>= 16;
|
281
|
+
ret += 16;
|
282
|
+
x -= rank16;
|
283
|
+
}
|
284
|
+
|
285
|
+
uint rank8 = 8-popCount(curB & ((1U << 8)-1));
|
286
|
+
if (rank8 < x){
|
287
|
+
curB >>= 8;
|
288
|
+
ret += 8;
|
289
|
+
x -= rank8;
|
290
|
+
}
|
291
|
+
|
292
|
+
while (x > 0){
|
293
|
+
if ((~curB) & 1){
|
294
|
+
x--;
|
295
|
+
}
|
296
|
+
curB >>= 1;
|
297
|
+
ret++;
|
298
|
+
}
|
299
|
+
return ret-1;
|
300
|
+
}
|
301
|
+
|
302
|
+
uint ssv::_select1(uint x) const{
|
303
|
+
uint left = 0;
|
304
|
+
uint right = LBlockSize;
|
305
|
+
while (left < right){
|
306
|
+
uint mid = (left+right)/2;
|
307
|
+
if (levelL[mid] < x) left = mid+1;
|
308
|
+
else right = mid;
|
309
|
+
}
|
310
|
+
uint posL = (left != 0) ? left-1: 0;
|
311
|
+
|
312
|
+
// sequential search over levelB
|
313
|
+
uint posM = posL * (SSV_LBLOCK/SSV_MBLOCK);
|
314
|
+
x -= levelL[posL];
|
315
|
+
while ((posM+1 < MBlockSize) && (((posM+1)%(SSV_LBLOCK/SSV_MBLOCK)) != 0) && (levelM[posM+1] < x)){
|
316
|
+
posM++;
|
317
|
+
}
|
318
|
+
|
319
|
+
x -= levelM[posM];
|
320
|
+
|
321
|
+
uint ret = posM * SSV_MBLOCK;
|
322
|
+
uint posB = posM * (SSV_MBLOCK/SSV_BLOCK);
|
323
|
+
uint rank32 = popCount(B[posB]);
|
324
|
+
if (rank32 < x){
|
325
|
+
posB++;
|
326
|
+
ret += SSV_BLOCK;
|
327
|
+
x -= rank32;
|
328
|
+
}
|
329
|
+
|
330
|
+
uint curB = B[posB];
|
331
|
+
uint rank16 = popCount(curB & ((1U<<16)-1));
|
332
|
+
if (rank16 < x){
|
333
|
+
curB >>= 16;
|
334
|
+
ret += 16;
|
335
|
+
x -= rank16;
|
336
|
+
}
|
337
|
+
|
338
|
+
uint rank8 = popCount(curB & ((1U << 8)-1));
|
339
|
+
if (rank8 < x){
|
340
|
+
curB >>= 8;
|
341
|
+
ret += 8;
|
342
|
+
x -= rank8;
|
343
|
+
}
|
344
|
+
|
345
|
+
while (x > 0){
|
346
|
+
if (curB & 1){
|
347
|
+
x--;
|
348
|
+
}
|
349
|
+
curB >>= 1;
|
350
|
+
ret++;
|
351
|
+
}
|
352
|
+
return ret-1;
|
353
|
+
}
|
354
|
+
|
355
|
+
}
|