native_btree 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/CMakeLists.txt +3 -3
- data/README.md +41 -2
- data/ext/native_btree/CMakeLists.txt +27 -7
- data/ext/native_btree/comparator.c +9 -0
- data/ext/native_btree/constructor.c +34 -6
- 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 +1 -1
- 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 +8 -2
- data/ext/native_btree/include/native_btree.h +37 -1
- data/ext/native_btree/include/rbtree_type.h +9 -2
- data/ext/native_btree/instance.c +2 -2
- data/ext/native_btree/iterators.c +54 -0
- data/ext/native_btree/native_btree.c +20 -2
- data/ext/native_btree/rbtree_type.c +29 -3
- data/ext/native_btree/search.c +1 -8
- data/lib/native_btree/native_btree.bundle +0 -0
- data/lib/native_btree/version.rb +1 -1
- data/spec/debug.rb +12 -3
- data/spec/native_btree_class_spec.rb +16 -0
- data/spec/native_btree_int_instance_spec.rb +188 -0
- data/spec/native_btree_iterators_spec.rb +32 -4
- data/spec/native_btree_module_spec.rb +20 -0
- data/spec/native_btree_search_spec.rb +94 -2
- metadata +7 -2
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
@@ -10,6 +10,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
10
10
|
* delete_if()
|
11
11
|
* each method refactoring for Enumerator return type
|
12
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
|
+
|
13
26
|
## [0.3.0] - 2022-09-11
|
14
27
|
|
15
28
|
### Added
|
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/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,6 +54,39 @@ 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.
|
@@ -68,7 +102,7 @@ Implemented methods:
|
|
68
102
|
* `delete`
|
69
103
|
* `size`
|
70
104
|
* `height`
|
71
|
-
* `each` (NB! block is required)
|
105
|
+
* `each` (NB! block is required) (NB! block is required)
|
72
106
|
* `include?`
|
73
107
|
* `clear`
|
74
108
|
* `to_h`
|
@@ -76,5 +110,10 @@ Implemented methods:
|
|
76
110
|
* `to_proc`
|
77
111
|
* `filter` (alias: select)
|
78
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?`
|
79
118
|
|
80
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
|
@@ -27,19 +37,29 @@ add_library(comparator OBJECT comparator.c)
|
|
27
37
|
add_library(iterators OBJECT iterators.c)
|
28
38
|
add_library(conversion OBJECT conversion.c)
|
29
39
|
add_library(search OBJECT search.c)
|
40
|
+
add_library(glib_module OBJECT glib_module.c)
|
30
41
|
|
31
|
-
|
32
|
-
|
42
|
+
|
43
|
+
set(LIB_OBJECTS)
|
44
|
+
list(APPEND LIB_OBJECTS
|
33
45
|
$<TARGET_OBJECTS:conversion>
|
34
46
|
$<TARGET_OBJECTS:iterators>
|
35
47
|
$<TARGET_OBJECTS:comparator>
|
36
48
|
$<TARGET_OBJECTS:instance>
|
37
49
|
$<TARGET_OBJECTS:constructor>
|
38
50
|
$<TARGET_OBJECTS:rbtree_type>
|
39
|
-
$<TARGET_OBJECTS:search>
|
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})
|
40
61
|
|
41
62
|
target_link_libraries(${EXT_NAME}
|
42
63
|
PRIVATE
|
43
64
|
native_btree_interface
|
44
65
|
${GLIB2_LDFLAGS})
|
45
|
-
|
@@ -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,18 +1,46 @@
|
|
1
1
|
#include <comparator.h>
|
2
2
|
#include <rbtree_type.h>
|
3
|
+
#include <stdbool.h>
|
3
4
|
|
4
|
-
|
5
|
-
|
5
|
+
inline static void
|
6
|
+
init_rbtree(RBTree *rbtree, gushort flags)
|
6
7
|
{
|
7
|
-
|
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
|
+
}
|
8
21
|
|
9
22
|
rbtree->gtree = g_tree_new_with_data(
|
10
|
-
|
23
|
+
native_comparator,
|
11
24
|
rbtree
|
12
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
|
+
}
|
13
42
|
|
14
|
-
|
15
|
-
rbtree->comparator = rb_block_proc();
|
43
|
+
init_rbtree((RBTree *) rbtree, flags);
|
16
44
|
|
17
45
|
return self;
|
18
46
|
}
|
@@ -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,7 +1,13 @@
|
|
1
1
|
#include <common.h>
|
2
2
|
|
3
3
|
typedef struct {
|
4
|
-
VALUE block;
|
5
|
-
RBTree *tree;
|
4
|
+
const VALUE block;
|
5
|
+
const RBTree *tree;
|
6
6
|
gconstpointer something;
|
7
7
|
} RBTreeSearchData;
|
8
|
+
|
9
|
+
#ifdef HAS_GTREE_NODE
|
10
|
+
|
11
|
+
typedef GTreeNode *(RBTreeStepFunction) (GTreeNode *node);
|
12
|
+
|
13
|
+
#endif
|
@@ -3,7 +3,7 @@
|
|
3
3
|
#include <ruby.h>
|
4
4
|
|
5
5
|
VALUE
|
6
|
-
rbtree_initialize(VALUE self);
|
6
|
+
rbtree_initialize(int argc, VALUE *argv, VALUE self);
|
7
7
|
|
8
8
|
VALUE
|
9
9
|
rbtree_set(VALUE self, VALUE key, VALUE value);
|
@@ -29,6 +29,12 @@ rbtree_is_include(VALUE self, VALUE key);
|
|
29
29
|
VALUE
|
30
30
|
rbtree_each(VALUE self);
|
31
31
|
|
32
|
+
VALUE
|
33
|
+
rbtree_each_key(VALUE self);
|
34
|
+
|
35
|
+
VALUE
|
36
|
+
rbtree_each_value(VALUE self);
|
37
|
+
|
32
38
|
VALUE
|
33
39
|
rbtree_to_h(VALUE self);
|
34
40
|
|
@@ -47,4 +53,34 @@ rbtree_filter_bang(VALUE self);
|
|
47
53
|
VALUE
|
48
54
|
rbtree_is_empty(VALUE self);
|
49
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);
|
85
|
+
|
50
86
|
#endif // _NATIVE_BTREE_
|
@@ -4,19 +4,26 @@
|
|
4
4
|
#include <common.h>
|
5
5
|
|
6
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,7 +1,7 @@
|
|
1
1
|
#include <common.h>
|
2
2
|
|
3
3
|
|
4
|
-
#ifndef
|
4
|
+
#ifndef HAS_GTREE_REMOVE_ALL
|
5
5
|
|
6
6
|
static gboolean
|
7
7
|
rbtree_remove_node(gpointer key, gpointer val, gpointer data) {
|
@@ -102,7 +102,7 @@ rbtree_clear(VALUE self)
|
|
102
102
|
{
|
103
103
|
EXTRACT_RBTREE_SELF(rbtree);
|
104
104
|
|
105
|
-
#ifdef
|
105
|
+
#ifdef HAS_GTREE_REMOVE_ALL
|
106
106
|
g_tree_remove_all(rbtree->gtree);
|
107
107
|
#else
|
108
108
|
g_tree_foreach(rbtree->gtree, rbtree_remove_node, (gpointer) rbtree);
|
@@ -1,5 +1,6 @@
|
|
1
1
|
#include <common.h>
|
2
2
|
|
3
|
+
|
3
4
|
static gboolean
|
4
5
|
foraech_callbac(gpointer a, gpointer b, gpointer data)
|
5
6
|
{
|
@@ -12,6 +13,31 @@ foraech_callbac(gpointer a, gpointer b, gpointer data)
|
|
12
13
|
return FALSE;
|
13
14
|
}
|
14
15
|
|
16
|
+
|
17
|
+
static gboolean
|
18
|
+
foraech_key_callbac(gpointer a, gpointer b, gpointer data)
|
19
|
+
{
|
20
|
+
VALUE key = (VALUE) a;
|
21
|
+
VALUE block = (VALUE) data;
|
22
|
+
|
23
|
+
rb_funcall(block, rb_intern("call"), 1, key);
|
24
|
+
|
25
|
+
return FALSE;
|
26
|
+
}
|
27
|
+
|
28
|
+
|
29
|
+
static gboolean
|
30
|
+
foraech_value_callbac(gpointer a, gpointer b, gpointer data)
|
31
|
+
{
|
32
|
+
VALUE value = (VALUE) b;
|
33
|
+
VALUE block = (VALUE) data;
|
34
|
+
|
35
|
+
rb_funcall(block, rb_intern("call"), 1, value);
|
36
|
+
|
37
|
+
return FALSE;
|
38
|
+
}
|
39
|
+
|
40
|
+
|
15
41
|
VALUE
|
16
42
|
rbtree_each(VALUE self)
|
17
43
|
{
|
@@ -24,3 +50,31 @@ rbtree_each(VALUE self)
|
|
24
50
|
|
25
51
|
return self;
|
26
52
|
}
|
53
|
+
|
54
|
+
|
55
|
+
VALUE
|
56
|
+
rbtree_each_key(VALUE self)
|
57
|
+
{
|
58
|
+
rb_need_block();
|
59
|
+
VALUE block = rb_block_proc();
|
60
|
+
|
61
|
+
EXTRACT_RBTREE_SELF(rbtree);
|
62
|
+
|
63
|
+
g_tree_foreach(rbtree->gtree, foraech_key_callbac, (gpointer) block);
|
64
|
+
|
65
|
+
return self;
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
VALUE
|
70
|
+
rbtree_each_value(VALUE self)
|
71
|
+
{
|
72
|
+
rb_need_block();
|
73
|
+
VALUE block = rb_block_proc();
|
74
|
+
|
75
|
+
EXTRACT_RBTREE_SELF(rbtree);
|
76
|
+
|
77
|
+
g_tree_foreach(rbtree->gtree, foraech_value_callbac, (gpointer) block);
|
78
|
+
|
79
|
+
return self;
|
80
|
+
}
|
@@ -1,14 +1,15 @@
|
|
1
1
|
#include <native_btree.h>
|
2
2
|
#include <rbtree_type.h>
|
3
|
+
#include <glib_module.h>
|
3
4
|
|
4
5
|
#define NATIVE_BTREE_MODULE "NativeBtree"
|
5
6
|
#define NATIVE_BTREE_CLASS "Btree"
|
7
|
+
#define NATIVE_BTREE_CONST_INT_COMPARATOR "INT_COMPARATOR"
|
6
8
|
|
7
9
|
|
8
10
|
VALUE native_btree_class;
|
9
11
|
VALUE native_btree_module;
|
10
12
|
|
11
|
-
|
12
13
|
void
|
13
14
|
Init_native_btree()
|
14
15
|
{
|
@@ -19,10 +20,20 @@ Init_native_btree()
|
|
19
20
|
rb_cObject
|
20
21
|
);
|
21
22
|
|
23
|
+
VALUE int_comparator = USHORT2NUM(RBTREE_FLAG_INT_COMPARATOR);
|
24
|
+
OBJ_FREEZE(int_comparator);
|
25
|
+
rb_define_const(
|
26
|
+
native_btree_class,
|
27
|
+
NATIVE_BTREE_CONST_INT_COMPARATOR,
|
28
|
+
int_comparator
|
29
|
+
);
|
30
|
+
|
31
|
+
rbtree_attach_module_glib();
|
32
|
+
|
22
33
|
// rb_include_module(native_btree_class, rb_mEnumerable);
|
23
34
|
|
24
35
|
rb_define_alloc_func(native_btree_class, rbtree_alloc);
|
25
|
-
rb_define_method(native_btree_class, "initialize", rbtree_initialize,
|
36
|
+
rb_define_method(native_btree_class, "initialize", rbtree_initialize, -1);
|
26
37
|
|
27
38
|
rb_define_method(native_btree_class, "[]=", rbtree_set, 2);
|
28
39
|
rb_define_alias(native_btree_class, "set", "[]=");
|
@@ -30,6 +41,8 @@ Init_native_btree()
|
|
30
41
|
rb_define_alias(native_btree_class, "get", "[]");
|
31
42
|
rb_define_method(native_btree_class, "delete", rbtree_delete, 1);
|
32
43
|
rb_define_method(native_btree_class, "each", rbtree_each, 0);
|
44
|
+
rb_define_method(native_btree_class, "each_key", rbtree_each_key, 0);
|
45
|
+
rb_define_method(native_btree_class, "each_value", rbtree_each_value, 0);
|
33
46
|
rb_define_method(native_btree_class, "size", rbtree_size, 0);
|
34
47
|
rb_define_method(native_btree_class, "height", rbtree_height, 0);
|
35
48
|
rb_define_method(native_btree_class, "clear", rbtree_clear, 0);
|
@@ -42,4 +55,9 @@ Init_native_btree()
|
|
42
55
|
rb_define_method(native_btree_class, "filter!", rbtree_filter_bang, 0);
|
43
56
|
rb_define_alias(native_btree_class, "select!", "filter!");
|
44
57
|
rb_define_method(native_btree_class, "empty?", rbtree_is_empty, 0);
|
58
|
+
|
59
|
+
#ifdef HAS_GTREE_NODE
|
60
|
+
rb_define_method(native_btree_class, "select_before", rbtree_select_before, 1);
|
61
|
+
rb_define_method(native_btree_class, "select_after", rbtree_select_after, 1);
|
62
|
+
#endif
|
45
63
|
}
|
@@ -8,7 +8,10 @@ rbtree_type_free(gpointer data)
|
|
8
8
|
{
|
9
9
|
RBTree *rbtree = (RBTree *) data;
|
10
10
|
|
11
|
-
|
11
|
+
if (rbtree->gtree) {
|
12
|
+
g_tree_destroy(rbtree->gtree);
|
13
|
+
}
|
14
|
+
|
12
15
|
g_free(data);
|
13
16
|
}
|
14
17
|
|
@@ -26,9 +29,11 @@ rbtree_mark_callback(gpointer key, gpointer value, gpointer data)
|
|
26
29
|
static void
|
27
30
|
rbtree_type_mark(gpointer data)
|
28
31
|
{
|
29
|
-
RBTree *rbtree = (RBTree *)data;
|
32
|
+
RBTree *rbtree = (RBTree *) data;
|
30
33
|
|
31
|
-
|
34
|
+
if (!NIL_P(rbtree->comparator)) {
|
35
|
+
rb_gc_mark(rbtree->comparator);
|
36
|
+
}
|
32
37
|
|
33
38
|
g_tree_foreach(rbtree->gtree, rbtree_mark_callback, NULL);
|
34
39
|
}
|
@@ -98,5 +103,26 @@ rbtree_alloc(VALUE self)
|
|
98
103
|
{
|
99
104
|
RBTree *rbtree = g_new(RBTree, 1);
|
100
105
|
|
106
|
+
rbtree->gtree = NULL;
|
107
|
+
rbtree->comparator = Qnil;
|
108
|
+
rbtree->flags = 0;
|
109
|
+
|
101
110
|
return TypedData_Wrap_Struct(self, &rbtree_type, rbtree);
|
102
111
|
}
|
112
|
+
|
113
|
+
|
114
|
+
VALUE
|
115
|
+
rbtree_clone_wrap(const RBTree *orig)
|
116
|
+
{
|
117
|
+
const VALUE rflags = USHORT2NUM(orig->flags);
|
118
|
+
|
119
|
+
VALUE new_tree = rb_funcall_with_block(
|
120
|
+
native_btree_class,
|
121
|
+
rb_intern("new"),
|
122
|
+
orig->flags ? 1 : 0,
|
123
|
+
orig->flags ? &rflags : NULL,
|
124
|
+
orig->comparator
|
125
|
+
);
|
126
|
+
|
127
|
+
return new_tree;
|
128
|
+
}
|
data/ext/native_btree/search.c
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#include <iterators.h>
|
2
2
|
|
3
|
-
VALUE native_btree_class;
|
4
3
|
|
5
4
|
static gboolean
|
6
5
|
filter_callback(gpointer a, gpointer b, gpointer data)
|
@@ -52,13 +51,7 @@ rbtree_filter(VALUE self)
|
|
52
51
|
|
53
52
|
VALUE block = rb_block_proc();
|
54
53
|
|
55
|
-
VALUE new_tree =
|
56
|
-
native_btree_class,
|
57
|
-
rb_intern("new"),
|
58
|
-
0,
|
59
|
-
NULL,
|
60
|
-
rbtree->comparator
|
61
|
-
);
|
54
|
+
VALUE new_tree = rbtree_clone_wrap(rbtree);
|
62
55
|
|
63
56
|
EXTRACT_RBTREE(new_tree, new_rbtree);
|
64
57
|
|
Binary file
|
data/lib/native_btree/version.rb
CHANGED
data/spec/debug.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "../lib/native_btree/native_btree"
|
4
4
|
|
5
|
-
tree = NativeBtree::Btree.new {
|
5
|
+
tree = NativeBtree::Btree.new() {|a, b| a - b }
|
6
6
|
|
7
7
|
GC.start
|
8
8
|
|
@@ -24,10 +24,19 @@ puts tree.to_h
|
|
24
24
|
pr = tree.to_proc
|
25
25
|
|
26
26
|
puts pr
|
27
|
-
puts pr.call(10)
|
28
|
-
puts pr.call(16)
|
29
27
|
|
30
28
|
|
29
|
+
tree.clear
|
30
|
+
tree[1] = 15
|
31
|
+
tree[2] = 22
|
32
|
+
tree[3] = 33
|
33
|
+
tree[4] = 44
|
34
|
+
tree[5] = 55
|
35
|
+
tree[6] = 66
|
36
|
+
tree[7] = 77
|
37
|
+
|
38
|
+
puts tree.select_after(4).to_h
|
39
|
+
|
31
40
|
GC.start
|
32
41
|
|
33
42
|
puts "exit 0"
|
@@ -19,6 +19,22 @@ RSpec.describe NativeBtree do
|
|
19
19
|
it "raise error if block is not given" do
|
20
20
|
expect { described_class.new() }.to raise_error(LocalJumpError)
|
21
21
|
end
|
22
|
+
|
23
|
+
it 'return new btree with int comparator' do
|
24
|
+
expect(described_class.new(described_class::INT_COMPARATOR))
|
25
|
+
.to be_kind_of(described_class)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "constants" do
|
31
|
+
it 'has const INT_COMPARATOR' do
|
32
|
+
expect(described_class.const_defined?(:INT_COMPARATOR)).to be true
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'const INT_COMPARATOR is 1' do
|
36
|
+
expect(described_class::INT_COMPARATOR).to be 128
|
37
|
+
end
|
22
38
|
end
|
23
39
|
end
|
24
40
|
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe NativeBtree do
|
4
|
+
|
5
|
+
describe NativeBtree::Btree do
|
6
|
+
let(:tree) do
|
7
|
+
described_class.new(described_class::INT_COMPARATOR)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#[]= method" do
|
11
|
+
|
12
|
+
it "respond to" do
|
13
|
+
expect(tree).to respond_to('[]=')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'set key/value pair' do
|
17
|
+
tree[2] = 22
|
18
|
+
expect(tree[2]).to be 22
|
19
|
+
end
|
20
|
+
|
21
|
+
it "pass key arg and value" do
|
22
|
+
expect(tree[:key] = 10).to be 10
|
23
|
+
end
|
24
|
+
|
25
|
+
it "Raise ArgumentError if key was not passed" do
|
26
|
+
expect { tree[] = 1 }.to raise_error(ArgumentError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'Call comparator while set value' do
|
30
|
+
comparator = spy('comparator')
|
31
|
+
def comparator.to_proc
|
32
|
+
proc do |a, b|
|
33
|
+
comparator.call()
|
34
|
+
a - b
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
btree = described_class.new(&comparator)
|
39
|
+
btree[1] = 1
|
40
|
+
btree[2] = 2
|
41
|
+
expect(comparator).to have_received(:call)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'has a set alias' do
|
45
|
+
expect(tree).to respond_to('set')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#[] method" do
|
50
|
+
it "respond to" do
|
51
|
+
expect(tree).to respond_to('[]')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'return expected value if found' do
|
55
|
+
tree[3] = 'a'
|
56
|
+
tree[4] = 'b'
|
57
|
+
expect(tree[3]).to be 'a'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'return nil if not found' do
|
61
|
+
tree[1] = '1'
|
62
|
+
tree[5] = '5'
|
63
|
+
expect(tree[2]).to be_nil
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'has a get alias' do
|
67
|
+
expect(tree).to respond_to('get')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#height method" do
|
72
|
+
it "respond to" do
|
73
|
+
expect(tree).to respond_to(:height)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'return tree height with items' do
|
77
|
+
tree[1] = 11
|
78
|
+
tree[2] = 22
|
79
|
+
tree[3] = 33
|
80
|
+
tree[4] = 44
|
81
|
+
expect(tree.height).to be 3
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'return 0 if empty tree' do
|
85
|
+
expect(tree.height).to be 0
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#size method" do
|
90
|
+
it "respond to" do
|
91
|
+
expect(tree).to respond_to(:size)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'return count of nodes' do
|
95
|
+
tree[1] = 1
|
96
|
+
tree[2] = 2
|
97
|
+
tree[3] = 3
|
98
|
+
expect(tree.size).to be 3
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'return 0 if empty tree' do
|
102
|
+
expect(tree.size).to be 0
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#delete method" do
|
108
|
+
it "respond to" do
|
109
|
+
expect(tree).to respond_to(:delete)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'delete key value pair' do
|
113
|
+
tree[2] = 22
|
114
|
+
tree[3] = 33
|
115
|
+
tree.delete(3)
|
116
|
+
expect(tree[3]).to be_nil
|
117
|
+
end
|
118
|
+
|
119
|
+
it "return nil if not found" do
|
120
|
+
tree[3] = 33
|
121
|
+
expect(tree.delete(4)).to be_nil
|
122
|
+
end
|
123
|
+
|
124
|
+
it "return value if key is found" do
|
125
|
+
tree[2] = 22
|
126
|
+
tree[3] = 33
|
127
|
+
expect(tree.delete(2)).to be 22
|
128
|
+
end
|
129
|
+
|
130
|
+
it "call block with key if not found" do
|
131
|
+
tree[2] = 22
|
132
|
+
block = ->(key) { "#{key} is not found" }
|
133
|
+
expect(tree.delete(7, &block)).to be == "7 is not found"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#clear method" do
|
138
|
+
it "respond to" do
|
139
|
+
expect(tree).to respond_to(:clear)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'clear tree' do
|
143
|
+
tree[1] = 11
|
144
|
+
tree[2] = 22
|
145
|
+
tree[3] = 33
|
146
|
+
expect(tree.size).to be 3
|
147
|
+
tree.clear()
|
148
|
+
expect(tree.size).to be 0
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'return self' do
|
152
|
+
tree[1] = 11
|
153
|
+
expect(tree.clear()).to be tree
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#include? method" do
|
158
|
+
it "respond to" do
|
159
|
+
expect(tree).to respond_to(:include?)
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'return true is key exists' do
|
163
|
+
tree[3] = 33
|
164
|
+
expect(tree.include?(3)).to be true
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'return false if key not exists' do
|
168
|
+
tree[3] = 33
|
169
|
+
expect(tree.include?(4)).to be false
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "#empty? method" do
|
174
|
+
it 'respond to' do
|
175
|
+
expect(tree).to respond_to(:empty?)
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'return false if nodes exists' do
|
179
|
+
tree[3] = 33
|
180
|
+
expect(tree.empty?).to be false
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'return true if nodes not exists' do
|
184
|
+
expect(tree.empty?).to be true
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -48,14 +48,42 @@ RSpec.describe NativeBtree do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
describe "#each_key method" do
|
51
|
-
|
52
|
-
expect(
|
51
|
+
it "respond to" do
|
52
|
+
expect(tree).to respond_to(:each_key)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'yield ordered keys' do
|
56
|
+
tree[16] = 160
|
57
|
+
tree[0] = 0
|
58
|
+
tree[5] = 50
|
59
|
+
tree[-4] = -40
|
60
|
+
tree[7] = 70
|
61
|
+
|
62
|
+
check = [-4, 0, 5, 7, 16]
|
63
|
+
result = []
|
64
|
+
tree.each_key { |key| result << key }
|
65
|
+
|
66
|
+
expect(result).to eq(check)
|
53
67
|
end
|
54
68
|
end
|
55
69
|
|
56
70
|
describe "#each_value method" do
|
57
|
-
|
58
|
-
expect(
|
71
|
+
it "respond to" do
|
72
|
+
expect(tree).to respond_to(:each_value)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'yield values by ordered keys' do
|
76
|
+
tree[16] = 160
|
77
|
+
tree[0] = 0
|
78
|
+
tree[5] = 50
|
79
|
+
tree[-4] = -40
|
80
|
+
tree[7] = 70
|
81
|
+
|
82
|
+
check = [-40, 0, 50, 70, 160]
|
83
|
+
result = []
|
84
|
+
tree.each_value { |value| result << value }
|
85
|
+
|
86
|
+
expect(result).to eq(check)
|
59
87
|
end
|
60
88
|
end
|
61
89
|
end
|
@@ -12,4 +12,24 @@ RSpec.describe NativeBtree do
|
|
12
12
|
it "Btree is class" do
|
13
13
|
expect(described_class::Btree.class).to be Class
|
14
14
|
end
|
15
|
+
|
16
|
+
it "Has Glib contstant" do
|
17
|
+
expect(described_class.const_defined?(:Glib)).to be true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "Glib is module" do
|
21
|
+
expect(described_class::Glib.class).to be Module
|
22
|
+
end
|
23
|
+
|
24
|
+
it "Has MAJOR_VERSION contstant" do
|
25
|
+
expect(described_class::Glib.const_defined?(:MAJOR_VERSION)).to be true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "Has MINOR_VERSION contstant" do
|
29
|
+
expect(described_class::Glib.const_defined?(:MINOR_VERSION)).to be true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "Has MICRO_VERSION contstant" do
|
33
|
+
expect(described_class::Glib.const_defined?(:MICRO_VERSION)).to be true
|
34
|
+
end
|
15
35
|
end
|
@@ -54,6 +54,17 @@ RSpec.describe NativeBtree do
|
|
54
54
|
expect(tree.equal?(result)).to be false
|
55
55
|
end
|
56
56
|
|
57
|
+
it 'construct correct tree with int comparator' do
|
58
|
+
tree = described_class.new(described_class::INT_COMPARATOR)
|
59
|
+
|
60
|
+
tree[1] = 11
|
61
|
+
tree[5] = 90
|
62
|
+
tree[2] = 32
|
63
|
+
tree[100] = 15
|
64
|
+
tree[46] = 8
|
65
|
+
|
66
|
+
expect(tree.filter { |v| v > 20 }.to_a).to match_array([[2, 32], [5, 90]])
|
67
|
+
end
|
57
68
|
end
|
58
69
|
|
59
70
|
describe "#filter! method" do
|
@@ -88,7 +99,8 @@ RSpec.describe NativeBtree do
|
|
88
99
|
tree[100] = 15
|
89
100
|
tree[46] = 8
|
90
101
|
|
91
|
-
expect(tree.filter! { |v| v > 20 }.to_a)
|
102
|
+
expect(tree.filter! { |v| v > 20 }.to_a)
|
103
|
+
.to match_array([[2, 32], [5, 90]])
|
92
104
|
end
|
93
105
|
|
94
106
|
it 'filter tree by keys' do
|
@@ -98,7 +110,8 @@ RSpec.describe NativeBtree do
|
|
98
110
|
tree[100] = 15
|
99
111
|
tree[46] = 8
|
100
112
|
|
101
|
-
expect(tree.filter! { |_v, k| k > 20 }.to_a)
|
113
|
+
expect(tree.filter! { |_v, k| k > 20 }.to_a)
|
114
|
+
.to match_array([[46, 8], [100, 15]])
|
102
115
|
end
|
103
116
|
|
104
117
|
end
|
@@ -114,5 +127,84 @@ RSpec.describe NativeBtree do
|
|
114
127
|
expect(tree).to respond_to(:select!)
|
115
128
|
end
|
116
129
|
end
|
130
|
+
|
131
|
+
if NativeBtree::Glib::MAJOR_VERSION == 2 &&
|
132
|
+
NativeBtree::Glib::MINOR_VERSION >= 68
|
133
|
+
|
134
|
+
describe "select_before method" do
|
135
|
+
it 'respond_to' do
|
136
|
+
expect(tree).to respond_to(:select_before)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'return expected collection' do
|
140
|
+
tree[1] = 11
|
141
|
+
tree[2] = 32
|
142
|
+
tree[5] = 90
|
143
|
+
tree[46] = 8
|
144
|
+
tree[100] = 15
|
145
|
+
|
146
|
+
expect(tree.select_before(5).to_a)
|
147
|
+
.to match_array([[1, 11], [2, 32], [5, 90]])
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'return correct tree if one target' do
|
151
|
+
tree[100] = 15
|
152
|
+
tree[46] = 8
|
153
|
+
tree[5] = 90
|
154
|
+
|
155
|
+
expect(tree.select_before(5).to_a)
|
156
|
+
.to match_array([[5, 90]])
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'return empty tree if no targets' do
|
160
|
+
tree[100] = 15
|
161
|
+
tree[46] = 8
|
162
|
+
|
163
|
+
expect(tree.select_before(5).to_a)
|
164
|
+
.to match_array([])
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "select_after" do
|
169
|
+
it "respond to" do
|
170
|
+
expect(tree).to respond_to(:select_after)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'return expected collection' do
|
174
|
+
tree[1] = 11
|
175
|
+
tree[5] = 90
|
176
|
+
tree[2] = 32
|
177
|
+
tree[100] = 15
|
178
|
+
tree[46] = 8
|
179
|
+
|
180
|
+
expect(tree.select_after(5).to_a)
|
181
|
+
.to match_array([[5, 90], [46, 8], [100, 15]])
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'return correct tree if one target' do
|
185
|
+
tree[3] = 15
|
186
|
+
tree[4] = 8
|
187
|
+
tree[5] = 90
|
188
|
+
|
189
|
+
expect(tree.select_after(5).to_a)
|
190
|
+
.to match_array([[5, 90]])
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'return empty tree if no targets' do
|
194
|
+
tree[1] = 11
|
195
|
+
tree[2] = 32
|
196
|
+
|
197
|
+
expect(tree.select_after(5).to_a)
|
198
|
+
.to match_array([])
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "select_between" do
|
203
|
+
xit "respond to" do
|
204
|
+
expect(tree).to respond_to(:select_between)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
117
209
|
end
|
118
210
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: native_btree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Feodorov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby bindings to GTree balanced binary tree from GLib library.
|
14
14
|
email:
|
@@ -29,8 +29,12 @@ files:
|
|
29
29
|
- ext/native_btree/constructor.c
|
30
30
|
- ext/native_btree/conversion.c
|
31
31
|
- ext/native_btree/extconf_cmake.rb
|
32
|
+
- ext/native_btree/glib2_68/CMakeLists.txt
|
33
|
+
- ext/native_btree/glib2_68/additional_iterators.c
|
34
|
+
- ext/native_btree/glib_module.c
|
32
35
|
- ext/native_btree/include/common.h
|
33
36
|
- ext/native_btree/include/comparator.h
|
37
|
+
- ext/native_btree/include/glib_module.h
|
34
38
|
- ext/native_btree/include/iterators.h
|
35
39
|
- ext/native_btree/include/native_btree.h
|
36
40
|
- ext/native_btree/include/rbtree_type.h
|
@@ -47,6 +51,7 @@ files:
|
|
47
51
|
- spec/native_btree_class_spec.rb
|
48
52
|
- spec/native_btree_conversion_spec.rb
|
49
53
|
- spec/native_btree_instance_spec.rb
|
54
|
+
- spec/native_btree_int_instance_spec.rb
|
50
55
|
- spec/native_btree_iterators_spec.rb
|
51
56
|
- spec/native_btree_module_spec.rb
|
52
57
|
- spec/native_btree_search_spec.rb
|