dartsclone 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,20 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.bundle
10
+ *.so
11
+ *.o
12
+ *.a
13
+ *.swp
14
+ mkmf.log
15
+ tags
16
+ .DS_Store
17
+ .ruby-version
18
+
19
+ # rspec failure tracking
20
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,11 @@
1
+ ---
2
+ os: linux
3
+ dist: xenial
4
+ language: ruby
5
+ cache: bundler
6
+ rvm:
7
+ - '2.5'
8
+ - '2.6'
9
+ - '2.7'
10
+
11
+ before_install: gem install bundler -v 2.1.2
@@ -0,0 +1,2 @@
1
+ ## 0.1.0
2
+ - First release.
@@ -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
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in darts.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "rake-compiler"
8
+ gem "rspec", "~> 3.0"
@@ -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.
@@ -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).
@@ -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]
@@ -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,8 @@
1
+ #include "dartscloneext.hpp"
2
+
3
+ extern "C"
4
+ void Init_dartscloneext(void)
5
+ {
6
+ VALUE rb_mDarts = rb_define_module("DartsClone");
7
+ RbDoubleArray::define_class(rb_mDarts);
8
+ }
@@ -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 */