native_btree 0.2.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -3
- data/CMakeLists.txt +3 -3
- data/Gemfile +6 -3
- data/README.md +51 -3
- data/ext/native_btree/CMakeLists.txt +29 -7
- data/ext/native_btree/comparator.c +9 -0
- data/ext/native_btree/constructor.c +34 -7
- data/ext/native_btree/conversion.c +25 -1
- data/ext/native_btree/glib2_68/CMakeLists.txt +3 -0
- data/ext/native_btree/glib2_68/additional_iterators.c +84 -0
- data/ext/native_btree/glib_module.c +45 -0
- data/ext/native_btree/include/common.h +7 -9
- data/ext/native_btree/include/comparator.h +3 -0
- data/ext/native_btree/include/glib_module.h +6 -0
- data/ext/native_btree/include/iterators.h +10 -2
- data/ext/native_btree/include/native_btree.h +82 -5
- data/ext/native_btree/include/rbtree_type.h +10 -3
- data/ext/native_btree/instance.c +15 -3
- data/ext/native_btree/iterators.c +55 -1
- data/ext/native_btree/native_btree.c +55 -20
- data/ext/native_btree/rbtree_type.c +36 -10
- data/ext/native_btree/search.c +94 -0
- data/lib/native_btree/native_btree.bundle +0 -0
- data/lib/native_btree/version.rb +1 -1
- data/spec/debug.rb +20 -2
- data/spec/native_btree_class_spec.rb +16 -0
- data/spec/native_btree_conversion_spec.rb +70 -0
- data/spec/native_btree_instance_spec.rb +8 -101
- data/spec/native_btree_int_instance_spec.rb +188 -0
- data/spec/native_btree_iterators_spec.rb +90 -0
- data/spec/native_btree_module_spec.rb +20 -0
- data/spec/native_btree_search_spec.rb +210 -0
- metadata +12 -8
- data/ext/native_btree/Makefile +0 -456
- data/ext/native_btree/include/btree.h +0 -63
- data/ext/native_btree/include/constructor.h +0 -11
- data/ext/native_btree/include/conversion.h +0 -8
- data/ext/native_btree/include/instance.h +0 -22
- data/lib/native_btree/native_btree.so +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '05598705616620516787d5fd639f883270684c2d3981b1c04056bffd8f2b1849'
|
4
|
+
data.tar.gz: 1dcd3be4d1838e5b01bf7e38b2ca746004903550366f93e91922821feb3229ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98aa96b9820e879f94cc1f6682f9eb82f2139c7a81dd92f955db24167f9f8b384a80221b10ade4de7718c5fb56f94eea1f19fbb4360dc25c639bf1b4fd682230
|
7
|
+
data.tar.gz: f9410012b8ce525b4816377b8c8998e4ded903fca874e268a1a613a4759a5bf62051e4b55dec4259c15be5a301b1bb23978b0198b0e66d28c83e4f5f7954af1f
|
data/CHANGELOG.md
CHANGED
@@ -7,12 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
* delete_if()
|
11
|
+
* each method refactoring for Enumerator return type
|
12
|
+
|
13
|
+
## [0.4.0] - 2022-09-16
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
* Native integer comparator
|
18
|
+
* search_before()
|
19
|
+
* search_after()
|
20
|
+
* empty?()
|
21
|
+
|
22
|
+
### Changed
|
23
|
+
|
24
|
+
* Bugfixes
|
25
|
+
|
26
|
+
## [0.3.0] - 2022-09-11
|
27
|
+
|
28
|
+
### Added
|
29
|
+
|
30
|
+
* to_proc()
|
31
|
+
* empty?()
|
10
32
|
* filter()
|
11
33
|
* filter!()
|
12
|
-
* each_key()
|
13
|
-
* each_value()
|
14
34
|
* select()
|
15
|
-
* select!
|
35
|
+
* select!()
|
16
36
|
|
17
37
|
## [0.2.1] - 2022-09-08
|
18
38
|
|
data/CMakeLists.txt
CHANGED
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5)
|
|
2
2
|
|
3
3
|
project(ruby-native-btree
|
4
4
|
LANGUAGES C
|
5
|
-
VERSION 0.
|
5
|
+
VERSION 0.4.0)
|
6
6
|
|
7
7
|
include(CheckSymbolExists)
|
8
8
|
|
@@ -12,8 +12,8 @@ set(CMAKE_C_STANDARD 11)
|
|
12
12
|
set(CMAKE_C_EXTENSIONS ON)
|
13
13
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
14
14
|
|
15
|
-
set(CMAKE_C_FLAGS_DEBUG " -O0 -ggdb3 -Wall -Wextra -
|
16
|
-
set(CMAKE_C_FLAGS_RELEASE "-O3")
|
15
|
+
set(CMAKE_C_FLAGS_DEBUG " -O0 -ggdb3 -Wall -Wextra -Wno-unused-parameter")
|
16
|
+
set(CMAKE_C_FLAGS_RELEASE "-O3 -fomit-frame-pointer")
|
17
17
|
set(CMAKE_C_FLAGS "-pipe -march=native")
|
18
18
|
|
19
19
|
# Force -fPIC
|
data/Gemfile
CHANGED
@@ -9,10 +9,13 @@ group :development do
|
|
9
9
|
gem 'awesome_print', '~> 1.9'
|
10
10
|
gem 'debase', '~> 0.2', platforms: [:mri_26, :mri_27]
|
11
11
|
gem 'pry', '~> 0.14'
|
12
|
+
gem 'ruby-debug-ide', '~> 0.7'
|
13
|
+
gem 'solargraph', '~> 0.46'
|
14
|
+
end
|
15
|
+
|
16
|
+
group :test do
|
17
|
+
gem 'rspec', '~> 3.11.0'
|
12
18
|
gem 'rubocop', '~> 1.35.0'
|
13
19
|
gem 'rubocop-rake', '~> 0.6.0'
|
14
20
|
gem 'rubocop-rspec', '~> 2.12.1'
|
15
|
-
gem 'rspec', '~> 3.11.0'
|
16
|
-
gem 'ruby-debug-ide', '~> 0.7'
|
17
|
-
gem 'solargraph', '~> 0.46'
|
18
21
|
end
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ In most cases it will behave same as Hash, but keys will be ordered by passed co
|
|
11
11
|
|
12
12
|
## Requirements
|
13
13
|
|
14
|
-
* **CMake** build tool version **>= 3.14.0
|
14
|
+
* **CMake** build tool version **>= 3.5.0**, >= 3.14.0 will be cool.
|
15
15
|
* `pkg-config` tool
|
16
16
|
* **GLib** library
|
17
17
|
* On Ubuntu run:
|
@@ -29,6 +29,7 @@ In most cases it will behave same as Hash, but keys will be ordered by passed co
|
|
29
29
|
|
30
30
|
## Basic usage
|
31
31
|
|
32
|
+
### Example
|
32
33
|
```ruby
|
33
34
|
require 'native_btree'
|
34
35
|
|
@@ -53,19 +54,66 @@ tree.height
|
|
53
54
|
# 2
|
54
55
|
```
|
55
56
|
|
57
|
+
### Native int comparator
|
58
|
+
Will behave like an array with negative indexes)
|
59
|
+
```ruby
|
60
|
+
# Pass comparator for keys as block
|
61
|
+
tree = NativeBtree::Btree.new(NativeBtree::Btree::INT_COMPARATOR)
|
62
|
+
|
63
|
+
tree[-2] = 22
|
64
|
+
tree[-1] = 1
|
65
|
+
tree[0] = 100
|
66
|
+
tree[5] = 55
|
67
|
+
|
68
|
+
tree.to_a
|
69
|
+
|
70
|
+
#[
|
71
|
+
# [0] [
|
72
|
+
# [0] -2,
|
73
|
+
# [1] 22
|
74
|
+
# ],
|
75
|
+
# [1] [
|
76
|
+
# [0] -1,
|
77
|
+
# [1] 1
|
78
|
+
# ],
|
79
|
+
# [2] [
|
80
|
+
# [0] 0,
|
81
|
+
# [1] 100
|
82
|
+
# ],
|
83
|
+
# [3] [
|
84
|
+
# [0] 5,
|
85
|
+
# [1] 55
|
86
|
+
# ]
|
87
|
+
#]
|
88
|
+
```
|
89
|
+
|
56
90
|
## API ref
|
57
91
|
|
58
92
|
You must provide your own comparator for keys in `new` class method block.
|
59
93
|
|
60
|
-
###
|
94
|
+
### API methods
|
95
|
+
|
96
|
+
In general this class behave same as Hash
|
97
|
+
|
98
|
+
Implemented methods:
|
61
99
|
|
62
100
|
* `[]= (alias: set)`
|
63
101
|
* `[] (alias: get)`
|
64
102
|
* `delete`
|
65
103
|
* `size`
|
66
104
|
* `height`
|
67
|
-
* `each`
|
105
|
+
* `each` (NB! block is required) (NB! block is required)
|
68
106
|
* `include?`
|
69
107
|
* `clear`
|
70
108
|
* `to_h`
|
71
109
|
* `to_a`
|
110
|
+
* `to_proc`
|
111
|
+
* `filter` (alias: select)
|
112
|
+
* `filter!` (alias: select!)
|
113
|
+
* `each_value`
|
114
|
+
* `each_key`
|
115
|
+
* `search_before` (GLib version >= 2.68) - Select keys <= first arg, ret new Btree
|
116
|
+
* `search_after` (GLib version >= 2.68) - Select keys >= first arg, ret new Btree
|
117
|
+
* `empty?`
|
118
|
+
|
119
|
+
You can mix in the `Enumerable` module if additional methods are needed.
|
@@ -9,12 +9,22 @@ include_directories(include ${GLIB2_INCLUDE_DIRS})
|
|
9
9
|
|
10
10
|
list(APPEND CMAKE_REQUIRED_LIBRARIES ${GLIB2_LDFLAGS})
|
11
11
|
list(APPEND CMAKE_REQUIRED_INCLUDES ${GLIB2_INCLUDE_DIRS})
|
12
|
-
check_symbol_exists(g_tree_remove_all "glib.h"
|
12
|
+
check_symbol_exists(g_tree_remove_all "glib.h" HAS_GTREE_REMOVE_ALL)
|
13
|
+
check_symbol_exists(g_tree_lookup_node "glib.h" HAS_GTREE_NODE)
|
13
14
|
|
14
|
-
if(
|
15
|
-
add_compile_definitions(
|
15
|
+
if(HAS_GTREE_REMOVE_ALL)
|
16
|
+
add_compile_definitions(HAS_GTREE_REMOVE_ALL)
|
16
17
|
endif()
|
17
18
|
|
19
|
+
if(HAS_GTREE_NODE)
|
20
|
+
add_compile_definitions(HAS_GTREE_NODE)
|
21
|
+
add_subdirectory("glib2_68")
|
22
|
+
else()
|
23
|
+
message(WARNING
|
24
|
+
"Available GLib is not support direct node access.
|
25
|
+
Version < 2.68.
|
26
|
+
Additional iterators will not compile.")
|
27
|
+
endif()
|
18
28
|
|
19
29
|
add_library(${EXT_NAME}
|
20
30
|
SHARED
|
@@ -26,18 +36,30 @@ add_library(instance OBJECT instance.c)
|
|
26
36
|
add_library(comparator OBJECT comparator.c)
|
27
37
|
add_library(iterators OBJECT iterators.c)
|
28
38
|
add_library(conversion OBJECT conversion.c)
|
39
|
+
add_library(search OBJECT search.c)
|
40
|
+
add_library(glib_module OBJECT glib_module.c)
|
29
41
|
|
30
|
-
|
31
|
-
|
42
|
+
|
43
|
+
set(LIB_OBJECTS)
|
44
|
+
list(APPEND LIB_OBJECTS
|
32
45
|
$<TARGET_OBJECTS:conversion>
|
33
46
|
$<TARGET_OBJECTS:iterators>
|
34
47
|
$<TARGET_OBJECTS:comparator>
|
35
48
|
$<TARGET_OBJECTS:instance>
|
36
49
|
$<TARGET_OBJECTS:constructor>
|
37
|
-
$<TARGET_OBJECTS:rbtree_type>
|
50
|
+
$<TARGET_OBJECTS:rbtree_type>
|
51
|
+
$<TARGET_OBJECTS:search>
|
52
|
+
$<TARGET_OBJECTS:glib_module>)
|
53
|
+
|
54
|
+
if(HAS_GTREE_NODE)
|
55
|
+
list(APPEND LIB_OBJECTS $<TARGET_OBJECTS:additional_iterators>)
|
56
|
+
endif()
|
57
|
+
|
58
|
+
add_library(native_btree_interface
|
59
|
+
STATIC
|
60
|
+
${LIB_OBJECTS})
|
38
61
|
|
39
62
|
target_link_libraries(${EXT_NAME}
|
40
63
|
PRIVATE
|
41
64
|
native_btree_interface
|
42
65
|
${GLIB2_LDFLAGS})
|
43
|
-
|
@@ -11,3 +11,12 @@ rbtree_native_comparator(gconstpointer a, gconstpointer b, gpointer data)
|
|
11
11
|
|
12
12
|
return compare_result;
|
13
13
|
}
|
14
|
+
|
15
|
+
gint
|
16
|
+
rbtree_int_comparator(gconstpointer ra, gconstpointer rb, gpointer data)
|
17
|
+
{
|
18
|
+
gint a = NUM2INT((VALUE) ra);
|
19
|
+
gint b = NUM2INT((VALUE) rb);
|
20
|
+
|
21
|
+
return a - b;
|
22
|
+
}
|
@@ -1,19 +1,46 @@
|
|
1
|
-
#include <constructor.h>
|
2
1
|
#include <comparator.h>
|
3
2
|
#include <rbtree_type.h>
|
3
|
+
#include <stdbool.h>
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
inline static void
|
6
|
+
init_rbtree(RBTree *rbtree, gushort flags)
|
7
7
|
{
|
8
|
-
|
8
|
+
bool flag_int_comparator = flags & RBTREE_FLAG_INT_COMPARATOR;
|
9
|
+
VALUE comparator = Qnil;
|
10
|
+
// NOTE: Possible segfault
|
11
|
+
GCompareDataFunc native_comparator = NULL;
|
12
|
+
|
13
|
+
if (flag_int_comparator) {
|
14
|
+
native_comparator = rbtree_int_comparator;
|
15
|
+
}
|
16
|
+
else {
|
17
|
+
rb_need_block();
|
18
|
+
comparator = rb_block_proc();
|
19
|
+
native_comparator = rbtree_native_comparator;
|
20
|
+
}
|
9
21
|
|
10
22
|
rbtree->gtree = g_tree_new_with_data(
|
11
|
-
|
23
|
+
native_comparator,
|
12
24
|
rbtree
|
13
25
|
);
|
26
|
+
rbtree->comparator = comparator;
|
27
|
+
rbtree->flags = flags;
|
28
|
+
}
|
29
|
+
|
30
|
+
VALUE
|
31
|
+
rbtree_initialize(int argc, VALUE* argv, VALUE self)
|
32
|
+
{
|
33
|
+
rb_check_arity(argc, 0, 1);
|
34
|
+
|
35
|
+
EXTRACT_RBTREE_SELF(rbtree);
|
36
|
+
|
37
|
+
gushort flags = 0;
|
38
|
+
|
39
|
+
if (argc > 0) {
|
40
|
+
flags = NUM2USHORT(argv[0]);
|
41
|
+
}
|
14
42
|
|
15
|
-
|
16
|
-
rbtree->comparator = rb_block_proc();
|
43
|
+
init_rbtree((RBTree *) rbtree, flags);
|
17
44
|
|
18
45
|
return self;
|
19
46
|
}
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#include <
|
1
|
+
#include <common.h>
|
2
|
+
|
2
3
|
|
3
4
|
static gboolean
|
4
5
|
rbtree_to_h_callback(gpointer key, gpointer value, gpointer data)
|
@@ -52,3 +53,26 @@ rbtree_to_a(VALUE self)
|
|
52
53
|
|
53
54
|
return array;
|
54
55
|
}
|
56
|
+
|
57
|
+
|
58
|
+
static VALUE
|
59
|
+
to_proc_proc(RB_BLOCK_CALL_FUNC_ARGLIST(key, callback_arg))
|
60
|
+
{
|
61
|
+
rb_check_arity(argc, 1, 1);
|
62
|
+
EXTRACT_RBTREE(callback_arg, rbtree);
|
63
|
+
|
64
|
+
VALUE value = (VALUE) g_tree_lookup(rbtree->gtree, (gconstpointer) key);
|
65
|
+
|
66
|
+
if (!value) {
|
67
|
+
return Qnil;
|
68
|
+
}
|
69
|
+
|
70
|
+
return value;
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
VALUE
|
75
|
+
rbtree_to_proc(VALUE self)
|
76
|
+
{
|
77
|
+
return rb_proc_new(to_proc_proc, self);
|
78
|
+
}
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#include <native_btree.h>
|
2
|
+
#include <iterators.h>
|
3
|
+
|
4
|
+
static void
|
5
|
+
rbtree_gtree_foreach(GTreeNode *node, RBTreeStepFunction step_func, GTraverseFunc callback, gpointer data)
|
6
|
+
{
|
7
|
+
while (node) {
|
8
|
+
callback(
|
9
|
+
g_tree_node_key(node),
|
10
|
+
g_tree_node_value(node),
|
11
|
+
data
|
12
|
+
);
|
13
|
+
|
14
|
+
node = step_func(node);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
|
19
|
+
static int
|
20
|
+
rbtree_traverse_insert(gpointer key, gpointer value, gpointer tree)
|
21
|
+
{
|
22
|
+
g_tree_insert(tree, key, value);
|
23
|
+
|
24
|
+
return FALSE;
|
25
|
+
}
|
26
|
+
|
27
|
+
|
28
|
+
VALUE
|
29
|
+
rbtree_select_before(VALUE self, VALUE target)
|
30
|
+
{
|
31
|
+
EXTRACT_RBTREE_SELF(rbtree);
|
32
|
+
|
33
|
+
VALUE new_tree = rbtree_clone_wrap(rbtree);
|
34
|
+
|
35
|
+
EXTRACT_RBTREE(new_tree, new_rbtree);
|
36
|
+
|
37
|
+
GTreeNode *target_node = g_tree_upper_bound(
|
38
|
+
rbtree->gtree,
|
39
|
+
(gconstpointer) target
|
40
|
+
);
|
41
|
+
|
42
|
+
target_node = g_tree_node_previous(target_node);
|
43
|
+
|
44
|
+
if (!target_node) {
|
45
|
+
return new_tree;
|
46
|
+
}
|
47
|
+
|
48
|
+
rbtree_gtree_foreach(
|
49
|
+
target_node,
|
50
|
+
g_tree_node_previous,
|
51
|
+
rbtree_traverse_insert,
|
52
|
+
(gpointer) new_rbtree->gtree
|
53
|
+
);
|
54
|
+
|
55
|
+
return new_tree;
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
VALUE
|
60
|
+
rbtree_select_after(VALUE self, VALUE target)
|
61
|
+
{
|
62
|
+
EXTRACT_RBTREE_SELF(rbtree);
|
63
|
+
|
64
|
+
VALUE new_tree = rbtree_clone_wrap(rbtree);
|
65
|
+
EXTRACT_RBTREE(new_tree, new_rbtree);
|
66
|
+
|
67
|
+
GTreeNode *target_node = g_tree_lower_bound(
|
68
|
+
rbtree->gtree,
|
69
|
+
(gconstpointer) target
|
70
|
+
);
|
71
|
+
|
72
|
+
if (!target_node) {
|
73
|
+
return new_tree;
|
74
|
+
}
|
75
|
+
|
76
|
+
rbtree_gtree_foreach(
|
77
|
+
target_node,
|
78
|
+
g_tree_node_next,
|
79
|
+
rbtree_traverse_insert,
|
80
|
+
(gpointer) new_rbtree->gtree
|
81
|
+
);
|
82
|
+
|
83
|
+
return new_tree;
|
84
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#include <stdbool.h>
|
2
|
+
#include <common.h>
|
3
|
+
#include <glib_module.h>
|
4
|
+
|
5
|
+
#define NATIVE_BTREE_GLIB_SUBMODULE "Glib"
|
6
|
+
#define GLIB_MODULE_MAJOR_VERSION "MAJOR_VERSION"
|
7
|
+
#define GLIB_MODULE_MINOR_VERSION "MINOR_VERSION"
|
8
|
+
#define GLIB_MODULE_MICRO_VERSION "MICRO_VERSION"
|
9
|
+
|
10
|
+
VALUE rbtree_glib_module;
|
11
|
+
|
12
|
+
void
|
13
|
+
rbtree_attach_module_glib()
|
14
|
+
{
|
15
|
+
static bool initialized = FALSE;
|
16
|
+
|
17
|
+
if (initialized) {
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
|
21
|
+
rbtree_glib_module = rb_define_module_under(
|
22
|
+
native_btree_module,
|
23
|
+
NATIVE_BTREE_GLIB_SUBMODULE
|
24
|
+
);
|
25
|
+
|
26
|
+
rb_define_const(
|
27
|
+
rbtree_glib_module,
|
28
|
+
GLIB_MODULE_MAJOR_VERSION,
|
29
|
+
INT2NUM(GLIB_MAJOR_VERSION)
|
30
|
+
);
|
31
|
+
|
32
|
+
rb_define_const(
|
33
|
+
rbtree_glib_module,
|
34
|
+
GLIB_MODULE_MINOR_VERSION,
|
35
|
+
INT2NUM(GLIB_MINOR_VERSION)
|
36
|
+
);
|
37
|
+
|
38
|
+
rb_define_const(
|
39
|
+
rbtree_glib_module,
|
40
|
+
GLIB_MODULE_MICRO_VERSION,
|
41
|
+
INT2NUM(GLIB_MICRO_VERSION)
|
42
|
+
);
|
43
|
+
|
44
|
+
initialized = TRUE;
|
45
|
+
}
|
@@ -1,21 +1,19 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <glib.h>
|
3
|
+
#include <rbtree_type.h>
|
4
|
+
#include <native_btree.h>
|
5
|
+
|
3
6
|
|
4
7
|
#ifndef _NATIVE_BTREE_COMMON_
|
5
8
|
#define _NATIVE_BTREE_COMMON_
|
6
9
|
|
7
|
-
#include <rbtree_type.h>
|
8
|
-
|
9
|
-
#define NATIVE_BTREE_MODULE "NativeBtree"
|
10
|
-
#define NATIVE_BTREE_CLASS "Btree"
|
11
|
-
|
12
10
|
#define EXTRACT_RBTREE(from, to) \
|
13
|
-
RBTree *to;
|
14
|
-
TypedData_Get_Struct(from, RBTree, &rbtree_type,
|
11
|
+
const RBTree *to; \
|
12
|
+
TypedData_Get_Struct(from, RBTree, &rbtree_type, to)
|
15
13
|
|
16
14
|
#define EXTRACT_RBTREE_SELF(to) EXTRACT_RBTREE(self, to)
|
17
15
|
|
18
|
-
extern VALUE
|
19
|
-
extern VALUE
|
16
|
+
extern VALUE native_btree_class;
|
17
|
+
extern VALUE native_btree_module;
|
20
18
|
|
21
19
|
#endif //_NATIVE_BTREE_COMMON_
|
@@ -1,5 +1,13 @@
|
|
1
1
|
#include <common.h>
|
2
2
|
|
3
|
+
typedef struct {
|
4
|
+
const VALUE block;
|
5
|
+
const RBTree *tree;
|
6
|
+
gconstpointer something;
|
7
|
+
} RBTreeSearchData;
|
3
8
|
|
4
|
-
|
5
|
-
|
9
|
+
#ifdef HAS_GTREE_NODE
|
10
|
+
|
11
|
+
typedef GTreeNode *(RBTreeStepFunction) (GTreeNode *node);
|
12
|
+
|
13
|
+
#endif
|
@@ -1,9 +1,86 @@
|
|
1
1
|
#ifndef _NATIVE_BTREE_
|
2
2
|
|
3
|
-
#include <
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
#include <ruby.h>
|
4
|
+
|
5
|
+
VALUE
|
6
|
+
rbtree_initialize(int argc, VALUE *argv, VALUE self);
|
7
|
+
|
8
|
+
VALUE
|
9
|
+
rbtree_set(VALUE self, VALUE key, VALUE value);
|
10
|
+
|
11
|
+
VALUE
|
12
|
+
rbtree_get(VALUE self, VALUE key);
|
13
|
+
|
14
|
+
VALUE
|
15
|
+
rbtree_delete(VALUE self, VALUE key);
|
16
|
+
|
17
|
+
VALUE
|
18
|
+
rbtree_size(VALUE self);
|
19
|
+
|
20
|
+
VALUE
|
21
|
+
rbtree_height(VALUE self);
|
22
|
+
|
23
|
+
VALUE
|
24
|
+
rbtree_clear(VALUE self);
|
25
|
+
|
26
|
+
VALUE
|
27
|
+
rbtree_is_include(VALUE self, VALUE key);
|
28
|
+
|
29
|
+
VALUE
|
30
|
+
rbtree_each(VALUE self);
|
31
|
+
|
32
|
+
VALUE
|
33
|
+
rbtree_each_key(VALUE self);
|
34
|
+
|
35
|
+
VALUE
|
36
|
+
rbtree_each_value(VALUE self);
|
37
|
+
|
38
|
+
VALUE
|
39
|
+
rbtree_to_h(VALUE self);
|
40
|
+
|
41
|
+
VALUE
|
42
|
+
rbtree_to_a(VALUE self);
|
43
|
+
|
44
|
+
VALUE
|
45
|
+
rbtree_to_proc(VALUE self);
|
46
|
+
|
47
|
+
VALUE
|
48
|
+
rbtree_filter(VALUE self);
|
49
|
+
|
50
|
+
VALUE
|
51
|
+
rbtree_filter_bang(VALUE self);
|
52
|
+
|
53
|
+
VALUE
|
54
|
+
rbtree_is_empty(VALUE self);
|
55
|
+
|
56
|
+
VALUE
|
57
|
+
rbtree_select_before(VALUE self, VALUE target);
|
58
|
+
|
59
|
+
VALUE
|
60
|
+
rbtree_select_after(VALUE self, VALUE target);
|
61
|
+
|
62
|
+
VALUE
|
63
|
+
rbtree_select_between(VALUE self, VALUE from, VALUE to);
|
64
|
+
|
65
|
+
VALUE
|
66
|
+
rbtree_flatten(VALUE self);
|
67
|
+
|
68
|
+
VALUE
|
69
|
+
rbtree_delete_if(VALUE self);
|
70
|
+
|
71
|
+
VALUE
|
72
|
+
rbtree_has_key(VALUE self, VALUE key);
|
73
|
+
|
74
|
+
VALUE
|
75
|
+
rbtree_has_value(VALUE self, VALUE value);
|
76
|
+
|
77
|
+
VALUE
|
78
|
+
rbtree_eql(VALUE self, VALUE tree);
|
79
|
+
|
80
|
+
VALUE
|
81
|
+
rbtree_keys(VALUE self);
|
82
|
+
|
83
|
+
VALUE
|
84
|
+
rbtree_values(VALUE self);
|
8
85
|
|
9
86
|
#endif // _NATIVE_BTREE_
|
@@ -3,20 +3,27 @@
|
|
3
3
|
|
4
4
|
#include <common.h>
|
5
5
|
|
6
|
-
#define
|
6
|
+
#define RBTREE_NATIVE_TYPE_NAME "native_btree"
|
7
|
+
#define RBTREE_FLAG_INT_COMPARATOR 0b10000000
|
7
8
|
|
8
9
|
extern const rb_data_type_t rbtree_type;
|
9
10
|
|
11
|
+
typedef struct _RBTree RBTree;
|
12
|
+
|
10
13
|
VALUE
|
11
14
|
rbtree_alloc(VALUE self);
|
12
15
|
|
16
|
+
VALUE
|
17
|
+
rbtree_clone_wrap(const RBTree *orig);
|
18
|
+
|
13
19
|
/**
|
14
20
|
* Internal native instance
|
15
21
|
*/
|
16
|
-
|
22
|
+
struct _RBTree
|
17
23
|
{
|
18
24
|
GTree *gtree;
|
19
25
|
VALUE comparator;
|
20
|
-
|
26
|
+
gushort flags;
|
27
|
+
};
|
21
28
|
|
22
29
|
#endif //_RBTREE_TYPE_
|
data/ext/native_btree/instance.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
#include <
|
1
|
+
#include <common.h>
|
2
2
|
|
3
|
-
|
3
|
+
|
4
|
+
#ifndef HAS_GTREE_REMOVE_ALL
|
4
5
|
|
5
6
|
static gboolean
|
6
7
|
rbtree_remove_node(gpointer key, gpointer val, gpointer data) {
|
@@ -101,7 +102,7 @@ rbtree_clear(VALUE self)
|
|
101
102
|
{
|
102
103
|
EXTRACT_RBTREE_SELF(rbtree);
|
103
104
|
|
104
|
-
#ifdef
|
105
|
+
#ifdef HAS_GTREE_REMOVE_ALL
|
105
106
|
g_tree_remove_all(rbtree->gtree);
|
106
107
|
#else
|
107
108
|
g_tree_foreach(rbtree->gtree, rbtree_remove_node, (gpointer) rbtree);
|
@@ -124,3 +125,14 @@ rbtree_is_include(VALUE self, VALUE key)
|
|
124
125
|
|
125
126
|
return Qtrue;
|
126
127
|
}
|
128
|
+
|
129
|
+
|
130
|
+
VALUE
|
131
|
+
rbtree_is_empty(VALUE self)
|
132
|
+
{
|
133
|
+
EXTRACT_RBTREE_SELF(rbtree);
|
134
|
+
|
135
|
+
gint size = g_tree_nnodes(rbtree->gtree);
|
136
|
+
|
137
|
+
return size > 0 ? Qfalse : Qtrue;
|
138
|
+
}
|