native_btree 0.5.0 → 0.6.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 +19 -1
- data/CMakeLists.txt +1 -1
- data/README.md +4 -1
- data/ext/native_btree/conversion.c +11 -0
- data/ext/native_btree/include/iterators.h +8 -1
- data/ext/native_btree/include/native_btree.h +9 -0
- data/ext/native_btree/instance.c +157 -47
- data/ext/native_btree/iterators.c +51 -0
- data/ext/native_btree/native_btree.c +7 -0
- data/ext/native_btree/search.c +8 -4
- data/lib/native_btree/native_btree.bundle +0 -0
- data/lib/native_btree/version.rb +1 -1
- data/spec/debug.rb +1 -0
- data/spec/native_btree_conversion_spec.rb +31 -0
- data/spec/native_btree_instance_spec.rb +57 -0
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 4744529a22fe3d5cd3eb53cf258fa5440346df593e6d268d7af3d2e4b197addf
         | 
| 4 | 
            +
              data.tar.gz: 887db38cf3c3c23cd72984f6ec2bbdfce1ebce57e547c5cc2d96c81184a36833
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: f46367c894c10a0ca5db645470228f08edafabe9010a5115d9c92008688eec29f9a0973ba462138483912a2bebe52660eb17828298ea69ebd1709d4811cfb470
         | 
| 7 | 
            +
              data.tar.gz: 9a342ae22e6ced29b02aa24917f1307fc0a0721885667185266eaa1b23f73fd37c90918126dd1ac6aa24cee08a3c838c25a951e3a84ea5f23cb93e2532d9549d
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -7,10 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |
| 7 7 |  | 
| 8 8 | 
             
            ## [Unreleased]
         | 
| 9 9 |  | 
| 10 | 
            -
            *  | 
| 10 | 
            +
            * #compact
         | 
| 11 | 
            +
            * #compact!
         | 
| 12 | 
            +
            * #>
         | 
| 13 | 
            +
            * #>=
         | 
| 14 | 
            +
            * #<
         | 
| 15 | 
            +
            * #<=
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            ## [0.6.0] - 2022-10-28
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ### Added
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            * inspect
         | 
| 22 | 
            +
            * to_s
         | 
| 23 | 
            +
            * delete_if
         | 
| 11 24 | 
             
            * first, min
         | 
| 12 25 | 
             
            * last, max
         | 
| 13 26 |  | 
| 27 | 
            +
            ### Changed
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            * Refactoring
         | 
| 30 | 
            +
            * Performance improvements for #==
         | 
| 31 | 
            +
             | 
| 14 32 | 
             
            ## [0.5.0] - 2022-10-04
         | 
| 15 33 |  | 
| 16 34 | 
             
            ### Added
         | 
    
        data/CMakeLists.txt
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -103,12 +103,14 @@ Implemented methods: | |
| 103 103 | 
             
            * `delete`
         | 
| 104 104 | 
             
            * `size`
         | 
| 105 105 | 
             
            * `height`
         | 
| 106 | 
            -
            * `each` | 
| 106 | 
            +
            * `each`
         | 
| 107 107 | 
             
            * `include?`
         | 
| 108 108 | 
             
            * `clear`
         | 
| 109 109 | 
             
            * `to_h`
         | 
| 110 110 | 
             
            * `to_a`
         | 
| 111 111 | 
             
            * `to_proc`
         | 
| 112 | 
            +
            * `to_s`
         | 
| 113 | 
            +
            * `inspect`
         | 
| 112 114 | 
             
            * `filter` (alias: select)
         | 
| 113 115 | 
             
            * `filter!` (alias: select!)
         | 
| 114 116 | 
             
            * `each_value`
         | 
| @@ -117,5 +119,6 @@ Implemented methods: | |
| 117 119 | 
             
            * `search_after` (GLib version >= 2.68) - Select keys >= first arg, ret new Btree
         | 
| 118 120 | 
             
            * `empty?`
         | 
| 119 121 | 
             
            * `reverse_each`
         | 
| 122 | 
            +
            * `delete_if`
         | 
| 120 123 |  | 
| 121 124 | 
             
            You can mix in the `Enumerable` module if additional methods are needed.
         | 
| @@ -76,3 +76,14 @@ rbtree_to_proc(VALUE self) | |
| 76 76 | 
             
            {
         | 
| 77 77 | 
             
              return rb_proc_new(to_proc_proc, self);
         | 
| 78 78 | 
             
            }
         | 
| 79 | 
            +
             | 
| 80 | 
            +
             | 
| 81 | 
            +
            VALUE
         | 
| 82 | 
            +
            rbtree_to_s(VALUE self)
         | 
| 83 | 
            +
            {
         | 
| 84 | 
            +
              VALUE h = rbtree_to_h(self);
         | 
| 85 | 
            +
             | 
| 86 | 
            +
              VALUE str = rb_sprintf("#<NativeBtree::Btree:%"PRIsVALUE">", h);
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              return str;
         | 
| 89 | 
            +
            }
         | 
| @@ -1,13 +1,20 @@ | |
| 1 1 | 
             
            #include <common.h>
         | 
| 2 2 |  | 
| 3 | 
            +
            #ifndef _NATIVE_BTREE_ITERATORS_
         | 
| 4 | 
            +
            #define _NATIVE_BTREE_ITERATORS_
         | 
| 5 | 
            +
             | 
| 3 6 | 
             
            typedef struct {
         | 
| 4 7 | 
             
              const VALUE block;
         | 
| 5 8 | 
             
              const RBTree *tree;
         | 
| 9 | 
            +
              glong counter;
         | 
| 10 | 
            +
              gushort flags;
         | 
| 6 11 | 
             
              gconstpointer something;
         | 
| 7 | 
            -
            }  | 
| 12 | 
            +
            } RBTreeSearchContext;
         | 
| 8 13 |  | 
| 9 14 | 
             
            #ifdef HAS_GTREE_NODE
         | 
| 10 15 |  | 
| 11 16 | 
             
            typedef GTreeNode *(RBTreeStepFunction) (GTreeNode *node);
         | 
| 12 17 |  | 
| 13 18 | 
             
            #endif
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            #endif // _NATIVE_BTREE_ITERATORS_
         | 
    
        data/ext/native_btree/instance.c
    CHANGED
    
    | @@ -4,6 +4,7 @@ | |
| 4 4 | 
             
              #include <compare_trees.h>
         | 
| 5 5 | 
             
            #else
         | 
| 6 6 | 
             
              #include <utils.h>
         | 
| 7 | 
            +
              #include <iterators.h>
         | 
| 7 8 | 
             
            #endif
         | 
| 8 9 |  | 
| 9 10 | 
             
            #ifndef HAS_GTREE_REMOVE_ALL
         | 
| @@ -20,6 +21,96 @@ rbtree_remove_node(gpointer key, gpointer val, gpointer data) { | |
| 20 21 | 
             
            #endif
         | 
| 21 22 |  | 
| 22 23 |  | 
| 24 | 
            +
            #ifndef HAS_GTREE_NODE
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            static gint
         | 
| 27 | 
            +
            rbtree_first_cb(gpointer a, gpointer b, gpointer data)
         | 
| 28 | 
            +
            {
         | 
| 29 | 
            +
              RBTreeSearchContext *context = (RBTreeSearchContext *) data;
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              context->something = (gconstpointer) b;
         | 
| 32 | 
            +
              context->counter = 0;
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              return TRUE;
         | 
| 35 | 
            +
            }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
             | 
| 38 | 
            +
            static gint
         | 
| 39 | 
            +
            rbtree_last_cb(gpointer a, gpointer b, gpointer data)
         | 
| 40 | 
            +
            {
         | 
| 41 | 
            +
              RBTreeSearchContext *context = (RBTreeSearchContext *) data;
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              context->something = (gconstpointer) b;
         | 
| 44 | 
            +
              context->counter += 1;
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              return FALSE;
         | 
| 47 | 
            +
            }
         | 
| 48 | 
            +
             | 
| 49 | 
            +
             | 
| 50 | 
            +
            static gint
         | 
| 51 | 
            +
            legacy_compare_visitor(gpointer a, gpointer b, gpointer data)
         | 
| 52 | 
            +
            {
         | 
| 53 | 
            +
              RBTreeSearchContext *context = (RBTreeSearchContext *) data;
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              GPtrArray *flat_tree = (GPtrArray *) context->something;
         | 
| 56 | 
            +
              VALUE key = (VALUE) a;
         | 
| 57 | 
            +
              VALUE val = (VALUE) b;
         | 
| 58 | 
            +
              VALUE is_eq = Qfalse;
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              VALUE key2 = (VALUE) g_ptr_array_index(flat_tree, context->counter);
         | 
| 61 | 
            +
              VALUE val2 = (VALUE) g_ptr_array_index(flat_tree, context->counter + 1);
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              is_eq = rb_funcall(key, rb_intern("=="), 1, key2);
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              if (!RTEST(is_eq)) {
         | 
| 66 | 
            +
                context->flags = 1;
         | 
| 67 | 
            +
                return TRUE;
         | 
| 68 | 
            +
              }
         | 
| 69 | 
            +
             | 
| 70 | 
            +
              is_eq = rb_funcall(val, rb_intern("=="), 1, val2);
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              if (!RTEST(is_eq)) {
         | 
| 73 | 
            +
                context->flags = 1;
         | 
| 74 | 
            +
                return TRUE;
         | 
| 75 | 
            +
              }
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              (context->counter) += 2;
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              return FALSE;
         | 
| 80 | 
            +
            }
         | 
| 81 | 
            +
             | 
| 82 | 
            +
             | 
| 83 | 
            +
            static inline gboolean
         | 
| 84 | 
            +
            legacy_rbtree_compare(const RBTree *a, const RBTree *b)
         | 
| 85 | 
            +
            {
         | 
| 86 | 
            +
              gboolean result = TRUE;
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              GPtrArray *second = rbtree_to_ptr_array(b);
         | 
| 89 | 
            +
             | 
| 90 | 
            +
              // assumes that the size of arrays is same (checked before)
         | 
| 91 | 
            +
             | 
| 92 | 
            +
              RBTreeSearchContext context = {
         | 
| 93 | 
            +
                Qnil,
         | 
| 94 | 
            +
                NULL,
         | 
| 95 | 
            +
                0,
         | 
| 96 | 
            +
                0,
         | 
| 97 | 
            +
                (gconstpointer) second
         | 
| 98 | 
            +
              };
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              g_tree_foreach(a->gtree, legacy_compare_visitor, &context);
         | 
| 101 | 
            +
             | 
| 102 | 
            +
              if (context.flags) {
         | 
| 103 | 
            +
                result = FALSE;
         | 
| 104 | 
            +
              }
         | 
| 105 | 
            +
             | 
| 106 | 
            +
              g_ptr_array_free(second, TRUE);
         | 
| 107 | 
            +
             | 
| 108 | 
            +
              return result;
         | 
| 109 | 
            +
            }
         | 
| 110 | 
            +
             | 
| 111 | 
            +
            #endif
         | 
| 112 | 
            +
             | 
| 113 | 
            +
             | 
| 23 114 | 
             
            VALUE
         | 
| 24 115 | 
             
            rbtree_set(VALUE self, VALUE key, VALUE value)
         | 
| 25 116 | 
             
            {
         | 
| @@ -141,53 +232,6 @@ rbtree_is_empty(VALUE self) | |
| 141 232 | 
             
            }
         | 
| 142 233 |  | 
| 143 234 |  | 
| 144 | 
            -
            #ifndef HAS_GTREE_NODE
         | 
| 145 | 
            -
             | 
| 146 | 
            -
            static inline gboolean
         | 
| 147 | 
            -
            legacy_rbtree_compare(const RBTree *a, const RBTree *b)
         | 
| 148 | 
            -
            {
         | 
| 149 | 
            -
              gboolean result = FALSE;
         | 
| 150 | 
            -
             | 
| 151 | 
            -
              GPtrArray *first = rbtree_to_ptr_array(a);
         | 
| 152 | 
            -
              GPtrArray *second = rbtree_to_ptr_array(b);
         | 
| 153 | 
            -
             | 
| 154 | 
            -
              // assumes that the size of arrays is same (checked before)
         | 
| 155 | 
            -
             | 
| 156 | 
            -
              VALUE key, val, key2, val2, is_eq;
         | 
| 157 | 
            -
             | 
| 158 | 
            -
              for (guint i = 0; i < first->len; i += 2) {
         | 
| 159 | 
            -
                key = (VALUE) g_ptr_array_index(first, i);
         | 
| 160 | 
            -
                val = (VALUE) g_ptr_array_index(first, i + 1);
         | 
| 161 | 
            -
             | 
| 162 | 
            -
                key2 = (VALUE) g_ptr_array_index(second, i);
         | 
| 163 | 
            -
                val2 = (VALUE) g_ptr_array_index(second, i + 1);
         | 
| 164 | 
            -
             | 
| 165 | 
            -
                is_eq = rb_funcall(key, rb_intern("=="), 1, key2);
         | 
| 166 | 
            -
             | 
| 167 | 
            -
                if (!RTEST(is_eq)) {
         | 
| 168 | 
            -
                  goto fail;
         | 
| 169 | 
            -
                }
         | 
| 170 | 
            -
             | 
| 171 | 
            -
                is_eq = rb_funcall(val, rb_intern("=="), 1, val2);
         | 
| 172 | 
            -
             | 
| 173 | 
            -
                if (!RTEST(is_eq)) {
         | 
| 174 | 
            -
                  goto fail;
         | 
| 175 | 
            -
                }
         | 
| 176 | 
            -
              }
         | 
| 177 | 
            -
             | 
| 178 | 
            -
              result = TRUE;
         | 
| 179 | 
            -
             | 
| 180 | 
            -
              fail:
         | 
| 181 | 
            -
             | 
| 182 | 
            -
              g_ptr_array_free(first, TRUE);
         | 
| 183 | 
            -
              g_ptr_array_free(second, TRUE);
         | 
| 184 | 
            -
             | 
| 185 | 
            -
              return result;
         | 
| 186 | 
            -
            }
         | 
| 187 | 
            -
             | 
| 188 | 
            -
            #endif
         | 
| 189 | 
            -
             | 
| 190 | 
            -
             | 
| 191 235 | 
             
            VALUE
         | 
| 192 236 | 
             
            rbtree_equal(VALUE self, VALUE second)
         | 
| 193 237 | 
             
            {
         | 
| @@ -221,3 +265,69 @@ rbtree_equal(VALUE self, VALUE second) | |
| 221 265 | 
             
              ret:
         | 
| 222 266 | 
             
              return result;
         | 
| 223 267 | 
             
            }
         | 
| 268 | 
            +
             | 
| 269 | 
            +
             | 
| 270 | 
            +
            VALUE
         | 
| 271 | 
            +
            rbtree_first(VALUE self)
         | 
| 272 | 
            +
            {
         | 
| 273 | 
            +
              EXTRACT_RBTREE_SELF(rbtree);
         | 
| 274 | 
            +
             | 
| 275 | 
            +
            #ifdef HAS_GTREE_NODE
         | 
| 276 | 
            +
              GTreeNode *node = g_tree_node_first(rbtree->gtree);
         | 
| 277 | 
            +
             | 
| 278 | 
            +
              if (!node) {
         | 
| 279 | 
            +
                return Qnil;
         | 
| 280 | 
            +
              }
         | 
| 281 | 
            +
             | 
| 282 | 
            +
              return (VALUE) g_tree_node_value(node);
         | 
| 283 | 
            +
            #else
         | 
| 284 | 
            +
              RBTreeSearchContext context = {
         | 
| 285 | 
            +
                Qnil,
         | 
| 286 | 
            +
                NULL,
         | 
| 287 | 
            +
                1,
         | 
| 288 | 
            +
                0,
         | 
| 289 | 
            +
                NULL
         | 
| 290 | 
            +
              };
         | 
| 291 | 
            +
             | 
| 292 | 
            +
              g_tree_foreach(rbtree->gtree, rbtree_first_cb, &context);
         | 
| 293 | 
            +
             | 
| 294 | 
            +
              if (context.counter) {
         | 
| 295 | 
            +
                return Qnil;
         | 
| 296 | 
            +
              }
         | 
| 297 | 
            +
             | 
| 298 | 
            +
              return (VALUE) context.something;
         | 
| 299 | 
            +
            #endif
         | 
| 300 | 
            +
            }
         | 
| 301 | 
            +
             | 
| 302 | 
            +
             | 
| 303 | 
            +
            VALUE
         | 
| 304 | 
            +
            rbtree_last(VALUE self)
         | 
| 305 | 
            +
            {
         | 
| 306 | 
            +
              EXTRACT_RBTREE_SELF(rbtree);
         | 
| 307 | 
            +
             | 
| 308 | 
            +
            #ifdef HAS_GTREE_NODE
         | 
| 309 | 
            +
              GTreeNode *node = g_tree_node_last(rbtree->gtree);
         | 
| 310 | 
            +
             | 
| 311 | 
            +
              if (!node) {
         | 
| 312 | 
            +
                return Qnil;
         | 
| 313 | 
            +
              }
         | 
| 314 | 
            +
             | 
| 315 | 
            +
              return (VALUE) g_tree_node_value(node);
         | 
| 316 | 
            +
            #else
         | 
| 317 | 
            +
              RBTreeSearchContext context = {
         | 
| 318 | 
            +
                Qnil,
         | 
| 319 | 
            +
                NULL,
         | 
| 320 | 
            +
                0,
         | 
| 321 | 
            +
                0,
         | 
| 322 | 
            +
                NULL
         | 
| 323 | 
            +
              };
         | 
| 324 | 
            +
             | 
| 325 | 
            +
              g_tree_foreach(rbtree->gtree, rbtree_last_cb, &context);
         | 
| 326 | 
            +
             | 
| 327 | 
            +
              if (!context.counter) {
         | 
| 328 | 
            +
                return Qnil;
         | 
| 329 | 
            +
              }
         | 
| 330 | 
            +
             | 
| 331 | 
            +
              return (VALUE) context.something;
         | 
| 332 | 
            +
            #endif
         | 
| 333 | 
            +
            }
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            #include <common.h>
         | 
| 2 | 
            +
            #include <iterators.h>
         | 
| 2 3 |  | 
| 3 4 | 
             
            #ifndef HAS_GTREE_NODE
         | 
| 4 5 | 
             
              #include <utils.h>
         | 
| @@ -128,3 +129,53 @@ rbtree_reverse_each(VALUE self) | |
| 128 129 |  | 
| 129 130 | 
             
              return self;
         | 
| 130 131 | 
             
            }
         | 
| 132 | 
            +
             | 
| 133 | 
            +
             | 
| 134 | 
            +
            static gint
         | 
| 135 | 
            +
            rbtree_delete_if_cb(gpointer k, gpointer v, gpointer data)
         | 
| 136 | 
            +
            {
         | 
| 137 | 
            +
              VALUE key = (VALUE) k;
         | 
| 138 | 
            +
              VALUE value = (VALUE) v;
         | 
| 139 | 
            +
              RBTreeSearchContext *context = (RBTreeSearchContext *) data;
         | 
| 140 | 
            +
              VALUE block = (VALUE) context->block;
         | 
| 141 | 
            +
              GPtrArray *result = (GPtrArray *) context->something;
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              VALUE to_delete = rb_funcall(block, rb_intern("call"), 2, key, value);
         | 
| 144 | 
            +
             | 
| 145 | 
            +
              if (RTEST(to_delete)) {
         | 
| 146 | 
            +
                g_ptr_array_add(result, (gpointer) key);
         | 
| 147 | 
            +
              }
         | 
| 148 | 
            +
             | 
| 149 | 
            +
              return FALSE;
         | 
| 150 | 
            +
            }
         | 
| 151 | 
            +
             | 
| 152 | 
            +
             | 
| 153 | 
            +
            VALUE
         | 
| 154 | 
            +
            rbtree_delete_if(VALUE self)
         | 
| 155 | 
            +
            {
         | 
| 156 | 
            +
              EXTRACT_RBTREE_SELF(rbtree);
         | 
| 157 | 
            +
             | 
| 158 | 
            +
              GPtrArray *to_delete = g_ptr_array_new();
         | 
| 159 | 
            +
             | 
| 160 | 
            +
              RETURN_SIZED_ENUMERATOR(self, 0, 0, rbtree_enum_length);
         | 
| 161 | 
            +
             | 
| 162 | 
            +
              VALUE block = rb_block_proc();
         | 
| 163 | 
            +
             | 
| 164 | 
            +
              RBTreeSearchContext context = {
         | 
| 165 | 
            +
                block,
         | 
| 166 | 
            +
                NULL,
         | 
| 167 | 
            +
                0,
         | 
| 168 | 
            +
                0,
         | 
| 169 | 
            +
                to_delete
         | 
| 170 | 
            +
              };
         | 
| 171 | 
            +
             | 
| 172 | 
            +
              g_tree_foreach(rbtree->gtree, rbtree_delete_if_cb, &context);
         | 
| 173 | 
            +
             | 
| 174 | 
            +
              for (guint i = 0; i < to_delete->len; i++) {
         | 
| 175 | 
            +
                g_tree_remove(rbtree->gtree, g_ptr_array_index(to_delete, i));
         | 
| 176 | 
            +
              }
         | 
| 177 | 
            +
             | 
| 178 | 
            +
              g_ptr_array_free(to_delete, TRUE);
         | 
| 179 | 
            +
             | 
| 180 | 
            +
              return self;
         | 
| 181 | 
            +
            }
         | 
| @@ -57,6 +57,13 @@ Init_native_btree() | |
| 57 57 | 
             
              rb_define_method(native_btree_class, "empty?", rbtree_is_empty, 0);
         | 
| 58 58 | 
             
              rb_define_method(native_btree_class, "==", rbtree_equal, 1);
         | 
| 59 59 | 
             
              rb_define_method(native_btree_class, "reverse_each", rbtree_reverse_each, 0);
         | 
| 60 | 
            +
              rb_define_method(native_btree_class, "first", rbtree_first, 0);
         | 
| 61 | 
            +
              rb_define_alias(native_btree_class, "min", "first");
         | 
| 62 | 
            +
              rb_define_method(native_btree_class, "last", rbtree_last, 0);
         | 
| 63 | 
            +
              rb_define_alias(native_btree_class, "max", "last");
         | 
| 64 | 
            +
              rb_define_method(native_btree_class, "delete_if", rbtree_delete_if, 0);
         | 
| 65 | 
            +
              rb_define_method(native_btree_class, "to_s", rbtree_to_s, 0);
         | 
| 66 | 
            +
              rb_define_alias(native_btree_class, "inspect", "to_s");
         | 
| 60 67 |  | 
| 61 68 | 
             
            #ifdef HAS_GTREE_NODE
         | 
| 62 69 | 
             
              rb_define_method(native_btree_class, "select_before", rbtree_select_before, 1);
         | 
    
        data/ext/native_btree/search.c
    CHANGED
    
    | @@ -4,7 +4,7 @@ | |
| 4 4 | 
             
            static gboolean
         | 
| 5 5 | 
             
            filter_callback(gpointer a, gpointer b, gpointer data)
         | 
| 6 6 | 
             
            {
         | 
| 7 | 
            -
               | 
| 7 | 
            +
              RBTreeSearchContext *context = (RBTreeSearchContext *) data;
         | 
| 8 8 |  | 
| 9 9 | 
             
              VALUE compare_result = rb_funcall(
         | 
| 10 10 | 
             
                context->block,
         | 
| @@ -24,7 +24,7 @@ filter_callback(gpointer a, gpointer b, gpointer data) | |
| 24 24 | 
             
            static gboolean
         | 
| 25 25 | 
             
            filter_bang_callback(gpointer a, gpointer b, gpointer data)
         | 
| 26 26 | 
             
            {
         | 
| 27 | 
            -
               | 
| 27 | 
            +
              RBTreeSearchContext *context = (RBTreeSearchContext *) data;
         | 
| 28 28 | 
             
              GPtrArray *to_remove = (GPtrArray *) context->something;
         | 
| 29 29 |  | 
| 30 30 | 
             
              VALUE compare_result = rb_funcall(
         | 
| @@ -55,9 +55,11 @@ rbtree_filter(VALUE self) | |
| 55 55 |  | 
| 56 56 | 
             
              EXTRACT_RBTREE(new_tree, new_rbtree);
         | 
| 57 57 |  | 
| 58 | 
            -
               | 
| 58 | 
            +
              RBTreeSearchContext data = {
         | 
| 59 59 | 
             
                block,
         | 
| 60 60 | 
             
                new_rbtree,
         | 
| 61 | 
            +
                0,
         | 
| 62 | 
            +
                0,
         | 
| 61 63 | 
             
                NULL
         | 
| 62 64 | 
             
              };
         | 
| 63 65 |  | 
| @@ -76,9 +78,11 @@ rbtree_filter_bang(VALUE self) | |
| 76 78 |  | 
| 77 79 | 
             
              GPtrArray *to_remove = g_ptr_array_new();
         | 
| 78 80 |  | 
| 79 | 
            -
               | 
| 81 | 
            +
              RBTreeSearchContext data = {
         | 
| 80 82 | 
             
                block,
         | 
| 81 83 | 
             
                NULL,
         | 
| 84 | 
            +
                0,
         | 
| 85 | 
            +
                0,
         | 
| 82 86 | 
             
                (gconstpointer) to_remove
         | 
| 83 87 | 
             
              };
         | 
| 84 88 |  | 
| Binary file | 
    
        data/lib/native_btree/version.rb
    CHANGED
    
    
    
        data/spec/debug.rb
    CHANGED
    
    
| @@ -65,6 +65,37 @@ RSpec.describe NativeBtree do | |
| 65 65 | 
             
                      expect(pr.call(12)).to be_nil
         | 
| 66 66 | 
             
                    end
         | 
| 67 67 | 
             
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  describe "#to_s" do
         | 
| 70 | 
            +
                    it 'respond to' do
         | 
| 71 | 
            +
                      expect(tree).to respond_to(:to_s)
         | 
| 72 | 
            +
                    end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                    it 'return correct str for empty' do
         | 
| 75 | 
            +
                      expect(tree.to_s).to eq('#<NativeBtree::Btree:{}>')
         | 
| 76 | 
            +
                    end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                    it 'return correct str' do
         | 
| 79 | 
            +
                      tree[10] = "20"
         | 
| 80 | 
            +
                      expect(tree.to_s).to eq('#<NativeBtree::Btree:{10=>"20"}>')
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  describe "#inspect" do
         | 
| 85 | 
            +
                    it 'respond to' do
         | 
| 86 | 
            +
                      expect(tree).to respond_to(:inspect)
         | 
| 87 | 
            +
                    end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                    it 'return correct str for empty' do
         | 
| 90 | 
            +
                      expect(tree.to_s).to eq('#<NativeBtree::Btree:{}>')
         | 
| 91 | 
            +
                    end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                    it 'return correct str' do
         | 
| 94 | 
            +
                      tree[10] = "20"
         | 
| 95 | 
            +
                      tree[30] = "40"
         | 
| 96 | 
            +
                      expect(tree.to_s).to eq('#<NativeBtree::Btree:{10=>"20", 30=>"40"}>')
         | 
| 97 | 
            +
                    end
         | 
| 98 | 
            +
                  end
         | 
| 68 99 | 
             
                end
         | 
| 69 100 | 
             
              end
         | 
| 70 101 | 
             
            end
         | 
| @@ -258,5 +258,62 @@ RSpec.describe NativeBtree do | |
| 258 258 | 
             
                    expect(tree).not_to eq tree2
         | 
| 259 259 | 
             
                  end
         | 
| 260 260 | 
             
                end
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                describe '#last method' do
         | 
| 263 | 
            +
                  it 'respond to' do
         | 
| 264 | 
            +
                    expect(tree).to respond_to(:last)
         | 
| 265 | 
            +
                  end
         | 
| 266 | 
            +
             | 
| 267 | 
            +
                  it 'return correct value' do
         | 
| 268 | 
            +
                    tree[1] = 10
         | 
| 269 | 
            +
                    tree[10] = 20
         | 
| 270 | 
            +
                    tree[20] = 30
         | 
| 271 | 
            +
             | 
| 272 | 
            +
                    expect(tree.last).to eq(30)
         | 
| 273 | 
            +
                  end
         | 
| 274 | 
            +
             | 
| 275 | 
            +
                  it 'return nil if empty' do
         | 
| 276 | 
            +
                    expect(tree.last).to be_nil
         | 
| 277 | 
            +
                  end
         | 
| 278 | 
            +
                end
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                describe '#first method' do
         | 
| 281 | 
            +
                  it 'respond to' do
         | 
| 282 | 
            +
                    expect(tree).to respond_to(:first)
         | 
| 283 | 
            +
                  end
         | 
| 284 | 
            +
             | 
| 285 | 
            +
                  it 'return correct value' do
         | 
| 286 | 
            +
                    tree[1] = 10
         | 
| 287 | 
            +
                    tree[10] = 20
         | 
| 288 | 
            +
                    tree[20] = 30
         | 
| 289 | 
            +
             | 
| 290 | 
            +
                    expect(tree.first).to eq(10)
         | 
| 291 | 
            +
                  end
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                  it 'return nil if empty' do
         | 
| 294 | 
            +
                    expect(tree.first).to be_nil
         | 
| 295 | 
            +
                  end
         | 
| 296 | 
            +
                end
         | 
| 297 | 
            +
             | 
| 298 | 
            +
                describe '#delete_if method' do
         | 
| 299 | 
            +
                  it 'respond to' do
         | 
| 300 | 
            +
                    expect(tree).to respond_to(:delete_if)
         | 
| 301 | 
            +
                  end
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                  it 'return self' do
         | 
| 304 | 
            +
                    expect(tree.delete_if { |_, _| false }).to be tree
         | 
| 305 | 
            +
                  end
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                  it 'return expected result' do
         | 
| 308 | 
            +
                    tree[1] = 10
         | 
| 309 | 
            +
                    tree[10] = 20
         | 
| 310 | 
            +
                    tree[20] = 30
         | 
| 311 | 
            +
             | 
| 312 | 
            +
                    tree.delete_if { |_, v| v < 30 }
         | 
| 313 | 
            +
             | 
| 314 | 
            +
                    expect(tree.to_a).to eq([[20, 30]])
         | 
| 315 | 
            +
                  end
         | 
| 316 | 
            +
                end
         | 
| 317 | 
            +
             | 
| 261 318 | 
             
              end
         | 
| 262 319 | 
             
            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.6.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-10- | 
| 11 | 
            +
            date: 2022-10-27 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies: []
         | 
| 13 13 | 
             
            description: Ruby bindings to GTree balanced binary tree from GLib library.
         | 
| 14 14 | 
             
            email:
         |