native_btree 0.1.0.alpha2 → 0.1.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: 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