]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
maple_tree: Refactor coalesce into a separate function.
authorLiam R. Howlett <Liam.Howlett@Oracle.com>
Fri, 11 Jan 2019 15:46:29 +0000 (10:46 -0500)
committerLiam R. Howlett <Liam.Howlett@Oracle.com>
Wed, 31 Jul 2019 14:52:36 +0000 (10:52 -0400)
Reworked logic to have a bit of a cleaner looking function.  Supports
full nodes now as well.

Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
lib/maple_tree.c

index 13958fa73eb99ceeffd929e6d9c0a787d626d5c6..198ef705a71d85ef048b51194a40847f0f786d69 100644 (file)
@@ -437,58 +437,85 @@ static void mas_update_limits(struct ma_state *ms, unsigned char slot)
        if (slot < MAPLE_RANGE64_SLOTS - 1)
                ms->max = mr64->pivot[slot];
 }
+/* Private
+ *
+ * This copies from the start to the specified end of a node into a new node.
+ * Returns a pointer to the node, encoded node is in mas->node.
+ * Node: mas->node is overwritten.
+ */
+static struct maple_range_64 *mas_partial_copy(struct ma_state *mas,
+                                              unsigned char end)
+{
+       struct maple_node *smn = mt_to_node(mas->node);
+       struct maple_range_64 *src = &smn->mr64;
+       struct maple_range_64 *dst = NULL;
+       struct maple_node *dmn;
+       int i = 0;
+       /* Allocate a new node */
+       mas_node_cnt(mas, 1);
+       if (mas_is_err(mas))
+               return NULL;
 
+       dmn = ma_next_alloc(mas);
+       dst = &dmn->mr64;
+       dmn->parent = smn->parent;
+       for (i = 0; i < end;i++)
+       {
+               RCU_INIT_POINTER(dst->slot[i],
+                               src->slot[i]);
+               dst->pivot[i] = src->pivot[i];
+       }
+       mas->node = mt_mk_node(dmn, maple_leaf_64);
+       return dst;
+}
 /* Private
  * Combine nulls with the same pivot value
+ * Note: The mas->node will most likely be changed, so keep track of the old
+ * mas->node to free it.
  */
 static int mas_coalesce(struct ma_state *mas)
 {
-       struct maple_range_64 *src = &mt_to_node(mas->node)->mr64;
+       struct maple_node *smn = mt_to_node(mas->node);
+       struct maple_range_64 *src = &smn->mr64;
        unsigned char s_slot, d_slot = 0;
        unsigned long last = mas->max;
        struct maple_range_64 *dst = NULL;
-       struct maple_node *mn;
+       int ret = 0;
 
 
        for (s_slot = 0; s_slot < MAPLE_RANGE64_SLOTS; s_slot++) {
                if (s_slot < MAPLE_RANGE64_SLOTS - 1) {
                        if (last == src->pivot[s_slot]) {
                                if (!dst) {
-                                       int i = 0;
-                                       /* Allocate a new node */
-                                       mas_node_cnt(mas, 1);
+                                       d_slot = s_slot;
+                                       dst = mas_partial_copy(mas, s_slot);
                                        if (mas_is_err(mas))
                                                return 0;
 
-                                       mn = ma_next_alloc(mas);
-                                       dst = &mn->mr64;
-                                       mn->parent = src->parent;
-                                       for (i = 0; i <= s_slot;i++)
-                                       {
-                                               RCU_INIT_POINTER(dst->slot[i],
-                                                                src->slot[i]);
-                                               dst->pivot[i] = src->pivot[i];
-                                       }
-                                       d_slot = s_slot;
-                                       mas->node = mt_mk_node(mn,
-                                                              maple_leaf_64);
                                }
                                continue;
                        }
 
                        if (s_slot != 0 && src->pivot[s_slot] == 0)
-                               break;
+                               goto done;
 
                        last = src->pivot[s_slot];
+                       if (!dst)
+                               continue;
 
-                       if (dst)
-                               dst->pivot[d_slot] = src->pivot[s_slot];
-               }
-               if (dst)
+                       dst->pivot[d_slot] = src->pivot[s_slot];
+                       RCU_INIT_POINTER(dst->slot[d_slot++],
+                                       src->slot[s_slot]);
+               } else if (dst && src->slot[s_slot] != NULL) {
+                       dst->pivot[d_slot] = mas->max;
                        RCU_INIT_POINTER(dst->slot[d_slot++],
-                                        src->slot[s_slot]);
+                                       src->slot[s_slot]);
+               }
        }
-       return s_slot - d_slot;
+done:
+       if (dst)
+               ret = s_slot - d_slot;
+       return ret;
 }
 
 static void ma_adopt_children(struct maple_node *parent)