native_btree 0.1.0.alpha2 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc39abeab06b5ed3984afa9cda174d12556523df6926db05e2889274c0157305
4
- data.tar.gz: 596a2b8af36be3da1ac5ebc2c64749f52e7ed5cb83d12280f11aa584f93e3fab
3
+ metadata.gz: a71b1e34d117e61eb4ef28533f3d4371447b942e81bbfaa23b85af4fc81210ad
4
+ data.tar.gz: 45b6b186bb06e9a58d5a26871f8ebb97dce6f3bffeeccb02169ea43dca972f86
5
5
  SHA512:
6
- metadata.gz: 87faa333af87558b8a7600e680daf5367dce6f5393e524d467321409b0f1e5285aeedb2cfc6d2c3044c8a978f84d5b6135a628b6a3736df7b040b5312f04bd5c
7
- data.tar.gz: 3aac04b9a2c1b14bff0db483c3075e164b6f7fe6fb9a9a45d4275fc9a66aa6a1cfa4f555a74c4680b821d12d8818985b0d10a2ca45fc69cd40a1f658c6401ab3
6
+ metadata.gz: 3bea00617a86a99ad538d31825538ff2547748b30e377e55dcfa98134a25777a0cf33466405395c99836e9bba337f2177ec2d033efc7a4cca17fbe615c087d82
7
+ data.tar.gz: 1d9ab5a418e9a9ad1e865ff31c1b126b738f2f546b35278fe483df1e357f8fccf427f9234fdc9ce031075d61956b28600af669aa7187d8b2d7f06a6146ff252d
data/CMakeLists.txt CHANGED
@@ -1,11 +1,11 @@
1
- cmake_minimum_required(VERSION 3.18.0)
1
+ cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR)
2
2
 
3
3
  project(ruby-native-btree
4
4
  LANGUAGES C
5
5
  VERSION 0.1.0
6
6
  HOMEPAGE_URL https://github.com/unixs/ruby-native-btree)
7
7
 
8
- set(REQUIRED_RUBY_VERSION 2.7.0)
8
+ set(REQUIRED_RUBY_VERSION 2.6.0)
9
9
 
10
10
  set(CMAKE_C_STANDARD 11)
11
11
  set(CMAKE_C_EXTENSIONS ON)
@@ -15,6 +15,9 @@ set(CMAKE_C_FLAGS_DEBUG " -O0 -ggdb3 -Wall -Wextra -Wpedantic -Wno-unused-parame
15
15
  set(CMAKE_C_FLAGS_RELEASE "-O3")
16
16
  set(CMAKE_C_FLAGS "-pipe -march=native")
17
17
 
18
+ # Force -fPIC
19
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
20
+
18
21
  if(NOT CMAKE_BUILD_TYPE)
19
22
  set(CMAKE_BUILD_TYPE "Release")
20
23
  endif()
@@ -36,7 +39,8 @@ include_directories(${Ruby_INCLUDE_DIRS})
36
39
  link_libraries(${Ruby_LIBRARIES})
37
40
  message("Ruby_INCLUDE_DIRS: ${Ruby_INCLUDE_DIRS}")
38
41
 
39
- message("Find Ruby deps.")
42
+ message(STATUS "Find Ruby deps.")
43
+
40
44
  # Find jemalloc
41
45
  pkg_check_modules(JEMALLOC jemalloc)
42
46
  if(JEMALLOC_FOUND)
data/Gemfile CHANGED
@@ -4,3 +4,15 @@ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem's dependencies in ruby_btree.gemspec
6
6
  gemspec
7
+
8
+ group :development do
9
+ gem 'awesome_print', '~> 1.9'
10
+ gem 'debase', '~> 0.2', platforms: [:mri_26, :mri_27]
11
+ gem 'pry', '~> 0.14'
12
+ gem 'rubocop', '~> 1.35.0'
13
+ gem 'rubocop-rake', '~> 0.6.0'
14
+ 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
+ end
data/README.md CHANGED
@@ -1,26 +1,28 @@
1
- # Native Balanced binary tree for Ruby
1
+ # GLib Balanced binary tree (GTree) bindings for Ruby
2
2
 
3
- Ruby bindings to [GTree - balanced binary tree from GLib library](https://developer.gnome.org/glib/stable/glib-Balanced-Binary-Trees.html) .
3
+ [![Ruby](https://github.com/unixs/ruby-native-btree/actions/workflows/main.yml/badge.svg)](https://github.com/unixs/ruby-native-btree/actions/workflows/main.yml)
4
4
 
5
- In most cases it is behave same as Hash, but keys will be ordered by passed comparator.
5
+ [GTree - balanced binary tree from GLib library](https://docs.gtk.org/glib/struct.Tree.html)
6
6
 
7
- Basic usage:
7
+ In most cases it will behave same as Hash, but keys will be ordered by passed comparator.
8
+
9
+ ## Basic usage:
8
10
 
9
11
  ```ruby
10
12
  require 'native_btree'
11
13
 
12
14
  # Pass comparator for keys as block
13
- tree = NativeBTree::BTree.new { |a, b| a <=> b }
15
+ tree = NativeBtree::Btree.new { |a, b| a - b }
14
16
 
15
- tree[:a1] = '111'
16
- tree[:c3] = '333'
17
- tree[:b2] = '222'
17
+ tree[1] = '111'
18
+ tree[3] = '333'
19
+ tree[2] = '222'
18
20
 
19
21
  tree.each { |k, v| puts "#{k} => #{v}" }
20
22
 
21
- # a1 => 111
22
- # b2 => 222
23
- # c3 => 333
23
+ # 1 => 111
24
+ # 2 => 222
25
+ # 3 => 333
24
26
  # nil
25
27
 
26
28
  tree.size
@@ -30,5 +32,15 @@ tree.height
30
32
  # 2
31
33
  ```
32
34
 
33
- Trees is may comparable by `==` or `.eql?` operator.
34
- Trees will be equal if all keys and all value is equal in both.
35
+ ## API ref
36
+
37
+ You must provide your own comparator for keys in `new` class method block.
38
+
39
+ ### Methods
40
+
41
+ * `[]= (alias: set)`
42
+ * `[] (alias: get)`
43
+ * `delete`
44
+ * `size`
45
+ * `height`
46
+ * `each`
data/Rakefile CHANGED
@@ -1,27 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
4
 
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- require "rubocop/rake_task"
5
+ begin
6
+ require "rspec/core/rake_task"
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ rescue LoadError
9
+ warn "RSpec rake tasks was not loaded"
10
+ end
9
11
 
10
- RuboCop::RakeTask.new
12
+ begin
13
+ require "rubocop/rake_task"
14
+ RuboCop::RakeTask.new
15
+ rescue LoadError
16
+ warn "Rubocop rake tasks was not loaded"
17
+ end
11
18
 
12
- task default: %i[rubocop spec]
19
+ task default: %i[cmake:build]
13
20
 
14
21
  BUILD_DIR = "build"
15
22
 
16
23
  namespace :cmake do
17
24
  desc "Remove build directory"
18
25
  task :rmbuild do
19
- sh "rm -rvf #{BUILD_DIR}"
26
+ sh "rm -rf #{BUILD_DIR}"
20
27
  end
21
28
 
22
29
  desc "Configure ext CMake project"
23
- task configure: %i[cmake:rmbuild] do
24
- sh "cmake . -B #{BUILD_DIR}"
30
+ task :configure do
31
+ sh "cmake -S . -B #{BUILD_DIR}"
25
32
  end
26
33
 
27
34
  desc "Build ext CMake project"
@@ -1,21 +1,28 @@
1
1
  set(EXT_NAME "native_btree")
2
2
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib/${EXT_NAME})
3
3
 
4
- include_directories(include)
5
-
6
- message("Find ext deps.")
4
+ message(STATUS "Find ext deps.")
7
5
 
8
6
  pkg_check_modules(GLIB2 REQUIRED glib-2.0)
9
7
 
10
- # include_directories(include ${GLIB2_INCLUDE_DIRS})
8
+ include_directories(include ${GLIB2_INCLUDE_DIRS})
9
+
10
+ add_library(rbtree_type OBJECT rbtree_type.c)
11
+ add_library(constructor OBJECT constructor.c)
12
+ add_library(instance OBJECT instance.c)
13
+ add_library(comparator OBJECT comparator.c)
14
+ add_library(iterators OBJECT iterators.c)
15
+
11
16
  add_library(${EXT_NAME}
12
17
  SHARED
13
18
  native_btree.c)
14
19
 
15
- #set_target_properties(${EXT_NAME} PROPERTIES BUNDLE TRUE)
16
-
17
-
18
- #target_link_libraries(${EXT_NAME}
19
- # PRIVATE
20
- # ${GLIB2_LDFLAGS})
21
-
20
+ target_link_libraries(${EXT_NAME}
21
+ PRIVATE
22
+ iterators
23
+ rbtree_type
24
+ constructor
25
+ instance
26
+ comparator
27
+ ${GLIB2_LDFLAGS})
28
+ #set_target_properties(${EXT_NAME} PROPERTIES BUNDLE TRUE)
@@ -0,0 +1,13 @@
1
+ #include <comparator.h>
2
+
3
+ gint
4
+ rbtree_native_comparator(gconstpointer a, gconstpointer b, gpointer data)
5
+ {
6
+ RBTree *rbtree = (RBTree *) data;
7
+
8
+ VALUE result = rb_funcall(rbtree->comparator, rb_intern("call"), 2, (VALUE) a, (VALUE) b);
9
+
10
+ gint compare_result = NUM2INT(result);
11
+
12
+ return compare_result;
13
+ }
@@ -0,0 +1,19 @@
1
+ #include <constructor.h>
2
+ #include <comparator.h>
3
+ #include <rbtree_type.h>
4
+
5
+ VALUE
6
+ rbtree_initialize(VALUE self)
7
+ {
8
+ EXTRACT_RBTREE_SELF(rbtree);
9
+
10
+ rbtree->gtree = g_tree_new_with_data(
11
+ rbtree_native_comparator,
12
+ rbtree
13
+ );
14
+
15
+ rb_need_block();
16
+ rbtree->comparator = rb_block_proc();
17
+
18
+ return self;
19
+ }
@@ -0,0 +1,21 @@
1
+ #include <ruby.h>
2
+ #include <glib.h>
3
+
4
+ #ifndef _NATIVE_BTREE_COMMON_
5
+ #define _NATIVE_BTREE_COMMON_
6
+
7
+ #include <rbtree_type.h>
8
+
9
+ #define NATIVE_BTREE_MODULE "NativeBtree"
10
+ #define NATIVE_BTREE_CLASS "Btree"
11
+
12
+ #define EXTRACT_RBTREE(from, to) \
13
+ RBTree *to; \
14
+ TypedData_Get_Struct(from, RBTree, &rbtree_type, rbtree)
15
+
16
+ #define EXTRACT_RBTREE_SELF(to) EXTRACT_RBTREE(self, to)
17
+
18
+ extern VALUE rbtree_class;
19
+ extern VALUE rbtree_module;
20
+
21
+ #endif //_NATIVE_BTREE_COMMON_
@@ -0,0 +1,4 @@
1
+ #include <common.h>
2
+
3
+ gint
4
+ rbtree_native_comparator(gconstpointer a, gconstpointer b, gpointer data);
@@ -0,0 +1,11 @@
1
+ #include <common.h>
2
+
3
+ #ifndef _NATIVE_BTREE_CONSTRUCTOR_
4
+ #define _NATIVE_BTREE_CONSTRUCTOR_
5
+
6
+
7
+
8
+ VALUE rbtree_alloc(VALUE self);
9
+ VALUE rbtree_initialize(VALUE self);
10
+
11
+ #endif //_NATIVE_BTREE_COMMON_H_
@@ -0,0 +1,16 @@
1
+ #include <common.h>
2
+
3
+ VALUE
4
+ rbtree_set(VALUE self, VALUE key, VALUE value);
5
+
6
+ VALUE
7
+ rbtree_get(VALUE self, VALUE key);
8
+
9
+ VALUE
10
+ rbtree_delete(VALUE self, VALUE key);
11
+
12
+ VALUE
13
+ rbtree_size(VALUE self);
14
+
15
+ VALUE
16
+ rbtree_height(VALUE self);
@@ -0,0 +1,5 @@
1
+ #include <common.h>
2
+
3
+
4
+ VALUE
5
+ rbtree_each(VALUE self);
@@ -1,17 +1,11 @@
1
1
  #ifndef _NATIVE_BTREE_
2
2
 
3
- #define NATIVE_BTREE "NativeBtree"
4
- #define NATIVE_BTREE_CLASS "Btree"
5
-
6
-
7
- #if defined(__cplusplus)
8
- extern "C" {
9
- #endif
10
-
11
- extern VALUE btree_class;
12
- extern VALUE btree_module;
13
- extern VALUE btree_class_from;
3
+ #include <common.h>
4
+ #include <constructor.h>
5
+ #include <instance.h>
6
+ #include <iterators.h>
14
7
 
8
+ /*
15
9
  VALUE
16
10
  btree_new(VALUE klass);
17
11
 
@@ -47,9 +41,6 @@ btree_cmp(VALUE self, VALUE tree2);
47
41
 
48
42
  VALUE
49
43
  btree_equal(VALUE self, VALUE tree2);
50
-
51
- #if defined(__cplusplus)
52
- }
53
- #endif
44
+ */
54
45
 
55
46
  #endif // _NATIVE_BTREE_
@@ -0,0 +1,22 @@
1
+ #ifndef _RBTREE_TYPE_
2
+ #define _RBTREE_TYPE_
3
+
4
+ #include <common.h>
5
+
6
+ #define NATIVE_TYPE_NAME "native_btree"
7
+
8
+ extern const rb_data_type_t rbtree_type;
9
+
10
+ VALUE
11
+ rbtree_alloc(VALUE self);
12
+
13
+ /**
14
+ * Internal native instance
15
+ */
16
+ typedef struct _RBTree
17
+ {
18
+ GTree *gtree;
19
+ VALUE comparator;
20
+ } RBTree;
21
+
22
+ #endif //_RBTREE_TYPE_
@@ -0,0 +1,83 @@
1
+ #include <instance.h>
2
+
3
+
4
+ VALUE
5
+ rbtree_set(VALUE self, VALUE key, VALUE value)
6
+ {
7
+ EXTRACT_RBTREE_SELF(rbtree);
8
+
9
+ g_tree_replace(rbtree->gtree, (gpointer) key, (gpointer) value);
10
+
11
+ return self;
12
+ }
13
+
14
+
15
+ VALUE
16
+ rbtree_get(VALUE self, VALUE key)
17
+ {
18
+ EXTRACT_RBTREE_SELF(rbtree);
19
+
20
+ gpointer found = g_tree_lookup(rbtree->gtree, (gpointer) key);
21
+
22
+ if (found == NULL) {
23
+ return Qnil;
24
+ }
25
+
26
+ VALUE result = (VALUE) found;
27
+
28
+ return result;
29
+ }
30
+
31
+
32
+ VALUE
33
+ rbtree_delete(VALUE self, VALUE key)
34
+ {
35
+ EXTRACT_RBTREE_SELF(rbtree);
36
+
37
+ VALUE found_key, found_value;
38
+ gboolean found = g_tree_lookup_extended(
39
+ rbtree->gtree,
40
+ (gconstpointer) key,
41
+ (gpointer *) &found_key,
42
+ (gpointer *) &found_value
43
+ );
44
+
45
+ if (found) {
46
+ g_tree_remove(rbtree->gtree, (gconstpointer) key);
47
+
48
+ return found_value;
49
+ }
50
+ else {
51
+ if (rb_block_given_p()) {
52
+ VALUE block = rb_block_proc();
53
+
54
+ return rb_funcall(block, rb_intern("call"), 1, key);
55
+ }
56
+
57
+ return Qnil;
58
+ }
59
+ }
60
+
61
+
62
+ VALUE
63
+ rbtree_height(VALUE self)
64
+ {
65
+ EXTRACT_RBTREE_SELF(rbtree);
66
+
67
+ gint size = g_tree_height(rbtree->gtree);
68
+ VALUE result = INT2NUM(size);
69
+
70
+ return result;
71
+ }
72
+
73
+
74
+ VALUE
75
+ rbtree_size(VALUE self)
76
+ {
77
+ EXTRACT_RBTREE_SELF(rbtree);
78
+
79
+ gint size = g_tree_nnodes(rbtree->gtree);
80
+ VALUE result = INT2NUM(size);
81
+
82
+ return result;
83
+ }
@@ -0,0 +1,26 @@
1
+ #include <iterators.h>
2
+
3
+ static gboolean
4
+ foraech_callbac(gpointer a, gpointer b, gpointer data)
5
+ {
6
+ VALUE key = (VALUE) a;
7
+ VALUE value = (VALUE) b;
8
+ VALUE block = (VALUE) data;
9
+
10
+ rb_funcall(block, rb_intern("call"), 2, value, key);
11
+
12
+ return FALSE;
13
+ }
14
+
15
+ VALUE
16
+ rbtree_each(VALUE self)
17
+ {
18
+ rb_need_block();
19
+ VALUE block = rb_block_proc();
20
+
21
+ EXTRACT_RBTREE_SELF(rbtree);
22
+
23
+ g_tree_foreach(rbtree->gtree, foraech_callbac, (gpointer) block);
24
+
25
+ return self;
26
+ }
@@ -1,27 +1,29 @@
1
- #include <ruby.h>
2
-
3
1
  #include <native_btree.h>
4
2
 
5
- VALUE btree_class;
6
- VALUE btree_module;
7
- VALUE btree_class_from;
8
-
9
- VALUE
10
- btree_from(VALUE klass);
11
-
12
- VALUE
13
- btree_from(VALUE klass)
14
- {
15
- VALUE result = INT2NUM(10);
3
+ VALUE rbtree_class;
4
+ VALUE rbtree_module;
16
5
 
17
- return result;
18
- }
19
6
 
20
7
  void
21
8
  Init_native_btree()
22
9
  {
23
- btree_module = rb_define_module(NATIVE_BTREE);
24
- btree_class = rb_define_class_under(btree_module, NATIVE_BTREE_CLASS, rb_cObject);
25
- rb_define_singleton_method(btree_class, "from", btree_from, 0);
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
+
19
+ rb_define_method(rbtree_class, "[]", rbtree_get, 1);
20
+ rb_define_alias(rbtree_class, "get", "[]");
21
+
22
+ rb_define_method(rbtree_class, "delete", rbtree_delete, 1);
23
+
24
+ rb_define_method(rbtree_class, "each", rbtree_each, 0);
25
+
26
+ rb_define_method(rbtree_class, "size", rbtree_size, 0);
27
+ rb_define_method(rbtree_class, "height", rbtree_height, 0);
26
28
  }
27
29
 
@@ -0,0 +1,102 @@
1
+ #include <rbtree_type.h>
2
+
3
+ const rb_data_type_t rbtree_type;
4
+
5
+
6
+ static void
7
+ rbtree_free(gpointer data)
8
+ {
9
+ RBTree *rbtree = (RBTree *) data;
10
+
11
+ g_tree_destroy(rbtree->gtree);
12
+ g_free(data);
13
+ }
14
+
15
+
16
+ static gboolean
17
+ rbtree_mark_callback(gpointer key, gpointer value, gpointer data)
18
+ {
19
+ rb_gc_mark((VALUE) key);
20
+ rb_gc_mark((VALUE) value);
21
+
22
+ return FALSE;
23
+ }
24
+
25
+
26
+ static void
27
+ rbtree_mark(gpointer data)
28
+ {
29
+ RBTree *rbtree = (RBTree *)data;
30
+
31
+ rb_gc_mark(rbtree->comparator);
32
+
33
+ g_tree_foreach(rbtree->gtree, rbtree_mark_callback, NULL);
34
+ }
35
+
36
+ /*
37
+
38
+ https://github.com/GNOME/glib/blob/main/glib/gtree.c#L80
39
+
40
+ struct _GTree
41
+ {
42
+ GTreeNode *root;
43
+ GCompareDataFunc key_compare;
44
+ GDestroyNotify key_destroy_func;
45
+ GDestroyNotify value_destroy_func;
46
+ gpointer key_compare_data;
47
+ guint nnodes;
48
+ gint ref_count;
49
+ };
50
+
51
+ struct _GTreeNode
52
+ {
53
+ gpointer key;
54
+ gpointer value;
55
+ GTreeNode *left;
56
+ GTreeNode *right;
57
+ gint8 balance;
58
+ guint8 left_child;
59
+ guint8 right_child;
60
+ };
61
+ */
62
+
63
+ static size_t
64
+ rbtree_size(gconstpointer data)
65
+ {
66
+ RBTree *rbtree = (RBTree *) data;
67
+
68
+ gint gtree_size = g_tree_nnodes(rbtree->gtree);
69
+
70
+ // struct _GTreeNode
71
+ size_t node_size = sizeof(gpointer) * 4 +
72
+ sizeof(gint8) +
73
+ sizeof(guint8) * 2;
74
+
75
+ // struct _GTree
76
+ size_t gtree_root_size = sizeof(gpointer) * 5 +
77
+ sizeof(gint8) +
78
+ sizeof(guint8) * 2;
79
+
80
+ return sizeof(RBTree) + node_size * gtree_size + gtree_root_size;
81
+ }
82
+
83
+
84
+ const rb_data_type_t rbtree_type = {
85
+ .wrap_struct_name = NATIVE_TYPE_NAME,
86
+ .function = {
87
+ .dmark = rbtree_mark,
88
+ .dfree = rbtree_free,
89
+ .dsize = rbtree_size,
90
+ },
91
+ .data = NULL,
92
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
93
+ };
94
+
95
+
96
+ VALUE
97
+ rbtree_alloc(VALUE self)
98
+ {
99
+ RBTree *rbtree = g_new(RBTree, 1);
100
+
101
+ return TypedData_Wrap_Struct(self, &rbtree_type, rbtree);
102
+ }
Binary file
@@ -1,3 +1,3 @@
1
1
  module NativeBtree
2
- VERSION = "0.1.0.alpha2".freeze
2
+ VERSION = "0.1.0".freeze
3
3
  end
data/native_btree.gemspec CHANGED
@@ -27,20 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.files += Dir['*.{md}']
28
28
  s.files += %w[Rakefile Gemfile CMakeLists.txt native_btree.gemspec LICENSE]
29
29
 
30
- s.bindir = "bin"
31
30
  s.executables = s.files.grep(%r{\Abin/}) { |f| File.basename(f) }
32
31
  s.require_paths = ["lib"]
33
32
  s.required_ruby_version = '>= 2.6'
34
-
35
- s.add_dependency 'rubocop', '~> 1.35.0'
36
- s.add_dependency 'rubocop-rake', '~> 0.6.0'
37
- s.add_dependency 'rubocop-rspec', '~> 2.12.1'
38
- s.add_dependency 'rake', '~> 13.0.6'
39
- s.add_dependency 'rspec', '~> 3.11.0'
40
-
41
- s.add_development_dependency 'awesome_print', '~> 1.9'
42
- s.add_development_dependency 'debase', '~> 0.2'
43
- s.add_development_dependency 'pry', '~> 0.14'
44
- s.add_development_dependency 'ruby-debug-ide', '~> 0.7'
45
- s.add_development_dependency 'solargraph', '~> 0.46'
46
33
  end
data/spec/debug.rb ADDED
@@ -0,0 +1,24 @@
1
+ # rubocop:disable all
2
+
3
+ require_relative "../lib/native_btree/native_btree"
4
+
5
+ tree = NativeBtree::Btree.new
6
+
7
+ GC.start
8
+
9
+ tree[3] = {a: 'value 3'}
10
+ tree[1] = {a: 'value 1'}
11
+ tree[2] = {a: 'value 2'}
12
+ tree[16] = {a: 'value 16'}
13
+ tree[0] = {a: 'value 0'}
14
+
15
+ GC.start
16
+
17
+ block = ->(key) { "#{key} is not found" }
18
+ puts tree.delete(77, &block)
19
+
20
+ tree = null
21
+
22
+ GC.start
23
+
24
+ puts "exit 0"
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe NativeBtree do
4
+ it "has a version number" do
5
+ expect(NativeBtree::VERSION).not_to be_nil
6
+ end
7
+
8
+ describe NativeBtree::Btree do
9
+
10
+ describe "initialize class method" do
11
+ it 'respond to new' do
12
+ expect(described_class).to respond_to('new').with(0).arguments
13
+ end
14
+
15
+ it "return new btree instance" do
16
+ expect(described_class.new { nil }).to be_kind_of(described_class)
17
+ end
18
+
19
+ it "raise error if block is not given" do
20
+ expect { described_class.new() }.to raise_error(LocalJumpError)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,239 @@
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 "#[]= method" do
13
+
14
+ it "respond to" do
15
+ expect(tree).to respond_to('[]=')
16
+ end
17
+
18
+ it 'set key/value pair' do
19
+ tree[2] = 22
20
+ expect(tree[2]).to be 22
21
+ end
22
+
23
+ it "pass key arg and value" do
24
+ expect(tree[:key] = 10).to be 10
25
+ end
26
+
27
+ it "Raise ArgumentError if key was not passed" do
28
+ expect { tree[] = 1 }.to raise_error(ArgumentError)
29
+ end
30
+
31
+ it 'Call comparator while set value' do
32
+ comparator = spy('comparator')
33
+ def comparator.to_proc
34
+ proc do |a, b|
35
+ comparator.call()
36
+ a - b
37
+ end
38
+ end
39
+
40
+ btree = described_class.new(&comparator)
41
+ btree[1] = 1
42
+ btree[2] = 2
43
+ expect(comparator).to have_received(:call)
44
+ end
45
+
46
+ it 'has a set alias' do
47
+ expect(tree).to respond_to('set')
48
+ end
49
+ end
50
+
51
+ describe "#[] method" do
52
+ it "respond to" do
53
+ expect(tree).to respond_to('[]')
54
+ end
55
+
56
+ it 'return expected value if found' do
57
+ tree[3] = 'a'
58
+ tree[4] = 'b'
59
+ expect(tree[3]).to be 'a'
60
+ end
61
+
62
+ it 'return nil if not found' do
63
+ tree[1] = '1'
64
+ tree[5] = '5'
65
+ expect(tree[2]).to be_nil
66
+ end
67
+
68
+ it 'has a get alias' do
69
+ expect(tree).to respond_to('get')
70
+ end
71
+ end
72
+
73
+ describe "#height method" do
74
+ it "respond to" do
75
+ expect(tree).to respond_to(:height)
76
+ end
77
+
78
+ it 'return tree height with items' do
79
+ tree[1] = 11
80
+ tree[2] = 22
81
+ tree[3] = 33
82
+ tree[4] = 44
83
+ expect(tree.height).to be 3
84
+ end
85
+
86
+ it 'return 0 if empty tree' do
87
+ expect(tree.height).to be 0
88
+ end
89
+ end
90
+
91
+ describe "#size method" do
92
+ it "respond to" do
93
+ expect(tree).to respond_to(:size)
94
+ end
95
+
96
+ it 'return count of nodes' do
97
+ tree[1] = 1
98
+ tree[2] = 2
99
+ tree[3] = 3
100
+ expect(tree.size).to be 3
101
+ end
102
+
103
+ it 'return 0 if empty tree' do
104
+ expect(tree.size).to be 0
105
+ end
106
+
107
+ end
108
+
109
+ describe "#delete method" do
110
+ it "respond to" do
111
+ expect(tree).to respond_to(:delete)
112
+ end
113
+
114
+ it 'delete key value pair' do
115
+ tree[2] = 22
116
+ tree[3] = 33
117
+ tree.delete(3)
118
+ expect(tree[3]).to be_nil
119
+ end
120
+
121
+ it "return nil if not found" do
122
+ tree[3] = 33
123
+ expect(tree.delete(4)).to be_nil
124
+ end
125
+
126
+ it "return value if key is found" do
127
+ tree[2] = 22
128
+ tree[3] = 33
129
+ expect(tree.delete(2)).to be 22
130
+ end
131
+
132
+ it "call block with key if not found" do
133
+ tree[2] = 22
134
+ block = ->(key) { "#{key} is not found" }
135
+ expect(tree.delete(7, &block)).to be == "7 is not found"
136
+ end
137
+ end
138
+
139
+ describe "#clear method" do
140
+ xit "respond to" do
141
+ expect(described_cless.respond_to?(:clear)).to be true
142
+ end
143
+ end
144
+
145
+ describe "#filter method" do
146
+ xit "respond to" do
147
+ expect(described_cless.respond_to?(:filter)).to be true
148
+ end
149
+ end
150
+
151
+ describe "#filter! method" do
152
+ xit "respond to" do
153
+ expect(described_cless.respond_to?(:filter!)).to be true
154
+ end
155
+ end
156
+
157
+ describe "#include? method" do
158
+ xit "respond to" do
159
+ expect(described_cless.respond_to?(:include?)).to be true
160
+ end
161
+ end
162
+
163
+ describe "to_ methods" do
164
+ describe "#to_a" do
165
+ xit "respond to" do
166
+ expect(described_cless.respond_to?(:to_a)).to be true
167
+ end
168
+ end
169
+
170
+ describe "#to_h" do
171
+ xit "respond to" do
172
+ expect(described_cless.respond_to?(:to_h)).to be true
173
+ end
174
+ end
175
+ end
176
+
177
+ describe "#each method" do
178
+ it "respond to" do
179
+ expect(tree).to respond_to(:each)
180
+ end
181
+
182
+ it 'yield in to block value first' do
183
+ tree[2] = 22
184
+
185
+ value = nil
186
+ tree.each { |v| value = v }
187
+
188
+ expect(value).to be 22
189
+ end
190
+
191
+ it 'yield in to block key second' do
192
+ tree[2] = 22
193
+
194
+ key = nil
195
+ tree.each { |_v, k| key = k }
196
+
197
+ expect(key).to be 2
198
+ end
199
+
200
+ it 'yield ordered keys' do
201
+ tree[16] = 16
202
+ tree[0] = 0
203
+ tree[5] = 5
204
+ tree[-4] = -4
205
+ tree[7] = 7
206
+
207
+ check = [-4, 0, 5, 7, 16]
208
+ result = []
209
+ tree.each { |value| result << value }
210
+
211
+ expect(result).to eq(check)
212
+ end
213
+ end
214
+
215
+ describe "#each_key method" do
216
+ xit "respond to" do
217
+ expect(described_cless.respond_to?(:each_key)).to be true
218
+ end
219
+ end
220
+
221
+ describe "#each_value method" do
222
+ xit "respond to" do
223
+ expect(described_cless.respond_to?(:each_value)).to be true
224
+ end
225
+ end
226
+
227
+ describe "#select method" do
228
+ xit "respond to" do
229
+ expect(described_cless.respond_to?(:select)).to be true
230
+ end
231
+ end
232
+
233
+ describe "#select! method" do
234
+ xit "respond to" do
235
+ expect(described_cless.respond_to?(:select!)).to be true
236
+ end
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe NativeBtree do
4
+ it "has a version number" do
5
+ expect(described_class.const_defined?(:VERSION)).to be true
6
+ end
7
+
8
+ it "Has Btree contstant" do
9
+ expect(described_class.const_defined?(:Btree)).to be true
10
+ end
11
+
12
+ it "Btree is class" do
13
+ expect(described_class::Btree.class).to be Class
14
+ end
15
+ end
metadata CHANGED
@@ -1,161 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: native_btree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha2
4
+ version: 0.1.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-08-30 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rubocop
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 1.35.0
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 1.35.0
27
- - !ruby/object:Gem::Dependency
28
- name: rubocop-rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 0.6.0
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 0.6.0
41
- - !ruby/object:Gem::Dependency
42
- name: rubocop-rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 2.12.1
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 2.12.1
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 13.0.6
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 13.0.6
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 3.11.0
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 3.11.0
83
- - !ruby/object:Gem::Dependency
84
- name: awesome_print
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '1.9'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '1.9'
97
- - !ruby/object:Gem::Dependency
98
- name: debase
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '0.2'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '0.2'
111
- - !ruby/object:Gem::Dependency
112
- name: pry
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '0.14'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '0.14'
125
- - !ruby/object:Gem::Dependency
126
- name: ruby-debug-ide
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '0.7'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '0.7'
139
- - !ruby/object:Gem::Dependency
140
- name: solargraph
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '0.46'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '0.46'
11
+ date: 2022-09-05 00:00:00.000000000 Z
12
+ dependencies: []
153
13
  description: Ruby bindings to GTree balanced binary tree from GLib library.
154
14
  email:
155
15
  - webmaster@unixcomp.org
156
- executables:
157
- - console
158
- - setup
16
+ executables: []
159
17
  extensions:
160
18
  - ext/native_btree/extconf_cmake.rb
161
19
  extra_rdoc_files: []
@@ -166,18 +24,31 @@ files:
166
24
  - LICENSE
167
25
  - README.md
168
26
  - Rakefile
169
- - bin/console
170
- - bin/setup
171
27
  - ext/native_btree/CMakeLists.txt
28
+ - ext/native_btree/comparator.c
29
+ - ext/native_btree/constructor.c
172
30
  - ext/native_btree/extconf_cmake.rb
173
31
  - ext/native_btree/include/btree.h
32
+ - ext/native_btree/include/common.h
33
+ - ext/native_btree/include/comparator.h
34
+ - ext/native_btree/include/constructor.h
35
+ - ext/native_btree/include/instance.h
36
+ - ext/native_btree/include/iterators.h
174
37
  - ext/native_btree/include/native_btree.h
38
+ - ext/native_btree/include/rbtree_type.h
39
+ - ext/native_btree/instance.c
40
+ - ext/native_btree/iterators.c
175
41
  - ext/native_btree/native_btree.c
42
+ - ext/native_btree/rbtree_type.c
176
43
  - lib/native_btree.rb
44
+ - lib/native_btree/native_btree.bundle
177
45
  - lib/native_btree/native_btree.so
178
46
  - lib/native_btree/version.rb
179
47
  - native_btree.gemspec
180
- - spec/native_btree_spec.rb
48
+ - spec/debug.rb
49
+ - spec/native_btree_class_spec.rb
50
+ - spec/native_btree_instance_spec.rb
51
+ - spec/native_btree_module_spec.rb
181
52
  - spec/spec_helper.rb
182
53
  homepage: https://github.com/unixs/ruby-native-btree
183
54
  licenses:
@@ -201,11 +72,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
201
72
  version: '2.6'
202
73
  required_rubygems_version: !ruby/object:Gem::Requirement
203
74
  requirements:
204
- - - ">"
75
+ - - ">="
205
76
  - !ruby/object:Gem::Version
206
- version: 1.3.1
77
+ version: '0'
207
78
  requirements: []
208
- rubygems_version: 3.1.6
79
+ rubygems_version: 3.3.21
209
80
  signing_key:
210
81
  specification_version: 4
211
82
  summary: Balanced binary tree from GLib.
data/bin/console DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "bundler/setup"
5
- require "ruby_btree"
6
-
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require "irb"
15
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe NativeBtree do
4
- it "has a version number" do
5
- expect(NativeBtree::VERSION).not_to be_nil
6
- end
7
-
8
- it "does something useful" do
9
- expect((1 + 1)).to be(2)
10
- end
11
-
12
- describe NativeBtree::Btree do
13
- it "respond to from" do
14
- expect(described_class.from).to be(10)
15
- end
16
- end
17
- end