Permalink
Browse files

start at the significant refactor

more agnostic names were chosen for structs, and C-style inheritance
done to get specific to sorted_btree.

some code was moved into btree_common.c and btree_common_footer.h with
the idea that forward-declarations will essentially allow for callbacks
so that utilities like shrink_node and grow_node, which will be the same
for different types of btrees can call into functions like allocate_node
that need different implementations.
  • Loading branch information...
1 parent ae62e42 commit 5cbf95315968c173cd00040c2c051880ff370131 @teepark committed Jun 27, 2011
Showing with 788 additions and 598 deletions.
  1. +1 −0 .gitignore
  2. +1 −1 pavement.py
  3. +108 −0 src/btree_common.c
  4. +145 −0 src/btree_common.h
  5. +378 −0 src/btree_common_footer.h
  6. +3 −3 src/btreemodule.c
  7. +141 −514 src/sorted_btree.c
  8. +11 −80 src/sorted_btree.h
View
@@ -1,5 +1,6 @@
*.pyc
.*.swp
+.*.swo
build/*
dist/*
*.egg-info/*
View
@@ -17,7 +17,7 @@
license="BSD",
ext_modules=[Extension(
'btree',
- ['btreemodule.c', 'sorted_btree.c'],
+ ['src/btreemodule.c', 'src/sorted_btree.c', 'src/btree_common.c'],
include_dirs=())],
classifiers = [
"Development Status :: 3 - Alpha",
View
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2009-2011, Travis Parker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the author nor the names of other
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "btree_common.h"
+
+
+/*
+ * pass value[s] (and for branch nodes, child[ren]) to neighbors
+ */
+void
+btnode_pass_left(char is_branch, bt_node_t *source, bt_node_t *target, int count,
+ bt_branch_t *parent, int sep_index) {
+ if (!count) return;
+
+ /* append the parent's separator value to the target */
+ target->values[target->filled] = parent->values[sep_index];
+
+ /* use the last value to be moved from the source as the new separator */
+ parent->values[sep_index] = source->values[count - 1];
+
+ /* continue appending from the beginning of the source's values */
+ memcpy(target->values + target->filled + 1, source->values,
+ sizeof(PyObject *) * (count - 1));
+
+ /* move down the source's remaining values to the beginning */
+ memmove(source->values, source->values + count,
+ sizeof(PyObject *) * (source->filled - count));
+
+ if (is_branch) {
+ bt_branch_t *src = (bt_branch_t *)source;
+ bt_branch_t *tgt = (bt_branch_t *)target;
+
+ /* move over the same number of child nodes */
+ memcpy(tgt->children + tgt->filled + 1, src->children,
+ sizeof(bt_node_t *) * count);
+
+ /* move over the source's remaining children */
+ memmove(src->children, src->children + count,
+ sizeof(bt_node_t *) * (src->filled - count + 1));
+ }
+
+ target->filled += count;
+ source->filled -= count;
+}
+
+void
+btnode_pass_right(char is_branch, bt_node_t *source, bt_node_t *target,
+ int count, bt_branch_t *parent, int sep_index) {
+ if (!count) return;
+
+ /* make space in the target for the moved item(s) */
+ memmove(target->values + count, target->values,
+ sizeof(PyObject *) * target->filled);
+
+ /* prepend the parent's separator value to the target */
+ target->values[count - 1] = parent->values[sep_index];
+
+ /* copy the first item to be moved into the parent */
+ parent->values[sep_index] = source->values[source->filled - count];
+
+ /* copy the other items to be moved into the target */
+ memcpy(target->values, source->values + source->filled - count + 1,
+ sizeof(PyObject *) * (count - 1));
+
+ if (is_branch) {
+ bt_branch_t *src = (bt_branch_t *)source;
+ bt_branch_t *tgt = (bt_branch_t *)target;
+
+ /* make space for the same number of child nodes */
+ memmove(tgt->children + count, tgt->children,
+ sizeof(bt_node_t *) * (tgt->filled + 1));
+
+ /* move over the children from source to target */
+ memcpy(tgt->children, src->children + src->filled + 1 - count,
+ sizeof(bt_node_t *) * count);
+ }
+
+ target->filled += count;
+ source->filled -= count;
+}
View
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2009-2011, Travis Parker
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the author nor the names of other
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BT_COMMON_H
+#define BT_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "Python.h"
+#include "structmember.h"
+
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 5
+ #define Py_TYPE(ob) (((PyObject *)(ob))->ob_type)
+#endif
+
+
+/*
+ * leaves, branches and a generic bt_node_t to which they are both castable
+ */
+#define BT_NODE_HEAD \
+ int filled; \
+ PyObject **values;
+
+typedef struct {
+ BT_NODE_HEAD
+} bt_node_t;
+typedef bt_node_t bt_leaf_t;
+
+#define BT_BRANCH_HEAD \
+ BT_NODE_HEAD \
+ bt_node_t **children;
+
+typedef struct {
+ BT_BRANCH_HEAD
+} bt_branch_t;
+
+
+/*
+ * a polymorphism typedef for btree python objects
+ */
+#define BT_PYOBJECT \
+ PyObject_HEAD \
+ int order; \
+ int depth; \
+ char flags; \
+ bt_node_t *root;
+
+typedef struct {
+ BT_PYOBJECT
+} bt_pyobject;
+
+
+/*
+ * flags for btree pyobjects
+ */
+#define BT_FLAG_INITED 1
+
+
+/*
+ * the necessary info to save a position and be
+ * able to resume traversing a tree in order
+ */
+typedef struct {
+ int depth;
+ int *indexes;
+ bt_node_t **lineage;
+ bt_pyobject *tree;
+} bt_path_t;
+
+#define BT_STACK_ALLOC_PATH(treeobj) \
+ bt_path_t path; \
+ int _indexes[(treeobj)->depth + 1]; \
+ bt_node_t *_lineage[(treeobj)->depth + 1]; \
+ path.tree = (treeobj); \
+ path.indexes = _indexes; \
+ path.lineage = _lineage;
+
+
+/*
+ * a python iterator object over a bt_pyobject
+ */
+#define BT_ITERATOR_HEAD \
+ PyObject_HEAD \
+ bt_path_t *path;
+
+typedef struct {
+ BT_ITERATOR_HEAD
+} bt_iter_pyobject;
+
+
+/*
+ * visitor function signatures for handing off to traversers
+ */
+typedef int (*bt_node_visitor)(
+ bt_node_t *node, char is_branch, int depth, void *data);
+
+typedef int (*bt_item_visitor)(
+ PyObject *item, char is_branch, int depth, void *data);
+
+
+/*
+ * a printf for pyobjects for debugging
+ */
+#define PRINTF(format_str, py_object) do { \
+ PyObject *__printf_pyobj = PyObject_Repr((PyObject *)(py_object)); \
+ printf((format_str), PyString_AsString(__printf_pyobj)); \
+ Py_DECREF(__printf_pyobj); \
+} while(0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BT_COMMON_H */
Oops, something went wrong.

0 comments on commit 5cbf953

Please sign in to comment.