diff --git a/compat/sys/tree.3 b/compat/sys/tree.3 index ffb39ef..ead02ea 100644 --- a/compat/sys/tree.3 +++ b/compat/sys/tree.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tree.3,v 1.20 2009/01/28 12:22:48 stsp Exp $ +.\" $OpenBSD: tree.3,v 1.26 2014/09/08 01:27:55 schwarze Exp $ .\"/* .\" * Copyright 2002 Niels Provos .\" * All rights reserved. @@ -23,7 +23,7 @@ .\" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" */ -.Dd $Mdocdate: January 28 2009 $ +.Dd $Mdocdate: September 8 2014 $ .Dt TREE 3 .Os .Sh NAME @@ -63,13 +63,15 @@ .Nm RB_RIGHT , .Nm RB_PARENT , .Nm RB_FOREACH , +.Nm RB_FOREACH_SAFE , .Nm RB_FOREACH_REVERSE , +.Nm RB_FOREACH_REVERSE_SAFE , .Nm RB_INIT , .Nm RB_INSERT , .Nm RB_REMOVE -.Nd "implementations of splay and red-black trees" +.Nd implementations of splay and red-black trees .Sh SYNOPSIS -.Fd #include +.In sys/tree.h .Pp .Fn SPLAY_PROTOTYPE "NAME" "TYPE" "FIELD" "CMP" .Fn SPLAY_GENERATE "NAME" "TYPE" "FIELD" "CMP" @@ -130,7 +132,9 @@ .Ft "struct TYPE *" .Fn RB_PARENT "struct TYPE *elm" "RB_ENTRY NAME" .Fn RB_FOREACH "VARNAME" "NAME" "RB_HEAD *head" +.Fn RB_FOREACH_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME" .Fn RB_FOREACH_REVERSE "VARNAME" "NAME" "RB_HEAD *head" +.Fn RB_FOREACH_REVERSE_SAFE "VARNAME" "NAME" "RB_HEAD *head" "TEMP_VARNAME" .Ft void .Fn RB_INIT "RB_HEAD *head" .Ft "struct TYPE *" @@ -258,6 +262,11 @@ The macro inserts the new element .Fa elm into the tree. +Upon success, +.Va NULL +is returned. +If a matching element already exists in the tree, the insertion is +aborted, and a pointer to the existing element is returned. .Pp The .Fn SPLAY_REMOVE @@ -265,6 +274,11 @@ macro removes the element .Fa elm from the tree pointed by .Fa head . +Upon success, a pointer to the removed element is returned. +.Va NULL +is returned if +.Fa elm +is not present in the tree. .Pp The .Fn SPLAY_FIND @@ -405,6 +419,9 @@ macro removes the element .Fa elm from the tree pointed by .Fa head . +.Fn RB_REMOVE +returns +.Fa elm . .Pp The .Fn RB_FIND @@ -443,6 +460,18 @@ macros: RB_FOREACH(np, NAME, &head) .Ed .Pp +The macros +.Fn RB_FOREACH_SAFE +and +.Fn RB_FOREACH_REVERSE_SAFE +traverse the tree referenced by head +in a forward or reverse direction respectively, +assigning each element in turn to np. +However, unlike their unsafe counterparts, +they permit both the removal of np +as well as freeing it from within the loop safely +without interfering with the traversal. +.Pp The .Fn RB_EMPTY macro should be used to check whether a red-black tree is empty. @@ -543,22 +572,6 @@ for (var = SPLAY_MIN(NAME, &head); var != NULL; var = nxt) { free(var); } .Ed -.Pp -Both -.Fn RB_INSERT -and -.Fn SPLAY_INSERT -return -.Va NULL -if the element was inserted in the tree successfully, otherwise they -return a pointer to the element with the colliding key. -.Pp -Accordingly, -.Fn RB_REMOVE -and -.Fn SPLAY_REMOVE -return the pointer to the removed element, otherwise they return -.Va NULL -to indicate an error. .Sh AUTHORS -The author of the tree macros is Niels Provos. +The author of the tree macros is +.An Niels Provos . diff --git a/compat/sys/tree.h b/compat/sys/tree.h index 08b1b2e..80d0f53 100644 --- a/compat/sys/tree.h +++ b/compat/sys/tree.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tree.h,v 1.11 2008/05/11 22:19:09 millert Exp $ */ +/* $OpenBSD: tree.h,v 1.13 2011/07/09 00:19:45 pirofti Exp $ */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -329,7 +329,7 @@ struct { \ } while (0) #ifndef RB_AUGMENT -#define RB_AUGMENT(x) +#define RB_AUGMENT(x) do {} while (0) #endif #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ @@ -730,9 +730,19 @@ name##_RB_MINMAX(struct name *head, int val) \ (x) != NULL; \ (x) = name##_RB_NEXT(x)) +#define RB_FOREACH_SAFE(x, name, head, y) \ + for ((x) = RB_MIN(name, head); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \ + (x) = (y)) + #define RB_FOREACH_REVERSE(x, name, head) \ for ((x) = RB_MAX(name, head); \ (x) != NULL; \ (x) = name##_RB_PREV(x)) +#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ + for ((x) = RB_MAX(name, head); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \ + (x) = (y)) + #endif /* _SYS_TREE_H_ */