#include "para.h"
#include "list.h"
#include "string.h"
-//#include "buffer_tree.h"
+#include "buffer_tree.h"
struct btr_buffer {
* the list represents an input buffer which has not been completely
* used by this btr node.
*/
- struct list_head buffer_queue;
+ struct list_head input_queue;
};
-#define FOR_EACH_TARGET_NODE(_tn, _btrn) list_for_each_entry((_tn), \
+#define FOR_EACH_CHILD(_tn, _btrn) list_for_each_entry((_tn), \
&((_btrn)->children), node)
#define FOR_EACH_BUFFER_REF(_br, _btrn) \
- list_for_each_entry((_br), &(_btrn)->buffer_queue, node)
+ list_for_each_entry((_br), &(_btrn)->input_queue, node)
#define FOR_EACH_BUFFER_REF_SAFE(_br, _tmp, _btrn) \
- list_for_each_entry_safe((_br), (_tmp), &(_btrn)->buffer_queue, node)
-
-INIT_STDERR_LOGGING(0);
+ list_for_each_entry_safe((_br), (_tmp), &(_btrn)->input_queue, node)
struct btr_node *btr_new_node(char *name, struct btr_node *parent)
{
if (parent)
list_add_tail(&btrn->node, &parent->children);
INIT_LIST_HEAD(&btrn->children);
- INIT_LIST_HEAD(&btrn->buffer_queue);
+ INIT_LIST_HEAD(&btrn->input_queue);
return btrn;
}
+/*
+ * Allocate a new btr buffer.
+ *
+ * The freshly allocated buffer will have a zero refcount.
+ */
static struct btr_buffer *new_btrb(char *buf, size_t size)
{
struct btr_buffer *btrb = para_malloc(sizeof(*btrb));
return btrb;
}
-void btr_drop_buffer_reference(struct btr_buffer_reference *br)
+/*
+ * Deallocate the reference, release the resources if refcount drops to zero.
+ */
+static void btr_drop_buffer_reference(struct btr_buffer_reference *br)
{
struct btr_buffer *btrb = br->btrb;
}
}
-static void add_btrb_to_targets(struct btr_buffer *btrb, struct btr_node *btrn)
+static void add_btrb_to_children(struct btr_buffer *btrb, struct btr_node *btrn)
{
- struct btr_node *tn; /* target node */
+ struct btr_node *ch;
- FOR_EACH_TARGET_NODE(tn, btrn) {
+ FOR_EACH_CHILD(ch, btrn) {
struct btr_buffer_reference *br = para_malloc(sizeof(*br));
br->btrb = btrb;
br->consumed = 0;
- list_add_tail(&br->node, &tn->buffer_queue);
+ list_add_tail(&br->node, &ch->input_queue);
btrb->refcount++;
}
}
struct btr_buffer *btrb;
btrb = new_btrb(buf, size);
- add_btrb_to_targets(btrb, btrn);
+ add_btrb_to_children(btrb, btrn);
}
-void btr_pushdown_br(struct btr_buffer_reference *br, struct btr_node *btrn)
+static void btr_pushdown_br(struct btr_buffer_reference *br, struct btr_node *btrn)
{
- add_btrb_to_targets(br->btrb, btrn);
+ add_btrb_to_children(br->btrb, btrn);
btr_drop_buffer_reference(br);
}
btr_pushdown_br(br, btrn);
}
-bool btr_no_children(struct btr_node *btrn)
+/* Return true if this node has no children. */
+bool btr_is_leaf_node(struct btr_node *btrn)
{
return list_empty(&btrn->children);
}
struct btr_buffer_reference *btr_next_br(struct btr_node *btrn)
{
- if (list_empty(&btrn->buffer_queue))
+ if (list_empty(&btrn->input_queue))
return NULL;
- return list_first_entry(&btrn->buffer_queue, struct btr_buffer_reference, node);
+ return list_first_entry(&btrn->input_queue, struct btr_buffer_reference, node);
}
+
static inline size_t br_available_bytes(struct btr_buffer_reference *br)
{
return br->btrb->size - br->consumed;
void btr_del_node(struct btr_node *btrn)
{
- struct btr_node *tn;
+ struct btr_node *ch;
- FOR_EACH_TARGET_NODE(tn, btrn)
- tn->parent = NULL;
+ FOR_EACH_CHILD(ch, btrn)
+ ch->parent = NULL;
flush_input_queue(btrn);
if (btrn->parent)
list_del(&btrn->node);
return size;
}
-int main(void)
+/**
+ * Return the size of the largest input queue.
+ *
+ * Iterates over all children of the given node.
+ */
+size_t btr_bytes_pending(struct btr_node *btrn)
{
- return 1;
+ size_t max_size = 0;
+ struct btr_node *ch;
+
+ FOR_EACH_CHILD(ch, btrn) {
+ size_t size = btr_get_input_queue_size(ch);
+ max_size = PARA_MAX(max_size, size);
+ }
+ return max_size;
}