dartsclone 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rspec +3 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +2 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +23 -0
- data/README.md +64 -0
- data/Rakefile +15 -0
- data/dartsclone.gemspec +27 -0
- data/ext/dartsclone/dartscloneext.cpp +8 -0
- data/ext/dartsclone/dartscloneext.hpp +229 -0
- data/ext/dartsclone/extconf.rb +8 -0
- data/ext/dartsclone/src/COPYING.md +11 -0
- data/ext/dartsclone/src/darts.h +1931 -0
- data/lib/dartsclone.rb +4 -0
- data/lib/dartsclone/version.rb +6 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ffd79764c75c8fd8c2b7dc55b5f80c3875a0641420f05a9d1e07d701ffc15a17
|
4
|
+
data.tar.gz: 70799ddcdb885b78fa338a36b28063df1ae41a0f87d3be6a1aad8faec8b939a7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af070c15bc7b53a58d06200a2a8da7ce931161c470248f43a80365af3323122db200fa467bce0fe738d5ecfbd1dde8865733c37a27dcf7d00f5c8947341feeef
|
7
|
+
data.tar.gz: d4bad89bbbb9b2a7c8aa0defb663e56db7cbdae2a934308ebb86c8ad4ddc24a8d659722186b1ce9de4ce1f4faeaefb17821f1564ec54865e668813ca06617994
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at yoshoku@outlook.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [https://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: https://contributor-covenant.org
|
74
|
+
[version]: https://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2020 Atsushi Tatsuma
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
12
|
+
and/or other materials provided with the distribution.
|
13
|
+
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
15
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
17
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
18
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
20
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
21
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
22
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
23
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Darts-clone.rb
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/yoshoku/darts-clone.rb.svg?branch=master)](https://travis-ci.org/yoshoku/darts-clone.rb)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/dartsclone.svg)](https://badge.fury.io/rb/dartsclone)
|
5
|
+
[![BSD 2-Clause License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg)](https://github.com/yoshoku/darts-clone.rb/blob/master/LICENSE.txt)
|
6
|
+
|
7
|
+
Darts-clone.rb is a Ruby binding for the [Darts-clone](https://github.com/s-yata/darts-clone).
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'dartsclone'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle install
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install dartsclone
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'dartsclone'
|
29
|
+
|
30
|
+
da = DartsClone::DoubleArray.new
|
31
|
+
|
32
|
+
# Construct a dictionary.
|
33
|
+
keys = ['abc', 'abcd', 'abcde', 'bcd', 'cde']
|
34
|
+
da.build(keys)
|
35
|
+
|
36
|
+
# Search for keys which match the prefix of given string.
|
37
|
+
p da.common_prefix_search('abcde')
|
38
|
+
# => [["abc", "abcd", "abcde"], [0, 1, 2]]
|
39
|
+
|
40
|
+
# Search a key which matches a given string.
|
41
|
+
p da.exact_match_search('abcd')
|
42
|
+
# => 1
|
43
|
+
|
44
|
+
# Dump the dictionary.
|
45
|
+
da.save('foo.dat')
|
46
|
+
|
47
|
+
# Load the dictionary.
|
48
|
+
da.open('foo.dat')
|
49
|
+
```
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/yoshoku/darts-clone.rb.
|
54
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/yoshoku/darts-clone.rb/blob/master/CODE_OF_CONDUCT.md).
|
55
|
+
|
56
|
+
## License
|
57
|
+
|
58
|
+
The gem is available as open source under the terms of the [BSD 2-clause License](https://opensource.org/licenses/BSD-2-Clause).
|
59
|
+
Moreover, the gem includes the source code of Darts-clone.
|
60
|
+
The License of Darts-clone can be found in [COPYING.md](https://github.com/yoshoku/darts-clone.rb/blob/master/ext/dartsclone/src/COPYING.md).
|
61
|
+
|
62
|
+
## Code of Conduct
|
63
|
+
|
64
|
+
Everyone interacting in the Darts project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/yoshoku/darts-clone.rb/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
require 'rake/extensiontask'
|
7
|
+
|
8
|
+
task :build => :compile
|
9
|
+
|
10
|
+
Rake::ExtensionTask.new('dartscloneext') do |ext|
|
11
|
+
ext.ext_dir = 'ext/dartsclone'
|
12
|
+
ext.lib_dir = 'lib/dartsclone'
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => [:clobber, :compile, :spec]
|
data/dartsclone.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative 'lib/dartsclone/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'dartsclone'
|
5
|
+
spec.version = DartsClone::VERSION
|
6
|
+
spec.authors = ['yoshoku']
|
7
|
+
spec.email = ['yoshoku@outlook.com']
|
8
|
+
|
9
|
+
spec.summary = 'Ruby binding for the Darts-clone.'
|
10
|
+
spec.description = 'Darts-clone.rb is a Ruby binding for the Darts-clone.'
|
11
|
+
spec.homepage = 'https://github.com/yoshoku/darts-clone.rb'
|
12
|
+
spec.license = 'BSD-2-Clause'
|
13
|
+
|
14
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
15
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
16
|
+
spec.metadata['changelog_uri'] = 'https://github.com/yoshoku/darts-clone.rb/blob/master/CHANGELOG.md'
|
17
|
+
|
18
|
+
# Specify which files should be added to the gem when it is released.
|
19
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
20
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
21
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
end
|
23
|
+
spec.bindir = 'exe'
|
24
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
|
+
spec.require_paths = ['lib']
|
26
|
+
spec.extensions = ['ext/dartsclone/extconf.rb']
|
27
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
#ifndef DARTSCLONEEXT_HPP
|
2
|
+
#define DARTSCLONEEXT_HPP 1
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
#include <darts.h>
|
6
|
+
|
7
|
+
class RbDoubleArray
|
8
|
+
{
|
9
|
+
public:
|
10
|
+
static VALUE double_array_alloc(VALUE self) {
|
11
|
+
Darts::DoubleArray* ptr = (Darts::DoubleArray*)ruby_xmalloc(sizeof(Darts::DoubleArray));
|
12
|
+
return Data_Wrap_Struct(self, NULL, double_array_free, ptr);
|
13
|
+
};
|
14
|
+
|
15
|
+
static void double_array_free(Darts::DoubleArray* ptr) {
|
16
|
+
ptr->~DoubleArrayImpl();
|
17
|
+
ruby_xfree(ptr);
|
18
|
+
};
|
19
|
+
|
20
|
+
static Darts::DoubleArray* get_double_array(VALUE self) {
|
21
|
+
Darts::DoubleArray* ptr;
|
22
|
+
Data_Get_Struct(self, Darts::DoubleArray, ptr);
|
23
|
+
return ptr;
|
24
|
+
};
|
25
|
+
|
26
|
+
static VALUE define_class(VALUE rb_mDarts) {
|
27
|
+
VALUE rb_cDoubleArray = rb_define_class_under(rb_mDarts, "DoubleArray", rb_cObject);
|
28
|
+
rb_define_alloc_func(rb_cDoubleArray, double_array_alloc);
|
29
|
+
rb_define_method(rb_cDoubleArray, "initialize", RUBY_METHOD_FUNC(_double_array_init), 0);
|
30
|
+
rb_define_method(rb_cDoubleArray, "build", RUBY_METHOD_FUNC(_double_array_build), -1);
|
31
|
+
rb_define_method(rb_cDoubleArray, "open", RUBY_METHOD_FUNC(_double_array_open), -1);
|
32
|
+
rb_define_method(rb_cDoubleArray, "save", RUBY_METHOD_FUNC(_double_array_save), -1);
|
33
|
+
rb_define_method(rb_cDoubleArray, "exact_match_search", RUBY_METHOD_FUNC(_double_array_exact_match_search), -1);
|
34
|
+
rb_define_method(rb_cDoubleArray, "common_prefix_search", RUBY_METHOD_FUNC(_double_array_common_prefix_search), -1);
|
35
|
+
rb_define_method(rb_cDoubleArray, "traverse", RUBY_METHOD_FUNC(_double_array_traverse), -1);
|
36
|
+
rb_define_method(rb_cDoubleArray, "unit_size", RUBY_METHOD_FUNC(_double_array_unit_size), 0);
|
37
|
+
rb_define_method(rb_cDoubleArray, "size", RUBY_METHOD_FUNC(_double_array_size), 0);
|
38
|
+
rb_define_method(rb_cDoubleArray, "total_size", RUBY_METHOD_FUNC(_double_array_total_size), 0);
|
39
|
+
rb_define_method(rb_cDoubleArray, "clear", RUBY_METHOD_FUNC(_double_array_clear), 0);
|
40
|
+
return rb_cDoubleArray;
|
41
|
+
};
|
42
|
+
|
43
|
+
private:
|
44
|
+
static VALUE _double_array_init(VALUE self) {
|
45
|
+
Darts::DoubleArray* ptr = get_double_array(self);
|
46
|
+
new (ptr) Darts::DoubleArray();
|
47
|
+
return Qnil;
|
48
|
+
};
|
49
|
+
|
50
|
+
static VALUE _double_array_build(int argc, VALUE* argv, VALUE self) {
|
51
|
+
VALUE _keys = Qnil;
|
52
|
+
VALUE kwargs = Qnil;
|
53
|
+
rb_scan_args(argc, argv, "1:", &_keys, &kwargs);
|
54
|
+
|
55
|
+
ID kwtable[1] = { rb_intern("values") };
|
56
|
+
VALUE kwvalues[1] = { Qundef };
|
57
|
+
rb_get_kwargs(kwargs, kwtable, 0, 1, kwvalues);
|
58
|
+
VALUE _values = kwvalues[0];
|
59
|
+
|
60
|
+
const int n_keys = RARRAY_LEN(_keys);
|
61
|
+
char** keys = (char**)ruby_xmalloc(n_keys * sizeof(char*));
|
62
|
+
int* values = _values == Qundef ? NULL : (int*)ruby_xmalloc(n_keys * sizeof(int));
|
63
|
+
for (int i = 0; i < n_keys; i++) {
|
64
|
+
VALUE key_str = rb_ary_entry(_keys, i);
|
65
|
+
keys[i] = StringValueCStr(key_str);
|
66
|
+
if (_values != Qundef) values[i] = NUM2INT(rb_ary_entry(_values, i));
|
67
|
+
}
|
68
|
+
|
69
|
+
try {
|
70
|
+
get_double_array(self)->build(n_keys, keys, NULL, values);
|
71
|
+
} catch (Darts::Details::Exception e) {
|
72
|
+
ruby_xfree(keys);
|
73
|
+
if (_values != Qundef) ruby_xfree(values);
|
74
|
+
rb_raise(rb_eRuntimeError, "%s", e.what());
|
75
|
+
return Qfalse;
|
76
|
+
}
|
77
|
+
ruby_xfree(keys);
|
78
|
+
if (_values != Qundef) ruby_xfree(values);
|
79
|
+
return Qtrue;
|
80
|
+
}
|
81
|
+
|
82
|
+
static VALUE _double_array_open(int argc, VALUE* argv, VALUE self) {
|
83
|
+
VALUE _filename = Qnil;
|
84
|
+
VALUE kwargs = Qnil;
|
85
|
+
rb_scan_args(argc, argv, "1:", &_filename, &kwargs);
|
86
|
+
|
87
|
+
ID kwtable[3] = { rb_intern("mode"), rb_intern("offset"), rb_intern("size") };
|
88
|
+
VALUE kwvalues[3] = { Qundef, Qundef, Qundef };
|
89
|
+
rb_get_kwargs(kwargs, kwtable, 0, 3, kwvalues);
|
90
|
+
|
91
|
+
const char* filename = StringValueCStr(_filename);
|
92
|
+
const char* mode = kwvalues[0] == Qundef ? "rb" : StringValueCStr(kwvalues[0]);
|
93
|
+
const size_t offset = kwvalues[1] == Qundef ? 0 : (size_t)NUM2INT(kwvalues[1]);
|
94
|
+
const size_t size = kwvalues[2] == Qundef ? 0 : (size_t)NUM2INT(kwvalues[2]);
|
95
|
+
|
96
|
+
if (get_double_array(self)->open(filename, mode, offset, size) != 0) {
|
97
|
+
return Qfalse;
|
98
|
+
}
|
99
|
+
return Qtrue;
|
100
|
+
};
|
101
|
+
|
102
|
+
static VALUE _double_array_save(int argc, VALUE* argv, VALUE self) {
|
103
|
+
VALUE _filename = Qnil;
|
104
|
+
VALUE kwargs = Qnil;
|
105
|
+
rb_scan_args(argc, argv, "1:", &_filename, &kwargs);
|
106
|
+
|
107
|
+
ID kwtable[2] = { rb_intern("mode"), rb_intern("offset") };
|
108
|
+
VALUE kwvalues[2] = { Qundef, Qundef };
|
109
|
+
rb_get_kwargs(kwargs, kwtable, 0, 2, kwvalues);
|
110
|
+
|
111
|
+
const char* filename = StringValueCStr(_filename);
|
112
|
+
const char* mode = kwvalues[0] == Qundef ? "wb" : StringValueCStr(kwvalues[0]);
|
113
|
+
const size_t offset = kwvalues[1] == Qundef ? 0 : (size_t)NUM2INT(kwvalues[1]);
|
114
|
+
|
115
|
+
if (get_double_array(self)->save(filename, mode, offset) != 0) {
|
116
|
+
return Qfalse;
|
117
|
+
}
|
118
|
+
return Qtrue;
|
119
|
+
};
|
120
|
+
|
121
|
+
static VALUE _double_array_exact_match_search(int argc, VALUE* argv, VALUE self) {
|
122
|
+
VALUE _key = Qnil;
|
123
|
+
VALUE kwargs = Qnil;
|
124
|
+
rb_scan_args(argc, argv, "1:", &_key, &kwargs);
|
125
|
+
|
126
|
+
ID kwtable[2] = { rb_intern("length"), rb_intern("node_pos") };
|
127
|
+
VALUE kwvalues[2] = { Qundef, Qundef };
|
128
|
+
rb_get_kwargs(kwargs, kwtable, 0, 2, kwvalues);
|
129
|
+
|
130
|
+
if (get_double_array(self)->array() == NULL) {
|
131
|
+
rb_raise(rb_eRuntimeError, "failed to search: dictionary is empty");
|
132
|
+
return Qnil;
|
133
|
+
}
|
134
|
+
|
135
|
+
const char* key = StringValueCStr(_key);
|
136
|
+
const size_t length = kwvalues[0] == Qundef ? 0 : (size_t)NUM2INT(kwvalues[0]);
|
137
|
+
const size_t node_pos = kwvalues[1] == Qundef ? 0 : (size_t)NUM2INT(kwvalues[1]);
|
138
|
+
|
139
|
+
Darts::DoubleArray::value_type value;
|
140
|
+
get_double_array(self)->exactMatchSearch(key, value, length, node_pos);
|
141
|
+
return INT2NUM(value);
|
142
|
+
};
|
143
|
+
|
144
|
+
static VALUE _double_array_common_prefix_search(int argc, VALUE* argv, VALUE self) {
|
145
|
+
VALUE _key = Qnil;
|
146
|
+
VALUE kwargs = Qnil;
|
147
|
+
rb_scan_args(argc, argv, "1:", &_key, &kwargs);
|
148
|
+
|
149
|
+
ID kwtable[3] = { rb_intern("max_num_results"), rb_intern("length"), rb_intern("node_pos") };
|
150
|
+
VALUE kwvalues[3] = { Qundef, Qundef, Qundef };
|
151
|
+
rb_get_kwargs(kwargs, kwtable, 0, 3, kwvalues);
|
152
|
+
|
153
|
+
if (get_double_array(self)->array() == NULL) {
|
154
|
+
rb_raise(rb_eRuntimeError, "failed to search: dictionary is empty");
|
155
|
+
return Qnil;
|
156
|
+
}
|
157
|
+
|
158
|
+
const char* key = StringValueCStr(_key);
|
159
|
+
const size_t max_num_results = kwvalues[0] == Qundef ? (size_t)NUM2INT(rb_funcall(_key, rb_intern("size"), 0)) : (size_t)NUM2INT(kwvalues[0]);
|
160
|
+
const size_t length = kwvalues[1] == Qundef ? 0 : (size_t)NUM2INT(kwvalues[1]);
|
161
|
+
const size_t node_pos = kwvalues[2] == Qundef ? 0 : (size_t)NUM2INT(kwvalues[2]);
|
162
|
+
|
163
|
+
Darts::DoubleArray::result_pair_type* results =
|
164
|
+
(Darts::DoubleArray::result_pair_type*)ruby_xmalloc(max_num_results * sizeof(Darts::DoubleArray::result_pair_type));
|
165
|
+
const size_t num_matches = get_double_array(self)->commonPrefixSearch(key, results, max_num_results, length, node_pos);
|
166
|
+
const int num_returns = (int)(max_num_results < num_matches ? max_num_results : num_matches);
|
167
|
+
|
168
|
+
VALUE ret = rb_ary_new();
|
169
|
+
if (num_returns > 0) {
|
170
|
+
VALUE keyenc = rb_funcall(_key, rb_intern("encoding"), 0);
|
171
|
+
VALUE lengths = rb_ary_new2(num_returns);
|
172
|
+
VALUE values = rb_ary_new2(num_returns);
|
173
|
+
for (int i = 0; i < num_returns; i++) {
|
174
|
+
rb_ary_store(lengths, i, rb_funcall(rb_str_new(key, results[i].length), rb_intern("force_encoding"), 1, keyenc));
|
175
|
+
rb_ary_store(values, i, INT2NUM(results[i].value));
|
176
|
+
}
|
177
|
+
rb_ary_push(ret, lengths);
|
178
|
+
rb_ary_push(ret, values);
|
179
|
+
}
|
180
|
+
ruby_xfree(results);
|
181
|
+
return ret;
|
182
|
+
};
|
183
|
+
|
184
|
+
static VALUE _double_array_traverse(int argc, VALUE* argv, VALUE self) {
|
185
|
+
VALUE _key = Qnil;
|
186
|
+
VALUE kwargs = Qnil;
|
187
|
+
rb_scan_args(argc, argv, "1:", &_key, &kwargs);
|
188
|
+
|
189
|
+
ID kwtable[3] = { rb_intern("node_pos"), rb_intern("key_pos"), rb_intern("length") };
|
190
|
+
VALUE kwvalues[3] = { Qundef, Qundef, Qundef };
|
191
|
+
rb_get_kwargs(kwargs, kwtable, 2, 1, kwvalues);
|
192
|
+
|
193
|
+
const char* key = StringValueCStr(_key);
|
194
|
+
size_t node_pos = (size_t)NUM2INT(kwvalues[0]);
|
195
|
+
size_t key_pos = (size_t)NUM2INT(kwvalues[1]);
|
196
|
+
const size_t length = kwvalues[2] == Qundef ? 0 : (size_t)NUM2INT(kwvalues[2]);
|
197
|
+
|
198
|
+
Darts::DoubleArray::value_type value = get_double_array(self)->traverse(key, node_pos, key_pos, length);
|
199
|
+
|
200
|
+
VALUE ret = rb_hash_new();
|
201
|
+
rb_hash_aset(ret, ID2SYM(rb_intern("value")), INT2NUM(value));
|
202
|
+
rb_hash_aset(ret, ID2SYM(rb_intern("node_pos")), INT2NUM((int)node_pos));
|
203
|
+
rb_hash_aset(ret, ID2SYM(rb_intern("key_pos")), INT2NUM((int)key_pos));
|
204
|
+
return ret;
|
205
|
+
};
|
206
|
+
|
207
|
+
static VALUE _double_array_unit_size(VALUE self) {
|
208
|
+
return INT2NUM((int)(get_double_array(self)->unit_size()));
|
209
|
+
};
|
210
|
+
|
211
|
+
static VALUE _double_array_size(VALUE self) {
|
212
|
+
return INT2NUM((int)(get_double_array(self)->size()));
|
213
|
+
};
|
214
|
+
|
215
|
+
static VALUE _double_array_total_size(VALUE self) {
|
216
|
+
return INT2NUM((int)(get_double_array(self)->total_size()));
|
217
|
+
};
|
218
|
+
|
219
|
+
static VALUE _double_array_nonzero_size(VALUE self) {
|
220
|
+
return INT2NUM((int)(get_double_array(self)->nonzero_size()));
|
221
|
+
};
|
222
|
+
|
223
|
+
static VALUE _double_array_clear(VALUE self) {
|
224
|
+
get_double_array(self)->clear();
|
225
|
+
return Qnil;
|
226
|
+
};
|
227
|
+
};
|
228
|
+
|
229
|
+
#endif /* DARTSCLONEEXT_HPP */
|