native_btree 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 398bae312c489bfe71fdee2f82499005e655097606a5537c38cfb122980b9f48
4
- data.tar.gz: 492df9b7fc0585e0615da770a6c3fd3e2d02323d33c1d3cfecae46b882b881a3
3
+ metadata.gz: 1dbf5cc77f1056fc6f84cf49496c233b9a3ecd9c62a0d82149cce9804a80edd7
4
+ data.tar.gz: eb1f55db08e767f443b02751258fb749ae991eb98e5426a8d5c81714c66ebd49
5
5
  SHA512:
6
- metadata.gz: 634ac5f2eab6a8f9ebf9ed577d5cd2fcdca75fdb8e61f285b3e83e244204976bdef93981320ea101a621b2845cb9346099d61a94193eb5872d0f1480ad363f09
7
- data.tar.gz: cf5f853401bdcab2d12088fe11c23cbde946e5a3542620d905e1acb59ede62522cbd293f65c7b10ca54f4a00737c9fe5485519c72358f185840fa8efbe81719b
6
+ metadata.gz: 7753f72aa3babc2151d74ae4bad29fb7c43e41cd7cf8b3bc9348e4b6e9be3c156d2ecc78fd2e689ca099e27df8bdee376550cbbc16b97ef15f15c431e8c5c093
7
+ data.tar.gz: d1992054500ad7207aea7186a0aa9bd3099cf013983c2596f5c2b5289ca5c8129f4ceeea4bf9ddf0777eb019b4dfc70be3b0feb571d741bb148af1f68de6e754
data/CHANGELOG.md CHANGED
@@ -7,12 +7,19 @@ 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.3.0] - 2022-09-11
14
+
15
+ ### Added
16
+
17
+ * to_proc()
18
+ * empty?()
10
19
  * filter()
11
20
  * filter!()
12
- * each_key()
13
- * each_value()
14
21
  * select()
15
- * select!
22
+ * select!()
16
23
 
17
24
  ## [0.2.1] - 2022-09-08
18
25
 
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.2.1)
5
+ VERSION 0.3.0)
6
6
 
7
7
  include(CheckSymbolExists)
8
8
 
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
@@ -57,15 +57,24 @@ tree.height
57
57
 
58
58
  You must provide your own comparator for keys in `new` class method block.
59
59
 
60
- ### Methods
60
+ ### API methods
61
+
62
+ In general this class behave same as Hash
63
+
64
+ Implemented methods:
61
65
 
62
66
  * `[]= (alias: set)`
63
67
  * `[] (alias: get)`
64
68
  * `delete`
65
69
  * `size`
66
70
  * `height`
67
- * `each`
71
+ * `each` (NB! block is required)
68
72
  * `include?`
69
73
  * `clear`
70
74
  * `to_h`
71
75
  * `to_a`
76
+ * `to_proc`
77
+ * `filter` (alias: select)
78
+ * `filter!` (alias: select!)
79
+
80
+ You can mix in the `Enumerable` module if additional methods are needed.
@@ -26,6 +26,7 @@ add_library(instance OBJECT instance.c)
26
26
  add_library(comparator OBJECT comparator.c)
27
27
  add_library(iterators OBJECT iterators.c)
28
28
  add_library(conversion OBJECT conversion.c)
29
+ add_library(search OBJECT search.c)
29
30
 
30
31
  add_library(native_btree_interface
31
32
  STATIC
@@ -34,7 +35,8 @@ add_library(native_btree_interface
34
35
  $<TARGET_OBJECTS:comparator>
35
36
  $<TARGET_OBJECTS:instance>
36
37
  $<TARGET_OBJECTS:constructor>
37
- $<TARGET_OBJECTS:rbtree_type>)
38
+ $<TARGET_OBJECTS:rbtree_type>
39
+ $<TARGET_OBJECTS:search>)
38
40
 
39
41
  target_link_libraries(${EXT_NAME}
40
42
  PRIVATE
@@ -1,4 +1,3 @@
1
- #include <constructor.h>
2
1
  #include <comparator.h>
3
2
  #include <rbtree_type.h>
4
3
 
@@ -1,4 +1,5 @@
1
- #include <conversion.h>
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
+ }
@@ -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
11
  RBTree *to; \
14
- TypedData_Get_Struct(from, RBTree, &rbtree_type, rbtree)
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 rbtree_class;
19
- extern VALUE rbtree_module;
16
+ extern VALUE native_btree_class;
17
+ extern VALUE native_btree_module;
20
18
 
21
19
  #endif //_NATIVE_BTREE_COMMON_
@@ -1,5 +1,7 @@
1
1
  #include <common.h>
2
2
 
3
-
4
- VALUE
5
- rbtree_each(VALUE self);
3
+ typedef struct {
4
+ VALUE block;
5
+ RBTree *tree;
6
+ gconstpointer something;
7
+ } RBTreeSearchData;
@@ -1,9 +1,50 @@
1
1
  #ifndef _NATIVE_BTREE_
2
2
 
3
- #include <common.h>
4
- #include <constructor.h>
5
- #include <instance.h>
6
- #include <iterators.h>
7
- #include <conversion.h>
3
+ #include <ruby.h>
4
+
5
+ VALUE
6
+ rbtree_initialize(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_to_h(VALUE self);
34
+
35
+ VALUE
36
+ rbtree_to_a(VALUE self);
37
+
38
+ VALUE
39
+ rbtree_to_proc(VALUE self);
40
+
41
+ VALUE
42
+ rbtree_filter(VALUE self);
43
+
44
+ VALUE
45
+ rbtree_filter_bang(VALUE self);
46
+
47
+ VALUE
48
+ rbtree_is_empty(VALUE self);
8
49
 
9
50
  #endif // _NATIVE_BTREE_
@@ -3,7 +3,7 @@
3
3
 
4
4
  #include <common.h>
5
5
 
6
- #define NATIVE_TYPE_NAME "native_btree"
6
+ #define RBTREE_NATIVE_TYPE_NAME "native_btree"
7
7
 
8
8
  extern const rb_data_type_t rbtree_type;
9
9
 
@@ -1,4 +1,5 @@
1
- #include <instance.h>
1
+ #include <common.h>
2
+
2
3
 
3
4
  #ifndef HAVE_GTREE_REMOVE_ALL
4
5
 
@@ -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
+ }
@@ -1,4 +1,4 @@
1
- #include <iterators.h>
1
+ #include <common.h>
2
2
 
3
3
  static gboolean
4
4
  foraech_callbac(gpointer a, gpointer b, gpointer data)
@@ -1,28 +1,45 @@
1
1
  #include <native_btree.h>
2
+ #include <rbtree_type.h>
2
3
 
3
- VALUE rbtree_class;
4
- VALUE rbtree_module;
4
+ #define NATIVE_BTREE_MODULE "NativeBtree"
5
+ #define NATIVE_BTREE_CLASS "Btree"
6
+
7
+
8
+ VALUE native_btree_class;
9
+ VALUE native_btree_module;
5
10
 
6
11
 
7
12
  void
8
13
  Init_native_btree()
9
14
  {
10
- rbtree_module = rb_define_module(NATIVE_BTREE_MODULE);
11
- rbtree_class = rb_define_class_under(rbtree_module, NATIVE_BTREE_CLASS, rb_cObject);
12
-
13
- rb_define_alloc_func(rbtree_class, rbtree_alloc);
14
- rb_define_method(rbtree_class, "initialize", rbtree_initialize, 0);
15
-
16
- rb_define_method(rbtree_class, "[]=", rbtree_set, 2);
17
- rb_define_alias(rbtree_class, "set", "[]=");
18
- rb_define_method(rbtree_class, "[]", rbtree_get, 1);
19
- rb_define_alias(rbtree_class, "get", "[]");
20
- rb_define_method(rbtree_class, "delete", rbtree_delete, 1);
21
- rb_define_method(rbtree_class, "each", rbtree_each, 0);
22
- rb_define_method(rbtree_class, "size", rbtree_size, 0);
23
- rb_define_method(rbtree_class, "height", rbtree_height, 0);
24
- rb_define_method(rbtree_class, "clear", rbtree_clear, 0);
25
- rb_define_method(rbtree_class, "include?", rbtree_is_include, 1);
26
- rb_define_method(rbtree_class, "to_h", rbtree_to_h, 0);
27
- rb_define_method(rbtree_class, "to_a", rbtree_to_a, 0);
15
+ native_btree_module = rb_define_module(NATIVE_BTREE_MODULE);
16
+ native_btree_class = rb_define_class_under(
17
+ native_btree_module,
18
+ NATIVE_BTREE_CLASS,
19
+ rb_cObject
20
+ );
21
+
22
+ // rb_include_module(native_btree_class, rb_mEnumerable);
23
+
24
+ rb_define_alloc_func(native_btree_class, rbtree_alloc);
25
+ rb_define_method(native_btree_class, "initialize", rbtree_initialize, 0);
26
+
27
+ rb_define_method(native_btree_class, "[]=", rbtree_set, 2);
28
+ rb_define_alias(native_btree_class, "set", "[]=");
29
+ rb_define_method(native_btree_class, "[]", rbtree_get, 1);
30
+ rb_define_alias(native_btree_class, "get", "[]");
31
+ rb_define_method(native_btree_class, "delete", rbtree_delete, 1);
32
+ rb_define_method(native_btree_class, "each", rbtree_each, 0);
33
+ rb_define_method(native_btree_class, "size", rbtree_size, 0);
34
+ rb_define_method(native_btree_class, "height", rbtree_height, 0);
35
+ rb_define_method(native_btree_class, "clear", rbtree_clear, 0);
36
+ rb_define_method(native_btree_class, "include?", rbtree_is_include, 1);
37
+ rb_define_method(native_btree_class, "to_h", rbtree_to_h, 0);
38
+ rb_define_method(native_btree_class, "to_a", rbtree_to_a, 0);
39
+ rb_define_method(native_btree_class, "to_proc", rbtree_to_proc, 0);
40
+ rb_define_method(native_btree_class, "filter", rbtree_filter, 0);
41
+ rb_define_alias(native_btree_class, "select", "filter");
42
+ rb_define_method(native_btree_class, "filter!", rbtree_filter_bang, 0);
43
+ rb_define_alias(native_btree_class, "select!", "filter!");
44
+ rb_define_method(native_btree_class, "empty?", rbtree_is_empty, 0);
28
45
  }
@@ -4,7 +4,7 @@ const rb_data_type_t rbtree_type;
4
4
 
5
5
 
6
6
  static void
7
- rbtree_free(gpointer data)
7
+ rbtree_type_free(gpointer data)
8
8
  {
9
9
  RBTree *rbtree = (RBTree *) data;
10
10
 
@@ -24,7 +24,7 @@ rbtree_mark_callback(gpointer key, gpointer value, gpointer data)
24
24
 
25
25
 
26
26
  static void
27
- rbtree_mark(gpointer data)
27
+ rbtree_type_mark(gpointer data)
28
28
  {
29
29
  RBTree *rbtree = (RBTree *)data;
30
30
 
@@ -61,7 +61,7 @@ struct _GTreeNode
61
61
  */
62
62
 
63
63
  static size_t
64
- rbtree_size(gconstpointer data)
64
+ rbtree_type_size(gconstpointer data)
65
65
  {
66
66
  RBTree *rbtree = (RBTree *) data;
67
67
 
@@ -82,11 +82,11 @@ rbtree_size(gconstpointer data)
82
82
 
83
83
 
84
84
  const rb_data_type_t rbtree_type = {
85
- .wrap_struct_name = NATIVE_TYPE_NAME,
85
+ .wrap_struct_name = RBTREE_NATIVE_TYPE_NAME,
86
86
  .function = {
87
- .dmark = rbtree_mark,
88
- .dfree = rbtree_free,
89
- .dsize = rbtree_size,
87
+ .dmark = rbtree_type_mark,
88
+ .dfree = rbtree_type_free,
89
+ .dsize = rbtree_type_size,
90
90
  },
91
91
  .data = NULL,
92
92
  .flags = RUBY_TYPED_FREE_IMMEDIATELY,
@@ -0,0 +1,101 @@
1
+ #include <iterators.h>
2
+
3
+ VALUE native_btree_class;
4
+
5
+ static gboolean
6
+ filter_callback(gpointer a, gpointer b, gpointer data)
7
+ {
8
+ RBTreeSearchData *context = (RBTreeSearchData *) data;
9
+
10
+ VALUE compare_result = rb_funcall(
11
+ context->block,
12
+ rb_intern("call"),
13
+ 2,
14
+ (VALUE) b,
15
+ (VALUE) a
16
+ );
17
+
18
+ if (RTEST(compare_result)) {
19
+ g_tree_insert(context->tree->gtree, a, b);
20
+ }
21
+
22
+ return FALSE;
23
+ }
24
+
25
+ static gboolean
26
+ filter_bang_callback(gpointer a, gpointer b, gpointer data)
27
+ {
28
+ RBTreeSearchData *context = (RBTreeSearchData *) data;
29
+ GPtrArray *to_remove = (GPtrArray *) context->something;
30
+
31
+ VALUE compare_result = rb_funcall(
32
+ context->block,
33
+ rb_intern("call"),
34
+ 2,
35
+ (VALUE) b,
36
+ (VALUE) a
37
+ );
38
+
39
+ if (!RTEST(compare_result)) {
40
+ // Add to remove
41
+ g_ptr_array_add(to_remove, a);
42
+ }
43
+
44
+ return FALSE;
45
+ }
46
+
47
+ VALUE
48
+ rbtree_filter(VALUE self)
49
+ {
50
+ rb_need_block();
51
+ EXTRACT_RBTREE_SELF(rbtree);
52
+
53
+ VALUE block = rb_block_proc();
54
+
55
+ VALUE new_tree = rb_funcall_with_block(
56
+ native_btree_class,
57
+ rb_intern("new"),
58
+ 0,
59
+ NULL,
60
+ rbtree->comparator
61
+ );
62
+
63
+ EXTRACT_RBTREE(new_tree, new_rbtree);
64
+
65
+ RBTreeSearchData data = {
66
+ block,
67
+ new_rbtree,
68
+ NULL
69
+ };
70
+
71
+ g_tree_foreach(rbtree->gtree, filter_callback, &data);
72
+
73
+ return new_tree;
74
+ }
75
+
76
+ VALUE
77
+ rbtree_filter_bang(VALUE self)
78
+ {
79
+ rb_need_block();
80
+ EXTRACT_RBTREE_SELF(rbtree);
81
+
82
+ VALUE block = rb_block_proc();
83
+
84
+ GPtrArray *to_remove = g_ptr_array_new();
85
+
86
+ RBTreeSearchData data = {
87
+ block,
88
+ NULL,
89
+ (gconstpointer) to_remove
90
+ };
91
+
92
+ g_tree_foreach(rbtree->gtree, filter_bang_callback, &data);
93
+
94
+ for (size_t i = 0; i < to_remove->len; i++) {
95
+ g_tree_remove(rbtree->gtree, g_ptr_array_index(to_remove, i));
96
+ }
97
+
98
+ g_ptr_array_free(to_remove, TRUE);
99
+
100
+ return self;
101
+ }
@@ -1,3 +1,3 @@
1
1
  module NativeBtree
2
- VERSION = "0.2.1".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
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
 
@@ -17,7 +17,16 @@ GC.start
17
17
  block = ->(key) { "#{key} is not found" }
18
18
  puts tree.delete(77, &block)
19
19
 
20
- tree = null
20
+ tree2 = tree.filter!() { true }
21
+
22
+ puts tree.to_h
23
+
24
+ pr = tree.to_proc
25
+
26
+ puts pr
27
+ puts pr.call(10)
28
+ puts pr.call(16)
29
+
21
30
 
22
31
  GC.start
23
32
 
@@ -0,0 +1,70 @@
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 do |a, b|
8
+ a - b
9
+ end
10
+ end
11
+
12
+ describe "to_ methods" do
13
+ describe "#to_a" do
14
+ it "respond to" do
15
+ expect(tree).to respond_to(:to_a)
16
+ end
17
+
18
+ it 'return Array' do
19
+ expect(tree.to_a).to be_kind_of(Array)
20
+ end
21
+
22
+ it 'has similar items' do
23
+ tree[2] = 22
24
+ tree[1] = 11
25
+ expect(tree.to_a()[0][1]).to be 11
26
+ end
27
+ end
28
+
29
+ describe "#to_h" do
30
+ it "respond to" do
31
+ expect(tree).to respond_to(:to_h)
32
+ end
33
+
34
+ it "return Hash" do
35
+ expect(tree.to_h).to be_kind_of(Hash)
36
+ end
37
+
38
+ it 'has similar keys' do
39
+ tree[2] = 22
40
+ tree[1] = 11
41
+ expect(tree.to_h()[1]).to be 11
42
+ end
43
+ end
44
+
45
+ describe '#to_proc' do
46
+ it 'respond to' do
47
+ expect(tree).to respond_to(:to_proc)
48
+ end
49
+
50
+ it 'return Proc' do
51
+ expect(tree.to_proc).to be_kind_of(Proc)
52
+ end
53
+
54
+ it 'return value for key' do
55
+ tree[2] = 22
56
+ tree[1] = 11
57
+ pr = tree.to_proc
58
+ expect(pr.call(1)).to be 11
59
+ end
60
+
61
+ it 'return null for non existent key' do
62
+ tree[2] = 22
63
+ tree[1] = 11
64
+ pr = tree.to_proc
65
+ expect(pr.call(12)).to be_nil
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end