Merge branch 'refs/heads/t/blob'
[paraslash.git] / buffer_tree.c
index f0a7b22..8a31751 100644 (file)
@@ -1,8 +1,4 @@
-/*
- * Copyright (C) 2009-2013 Andre Noll <maan@systemlinux.org>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2009 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
 
 /** \file buffer_tree.c Buffer tree and buffer pool implementations. */
 #include <regex.h>
@@ -544,14 +540,16 @@ static bool btr_no_children(struct btr_node *btrn)
 }
 
 /**
- * Find out whether a node is an orphan node.
+ * Find out whether a node is an orphan.
  *
  * \param btrn The buffer tree node.
  *
  * \return True if \a btrn has no parent.
  *
- * This function will always return true for the root node.  However in case
- * nodes have been removed from the tree, other nodes may become orphans too.
+ * This function returns true for the root node and false for any other node.
+ *
+ * After a (non-leaf) node was removed removed from the tree, the function
+ * returns true for all child nodes.
  */
 bool btr_no_parent(struct btr_node *btrn)
 {
@@ -769,6 +767,12 @@ void btr_drain(struct btr_node *btrn)
                btr_drop_buffer_reference(br);
 }
 
+static void btr_free_node(struct btr_node *btrn)
+{
+       free(btrn->name);
+       free(btrn);
+}
+
 /**
  * Remove a node from a buffer tree.
  *
@@ -796,8 +800,7 @@ void btr_remove_node(struct btr_node **btrnp)
        btr_drain(btrn);
        if (btrn->parent)
                list_del(&btrn->node);
-       free(btrn->name);
-       free(btrn);
+       btr_free_node(btrn);
 out:
        *btrnp = NULL;
 }
@@ -833,7 +836,7 @@ size_t btr_get_input_queue_size(struct btr_node *btrn)
 /**
  * Remove a node from the buffer tree, reconnecting parent and children.
  *
- * \param btrn The node to splice out.
+ * \param btrnp The node to splice out.
  *
  * This function is used by buffer tree nodes that do not exist during the
  * whole lifetime of the buffer tree. Unlike btr_remove_node(), calling
@@ -841,9 +844,9 @@ size_t btr_get_input_queue_size(struct btr_node *btrn)
  * but reconnects the buffer tree by making all child nodes of \a btrn children
  * of the parent of \a btrn.
  */
-void btr_splice_out_node(struct btr_node *btrn)
+void btr_splice_out_node(struct btr_node **btrnp)
 {
-       struct btr_node *ch, *tmp;
+       struct btr_node *btrn = *btrnp, *ch, *tmp;
 
        assert(btrn);
        PARA_NOTICE_LOG("splicing out %s\n", btrn->name);
@@ -856,9 +859,12 @@ void btr_splice_out_node(struct btr_node *btrn)
                ch->parent = btrn->parent;
                if (btrn->parent)
                        list_move(&ch->node, &btrn->parent->children);
+               else
+                       list_del(&ch->node);
        }
        assert(list_empty(&btrn->children));
-       btrn->parent = NULL;
+       btr_free_node(btrn);
+       *btrnp = NULL;
 }
 
 /**
@@ -895,7 +901,7 @@ size_t btr_get_output_queue_size(struct btr_node *btrn)
  * \return \p -ENOTSUP if no parent node of \a btrn understands \a command.
  * Otherwise the return value of the command handler is returned.
  *
- * \sa \ref receiver::execute, filter::execute, writer::execute.
+ * \sa \ref receiver::execute, \ref filter::execute, \ref writer::execute.
  */
 int btr_exec_up(struct btr_node *btrn, const char *command, char **value_result)
 {
@@ -925,7 +931,7 @@ int btr_exec_up(struct btr_node *btrn, const char *command, char **value_result)
  *
  * \return A pointer to the \a context address specified at node creation time.
  *
- * \sa btr_new_node(), struct \ref btr_node_description.
+ * \sa \ref btr_new_node(), struct \ref btr_node_description.
  */
 void *btr_context(struct btr_node *btrn)
 {
@@ -1199,21 +1205,20 @@ int btr_node_status(struct btr_node *btrn, size_t min_iqs,
        size_t iqs;
 
        assert(btrn);
-       if (type != BTR_NT_LEAF) {
-               if (btr_no_children(btrn))
-                       return -E_BTR_NO_CHILD;
-               if (btr_get_output_queue_size(btrn) > BTRN_MAX_PENDING)
-                       return 0;
-       }
-       if (type != BTR_NT_ROOT) {
-               if (btr_eof(btrn))
-                       return -E_BTR_EOF;
-               iqs = btr_get_input_queue_size(btrn);
-               if (iqs == 0) /* we have a parent, because not eof */
-                       return 0;
-               if (iqs < min_iqs && !btr_no_parent(btrn))
-                       return 0;
-       }
+       if (type != BTR_NT_LEAF && btr_no_children(btrn))
+               return -E_BTR_NO_CHILD;
+       if (type != BTR_NT_ROOT && btr_eof(btrn))
+               return -E_BTR_EOF;
+
+       if (btr_get_output_queue_size(btrn) > BTRN_MAX_PENDING)
+               return 0;
+       if (type == BTR_NT_ROOT)
+               return 1;
+       iqs = btr_get_input_queue_size(btrn);
+       if (iqs == 0) /* we have a parent, because not eof */
+               return 0;
+       if (iqs < min_iqs && !btr_no_parent(btrn))
+               return 0;
        return 1;
 }
 
@@ -1230,6 +1235,16 @@ void btr_get_node_start(struct btr_node *btrn, struct timeval *tv)
        *tv = btrn->start;
 }
 
+/**
+ * Get the parent node of a buffer tree node.
+ *
+ * \param btrn The node whose parent should be returned.
+ *
+ * \a btrn must not be \p NULL.
+ *
+ * \return The parent of \a btrn, or \p NULL if \a btrn is the
+ * root node of the buffer tree.
+ */
 struct btr_node *btr_parent(struct btr_node *btrn)
 {
        return btrn->parent;