tx 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|