Loading...
src/radix_tree_internal.h /dev/null libmalloc-166.200.60
--- /dev/null
+++ libmalloc/libmalloc-166.200.60/src/radix_tree_internal.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2015 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef __RADIX_TREE_INTERNAL_H
+#define __RADIX_TREE_INTERNAL_H
+
+#include <radix_tree.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#define RADIX_LABEL_BITS 11 //max number of label bits per edge
+#define RADIX_TREE_KEY_BITS (64 - 12) //number of keybits we use (starting from MSB)
+
+struct radix_edge {
+    unsigned label : RADIX_LABEL_BITS;
+    unsigned index : 16;
+    unsigned labelBits : 4;
+    unsigned isLeaf : 1;
+};
+
+_Static_assert(sizeof(struct radix_edge) == 4, "size of radix_edge must be 4");
+
+struct radix_node {
+    union {
+        struct { 
+            struct radix_edge edges[2];
+        };
+		struct {
+			uint64_t stackid : 32;
+			uint64_t size : 32;
+		};
+        struct { 
+            uint16_t next_free;
+            bool next_free_is_initialized;
+        };
+		uint64_t as_u64;
+    };
+};
+
+_Static_assert(sizeof(struct radix_node) == 8, "size of radix_node must be 8");
+
+
+struct radix_tree {
+	char header[8];
+	uint32_t leaf_size_shift;
+    uint32_t num_nodes;
+    uint32_t next_free;
+    struct radix_node nodes[];
+};
+
+static inline
+uint64_t
+leaf_size(struct radix_tree *tree, struct radix_node *node)
+{
+	return ((uint64_t)node->size) << tree->leaf_size_shift;
+}
+
+static inline
+void
+set_leaf_size(struct radix_tree *tree, struct radix_node *node, uint64_t size)
+{
+	node->size = size >> tree->leaf_size_shift;
+	assert(leaf_size(tree, node) == size);
+}
+
+
+/*
+ * Does this edge even exist?
+ */
+static inline 
+bool 
+edge_valid(struct radix_edge *edge) 
+{
+    return edge->labelBits != 0;
+}
+
+/*
+ * Read the most significant labelBits out of (key << keyshift)
+ */
+static inline 
+unsigned
+keybits(uint64_t key, int labelBits, int keyshift)
+{
+    uint64_t mask = (1 << labelBits) - 1;
+    return (unsigned) (key >> (64 - labelBits - keyshift)) & mask;
+}
+
+/*
+ * Add labelBits to key.
+ */
+static inline
+uint64_t
+extend_key(uint64_t key, int labelBits, int keyshift, uint64_t label) {
+	uint64_t mask __unused = (1 << labelBits) - 1;
+	assert((label & ~mask) == 0);
+	int shift = 64 - keyshift - labelBits; // [ keyshift | labelbits | 64 - keyshift - labelbits ]
+	assert((key & (mask << shift)) == 0);
+	return key | (label << shift);
+}
+
+/*
+ * Return true if exact radix tree traversal should follow this edge.
+ * That is, return true if the edge label matches the key bits exactly.
+ */
+static inline 
+bool 
+edge_matches(struct radix_edge *edge, uint64_t key, int keyshift) 
+{
+    if (!edge_valid(edge)) {
+        return false;
+    }
+    return keybits(key, edge->labelBits, keyshift) == edge->label;
+}
+
+
+/*
+ * Count the number of most-significant bits that (key << keyshift) has in
+ * common with edge.
+ */
+static inline 
+int 
+count_matching_bits(struct radix_edge *edge, uint64_t key, int keyshift)
+{
+    int labelBits = edge->labelBits;
+    uint64_t label = edge->label; 
+    while (labelBits) {
+        if (keybits(key, labelBits, keyshift) == label) { 
+            return labelBits; 
+        } 
+        labelBits--; 
+        label >>= 1;
+    }
+    return 0;
+}
+
+/*
+ * Lookup a radix tree node by index.  Returns NULL for invalid index.
+ */
+static inline 
+struct radix_node *
+getnode(struct radix_tree *tree, unsigned index)
+{ 
+    if (index > tree->num_nodes) {
+        return NULL;
+    } else { 
+        return &tree->nodes[index];
+    }
+}
+
+/*
+ * Initialize a radix tree in a new buffer
+ */
+struct radix_tree *
+radix_tree_init(void *buf, size_t size);
+
+
+/*
+ * Print a representation of a radix tree to stdout.
+ */
+void
+radix_tree_print(struct radix_tree *tree);
+
+/*
+ * Check a radix tree for consistency.  Returns true if everything is ok.
+ */
+bool
+radix_tree_fsck(struct radix_tree *tree);
+
+
+#endif