Changeset f2da0bb in mainline for uspace/app/bithenge/tree.c


Ignore:
Timestamp:
2012-06-24T19:24:35Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
04a7435f
Parents:
0d1a8fd
Message:

Bithenge: use reference counting for nodes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bithenge/tree.c

    r0d1a8fd rf2da0bb  
    4848}
    4949
    50 /** Destroy a node.
    51  * @memberof bithenge_node_t
    52  * @param node The node to destroy.
    53  * @return EOK on success or an error code from errno.h. */
    54 int bithenge_node_destroy(bithenge_node_t *node)
     50static int node_destroy(bithenge_node_t *node)
    5551{
    5652        switch (bithenge_node_type(node)) {
     
    7268}
    7369
     70/** Decrement a node's reference count and free it if appropriate.
     71 * @memberof bithenge_node_t
     72 * @param node The node to dereference, or NULL.
     73 * @return EOK on success or an error code from errno.h. */
     74int bithenge_node_dec_ref(bithenge_node_t *node)
     75{
     76        if (!node)
     77                return EOK;
     78        if (--node->refs == 0)
     79                return node_destroy(node);
     80        return EOK;
     81}
     82
    7483typedef struct
    7584{
     
    8392{
    8493        return (simple_internal_node_t *)node;
     94}
     95
     96static bithenge_node_t *simple_as_node(simple_internal_node_t *node)
     97{
     98        return &node->base;
    8599}
    86100
     
    102116        int rc;
    103117        simple_internal_node_t *node = node_as_simple(base);
    104         for (bithenge_int_t i = 0; i < node->len; i++) {
    105                 rc = bithenge_node_destroy(node->nodes[2*i+0]);
    106                 if (rc != EOK)
    107                         return rc;
    108                 rc = bithenge_node_destroy(node->nodes[2*i+1]);
     118        for (bithenge_int_t i = 0; i < 2 * node->len; i++) {
     119                rc = bithenge_node_dec_ref(node->nodes[i]);
    109120                if (rc != EOK)
    110121                        return rc;
     
    121132};
    122133
    123 static bithenge_node_t *simple_internal_as_node(simple_internal_node_t *node)
    124 {
    125         return &node->base;
    126 }
    127 
    128 /** Create an internal node from a set of keys and values. The node must be
    129  * freed with @a bithenge_node_t::bithenge_node_destroy after it is used, which
    130  * will also destroy all the key and value nodes.
     134/** Create an internal node from a set of keys and values. This function takes
     135 * ownership of a reference to the key and value nodes, and optionally the
     136 * array @a nodes.
    131137 * @memberof bithenge_node_t
    132138 * @param[out] out Stores the created internal node.
     
    135141 * @param len The number of key-value pairs in the node array.
    136142 * @param needs_free If true, when the internal node is destroyed it will free
    137  * the nodes array as well as destroying each node inside it.
     143 * the nodes array rather than just dereferencing each node inside it.
    138144 * @return EOK on success or an error code from errno.h. */
    139145int bithenge_new_simple_internal_node(bithenge_node_t **out,
     
    142148        assert(out);
    143149        simple_internal_node_t *node = malloc(sizeof(*node));
    144         if (!node)
     150        if (!node) {
     151                for (bithenge_int_t i = 0; i < 2 * len; i++)
     152                        bithenge_node_dec_ref(nodes[i]);
     153                if (needs_free)
     154                        free(nodes);
    145155                return ENOMEM;
     156        }
    146157        node->base.type = BITHENGE_NODE_INTERNAL;
     158        node->base.refs = 1;
    147159        node->base.internal_ops = &simple_internal_node_ops;
    148160        node->nodes = nodes;
    149161        node->len = len;
    150162        node->needs_free = needs_free;
    151         *out = simple_internal_as_node(node);
    152         return EOK;
    153 }
    154 
    155 static bithenge_node_t false_node = { BITHENGE_NODE_BOOLEAN, .boolean_value = false };
    156 static bithenge_node_t true_node = { BITHENGE_NODE_BOOLEAN, .boolean_value = true };
    157 
    158 /** Create a boolean node. The node must be freed with @a
    159  * bithenge_node_t::bithenge_node_destroy after it is used.
     163        *out = simple_as_node(node);
     164        return EOK;
     165}
     166
     167static bithenge_node_t false_node = { BITHENGE_NODE_BOOLEAN, 1, .boolean_value = false };
     168static bithenge_node_t true_node = { BITHENGE_NODE_BOOLEAN, 1, .boolean_value = true };
     169
     170/** Create a boolean node.
    160171 * @memberof bithenge_node_t
    161172 * @param[out] out Stores the created boolean node.
     
    166177        assert(out);
    167178        *out = value ? &true_node : &false_node;
    168         return EOK;
    169 }
    170 
    171 /** Create an integer node. The node must be freed with @a
    172  * bithenge_node_t::bithenge_node_destroy after it is used.
     179        (*out)->refs++;
     180        return EOK;
     181}
     182
     183/** Create an integer node.
    173184 * @memberof bithenge_node_t
    174185 * @param[out] out Stores the created integer node.
     
    182193                return ENOMEM;
    183194        node->type = BITHENGE_NODE_INTEGER;
     195        node->refs = 1;
    184196        node->integer_value = value;
    185197        *out = node;
     
    187199}
    188200
    189 /** Create a string node. The node must be freed with @a
    190  * bithenge_node_t::bithenge_node_destroy after it is used.
     201/** Create a string node.
    191202 * @memberof bithenge_node_t
    192203 * @param[out] out Stores the created string node.
     
    202213                return ENOMEM;
    203214        node->type = BITHENGE_NODE_STRING;
     215        node->refs = 1;
    204216        node->string_value.ptr = value;
    205217        node->string_value.needs_free = needs_free;
Note: See TracChangeset for help on using the changeset viewer.