X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Ftree.h;h=e96d1fa12e5ab7c49ab58656864db69d0e1e1f31;hb=4b2be143cd5ab216c6a7ebd8715b732169077e5d;hp=146d35d56ecbcf7a5957386856f36279eb5c8d18;hpb=5b21bdabe43611385d1d55a21d5b1f607b133d29;p=ffmpeg diff --git a/libavutil/tree.h b/libavutil/tree.h index 146d35d56ec..e96d1fa12e5 100644 --- a/libavutil/tree.h +++ b/libavutil/tree.h @@ -19,21 +19,24 @@ */ /** - * @file tree.h + * @file libavutil/tree.h * A tree container. + * Insertion, removal, finding equal, largest which is smaller than and + * smallest which is larger than, all have O(log n) worst case complexity. * @author Michael Niedermayer */ -#ifndef FFMPEG_TREE_H -#define FFMPEG_TREE_H +#ifndef AVUTIL_TREE_H +#define AVUTIL_TREE_H struct AVTreeNode; +extern const int av_tree_node_size; /** * Finds an element. * @param root a pointer to the root node of the tree - * @param next If next is not NULL then next[0] will contain the previous - * element and next[1] the next element if either does not exist + * @param next If next is not NULL, then next[0] will contain the previous + * element and next[1] the next element. If either does not exist, * then the corresponding entry in next is unchanged. * @return An element with cmp(key, elem)==0 or NULL if no such element exists in * the tree. @@ -41,18 +44,39 @@ struct AVTreeNode; void *av_tree_find(const struct AVTreeNode *root, void *key, int (*cmp)(void *key, const void *b), void *next[2]); /** - * Finds a element for which cmp(key, elem)==0, if no such element is found key - * is inserted into the tree. - * @param rootp A pointer to a pointer to the root node of the tree. Note that + * Inserts or removes an element. + * If *next is NULL, then the supplied element will be removed if it exists. + * If *next is not NULL, then the supplied element will be inserted, unless + * it already exists in the tree. + * @param rootp A pointer to a pointer to the root node of the tree; note that * the root node can change during insertions, this is required * to keep the tree balanced. - * - * @return If no insertion happened, the found element. - * If an insertion happened, then either key or NULL will be returned. + * @param next Used to allocate and free AVTreeNodes. For insertion the user + * must set it to an allocated and zeroed object of at least + * av_tree_node_size bytes size. av_tree_insert() will set it to + * NULL if it has been consumed. + * For deleting elements *next is set to NULL by the user and + * av_tree_node_size() will set it to the AVTreeNode which was + * used for the removed element. + * This allows the use of flat arrays, which have + * lower overhead compared to many malloced elements. + * You might want to define a function like: + * @code + * void *tree_insert(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b), AVTreeNode **next){ + * if(!*next) *next= av_mallocz(av_tree_node_size); + * return av_tree_insert(rootp, key, cmp, next); + * } + * void *tree_remove(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b, AVTreeNode **next)){ + * if(*next) av_freep(next); + * return av_tree_insert(rootp, key, cmp, next); + * } + * @endcode + * @return If no insertion happened, the found element; if an insertion or + * removal happened, then either key or NULL will be returned. * Which one it is depends on the tree state and the implementation. You * should make no assumptions that it's one or the other in the code. */ -void *av_tree_insert(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b)); +void *av_tree_insert(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b), struct AVTreeNode **next); void av_tree_destroy(struct AVTreeNode *t); -#endif /* FFMPEG_TREE_H */ +#endif /* AVUTIL_TREE_H */