ba2a08754f33a794a19309a1fd7287b749a0f9e5
7 //#include "buffer_tree.h"
13 /** The number of references to this buffer. */
17 struct btr_buffer_reference
{
18 struct btr_buffer
*btrb
;
20 /* Each buffer reference belongs to the buffer queue list of some buffer tree node. */
21 struct list_head node
;
26 struct btr_node
*parent
;
27 /* The position of this btr node in the buffer tree. */
28 struct list_head node
;
29 /* The children nodes of this btr node are linked together in a list. */
30 struct list_head children
;
32 * The input queue is a list of references to btr buffers. Each item on
33 * the list represents an input buffer which has not been completely
34 * used by this btr node.
36 struct list_head buffer_queue
;
39 #define FOR_EACH_TARGET_NODE(_tn, _btrn) list_for_each_entry((_tn), \
40 &((_btrn)->children), node)
42 #define FOR_EACH_BUFFER_REF(_br, _btrn) \
43 list_for_each_entry((_br), &(_btrn)->buffer_queue, node)
44 #define FOR_EACH_BUFFER_REF_SAFE(_br, _tmp, _btrn) \
45 list_for_each_entry_safe((_br), (_tmp), &(_btrn)->buffer_queue, node)
47 INIT_STDERR_LOGGING(0);
49 struct btr_node
*btr_new_node(char *name
, struct btr_node
*parent
)
51 struct btr_node
*btrn
= para_malloc(sizeof(*btrn
));
53 btrn
->name
= para_strdup(name
);
54 btrn
->parent
= parent
;
56 list_add_tail(&btrn
->node
, &parent
->children
);
57 INIT_LIST_HEAD(&btrn
->children
);
58 INIT_LIST_HEAD(&btrn
->buffer_queue
);
62 static struct btr_buffer
*new_btrb(char *buf
, size_t size
)
64 struct btr_buffer
*btrb
= para_malloc(sizeof(*btrb
));
72 void btr_drop_buffer_reference(struct btr_buffer_reference
*br
)
74 struct btr_buffer
*btrb
= br
->btrb
;
79 if (btrb
->refcount
== 0) {
85 static void add_btrb_to_targets(struct btr_buffer
*btrb
, struct btr_node
*btrn
)
87 struct btr_node
*tn
; /* target node */
89 FOR_EACH_TARGET_NODE(tn
, btrn
) {
90 struct btr_buffer_reference
*br
= para_malloc(sizeof(*br
));
93 list_add_tail(&br
->node
, &tn
->buffer_queue
);
98 void btr_add_output(char *buf
, size_t size
, struct btr_node
*btrn
)
100 struct btr_buffer
*btrb
;
102 btrb
= new_btrb(buf
, size
);
103 add_btrb_to_targets(btrb
, btrn
);
106 void btr_pushdown_br(struct btr_buffer_reference
*br
, struct btr_node
*btrn
)
108 add_btrb_to_targets(br
->btrb
, btrn
);
109 btr_drop_buffer_reference(br
);
112 void btr_pushdown(struct btr_node
*btrn
)
114 struct btr_buffer_reference
*br
, *tmp
;
116 FOR_EACH_BUFFER_REF_SAFE(br
, tmp
, btrn
)
117 btr_pushdown_br(br
, btrn
);
120 bool btr_no_children(struct btr_node
*btrn
)
122 return list_empty(&btrn
->children
);
125 bool btr_no_parent(struct btr_node
*btrn
)
127 return !btrn
->parent
;
130 bool btr_inplace_ok(struct btr_node
*btrn
)
134 return list_is_singular(&btrn
->parent
->children
);
137 struct btr_buffer_reference
*btr_next_br(struct btr_node
*btrn
)
139 if (list_empty(&btrn
->buffer_queue
))
141 return list_first_entry(&btrn
->buffer_queue
, struct btr_buffer_reference
, node
);
144 static inline size_t br_available_bytes(struct btr_buffer_reference
*br
)
146 return br
->btrb
->size
- br
->consumed
;
149 size_t btr_get_buffer_by_reference(struct btr_buffer_reference
*br
, char **buf
)
151 *buf
= br
->btrb
->buf
+ br
->consumed
;
152 return br_available_bytes(br
);
155 void btr_increase_used_bytes(struct btr_buffer_reference
*br
, size_t consumed
)
157 br
->consumed
+= consumed
;
158 if (br
->consumed
== br
->btrb
->size
)
159 btr_drop_buffer_reference(br
);
162 static void flush_input_queue(struct btr_node
*btrn
)
164 struct btr_buffer_reference
*br
, *tmp
;
165 FOR_EACH_BUFFER_REF_SAFE(br
, tmp
, btrn
)
166 btr_drop_buffer_reference(br
);
169 void btr_del_node(struct btr_node
*btrn
)
173 FOR_EACH_TARGET_NODE(tn
, btrn
)
175 flush_input_queue(btrn
);
177 list_del(&btrn
->node
);
182 size_t btr_get_input_queue_size(struct btr_node
*btrn
)
184 struct btr_buffer_reference
*br
;
187 FOR_EACH_BUFFER_REF(br
, btrn
)
188 size
+= br_available_bytes(br
);