ztx 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0f3ebafd30e7497278b5d0ed3cfe793fc85d5dd2
4
+ data.tar.gz: 8c305537fea1dd3e84aec06eb6166aba76ba7a97
5
+ SHA512:
6
+ metadata.gz: 32fc00fd5b964f5cbe1763591506de3b134df4a25be39eb6c8b2ee4dcef2c2b5191a928ef777c93f2a9a7916a39d1671dbdb8fb48d7090e64ce27944b0ea0c5c
7
+ data.tar.gz: 50cc3158dab18730fe27296085167076c8a118f9894545ebb0ae46e59e0818d9d70478238e6873ee7267c93968fdaf1fa4ba6245ad9cbffba83ed8f7d728555c
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ztx.gemspec
4
+ gemspec
@@ -0,0 +1,41 @@
1
+ # Ztx
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ztx`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ztx'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ztx
22
+
23
+ ## Usage
24
+
25
+ See http://gimite.net/en/index.php?tx-ruby
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ztx.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,59 @@
1
+ This is a Ruby binding of Tx, a library for a compact trie data structure.
2
+
3
+ See http://gimite.net/en/index.php?tx-ruby to know how to install etc.
4
+
5
+ For details of Tx, see: http://www-tsujii.is.s.u-tokyo.ac.jp/~hillbig/tx.htm
6
+
7
+ Usage example of simple index:
8
+ require "tx"
9
+
10
+ # Builds an index and saves it to a file.
11
+ builder = Tx::Builder.new
12
+ builder.add_all(["foo", "ho", "hog", "hoga", "hoge", "hogeshi"])
13
+ builder.build("test.index")
14
+
15
+ # Loads an index.
16
+ index = Tx::Index.open("test.index")
17
+
18
+ # Simple lookup.
19
+ index.include?("hoge") #=> true
20
+ index.include?("bar") #=> false
21
+
22
+ # Searches prefixes of the word.
23
+ index.longest_prefix("hogeeee") #=> 4 (which means "hoge" is in the index)
24
+ index.search_prefixes("hoge") #=> ["ho", "hog", "hoge"]
25
+
26
+ # Searches words which begin with the string.
27
+ index.search_expansions("hog") #=> ["hog", "hoga", "hoge", "hogeshi"]
28
+
29
+ # Finds all occurences of words in the index.
30
+ index.scan("hogefugafoo") #=> [["hoge", 0], ["foo", 8]]
31
+
32
+ # Replaces words in the index.
33
+ index.gsub("hogefugafoo"){ |s, i| s.upcase }
34
+ #=> "HOGEfugaFOO"
35
+
36
+ Usage example of Hash-like index:
37
+ require "tx"
38
+
39
+ # Builds an index and saves it to a file.
40
+ builder = Tx::MapBuilder.new
41
+ builder.add("ho", "foo")
42
+ builder.add("hoge", "bar")
43
+ builder.build("test")
44
+
45
+ # Loads an index.
46
+ map = Tx::Map.open("test")
47
+
48
+ # Simple lookup.
49
+ map.has_key?("hoge") #=> true
50
+ map["hoge"] #=> "bar"
51
+ map["fuga"] #=> nil
52
+
53
+ # Searches prefixes/expansion of the word in keys.
54
+ map.key_index.longest_prefix("hogeeee") #=> 4 (which means the index has a key "hoge")
55
+ map.key_index.search_prefixes("hoge") #=> ["ho", "hoge"]
56
+ map.key_index.search_expansions("ho") #=> ["ho", "hoge"]
57
+
58
+ # Finds all occurences of keys in the index.
59
+ index.scan("hogehoga") #=> [["hoge", 0, "bar"], ["ho", 4, "foo"]]
@@ -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
@@ -0,0 +1,6 @@
1
+ ssv.o: ssv.cpp ssv.hpp
2
+ tx_core.o: tx.cpp tx.hpp ssv.hpp
3
+ tx_swig.o: tx_swig.cpp tx_swig.h
4
+ tx_swig_wrap.o: tx_swig_wrap.cxx tx_swig.h tx.hpp ssv.hpp
5
+ tx_swig_wrap.cxx: tx_swig.i tx_swig.h
6
+ swig -c++ -ruby -initname tx_core tx_swig.i
@@ -0,0 +1,15 @@
1
+ require "rbconfig"
2
+ require "mkmf"
3
+
4
+ if RbConfig::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
@@ -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
+ }