2 * This file is part of the ZFS Event Daemon (ZED).
4 * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
5 * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
6 * Refer to the OpenZFS git commit log for authoritative copyright attribution.
8 * The contents of this file are subject to the terms of the
9 * Common Development and Distribution License Version 1.0 (CDDL-1.0).
10 * You can obtain a copy of the license from the top-level file
11 * "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.
12 * You may not use this file except in compliance with the license.
21 #include <sys/sysmacros.h>
22 #include "zed_strings.h"
26 avl_node_t
*iteratorp
;
29 struct zed_strings_node
{
35 typedef struct zed_strings_node zed_strings_node_t
;
38 * Compare zed_strings_node_t nodes [x1] and [x2].
39 * As required for the AVL tree, return -1 for <, 0 for ==, and +1 for >.
42 _zed_strings_node_compare(const void *x1
, const void *x2
)
51 s1
= ((const zed_strings_node_t
*) x1
)->key
;
53 s2
= ((const zed_strings_node_t
*) x2
)->key
;
67 * Return a new string container, or NULL on error.
70 zed_strings_create(void)
74 zsp
= calloc(1, sizeof (*zsp
));
78 avl_create(&zsp
->tree
, _zed_strings_node_compare
,
79 sizeof (zed_strings_node_t
), offsetof(zed_strings_node_t
, node
));
81 zsp
->iteratorp
= NULL
;
86 * Destroy the string node [np].
89 _zed_strings_node_destroy(zed_strings_node_t
*np
)
95 if (np
->key
!= np
->val
)
107 * Return a new string node for storing the string [val], or NULL on error.
108 * If [key] is specified, it will be used to index the node; otherwise,
109 * the string [val] will be used.
111 static zed_strings_node_t
*
112 _zed_strings_node_create(const char *key
, const char *val
)
114 zed_strings_node_t
*np
;
118 np
= calloc(1, sizeof (*np
));
122 np
->val
= strdup(val
);
127 np
->key
= strdup(key
);
136 _zed_strings_node_destroy(np
);
141 * Destroy the string container [zsp] and all nodes within.
144 zed_strings_destroy(zed_strings_t
*zsp
)
147 zed_strings_node_t
*np
;
153 while ((np
= avl_destroy_nodes(&zsp
->tree
, &cookie
)))
154 _zed_strings_node_destroy(np
);
156 avl_destroy(&zsp
->tree
);
161 * Add a copy of the string [s] indexed by [key] to the container [zsp].
162 * If [key] already exists within the container [zsp], it will be replaced
163 * with the new string [s].
164 * If [key] is NULL, the string [s] will be used as the key.
165 * Return 0 on success, or -1 on error.
168 zed_strings_add(zed_strings_t
*zsp
, const char *key
, const char *s
)
170 zed_strings_node_t
*newp
, *oldp
;
179 newp
= _zed_strings_node_create(key
, s
);
183 oldp
= avl_find(&zsp
->tree
, newp
, NULL
);
185 avl_remove(&zsp
->tree
, oldp
);
186 _zed_strings_node_destroy(oldp
);
188 avl_add(&zsp
->tree
, newp
);
193 * Return the first string in container [zsp].
194 * Return NULL if there are no strings, or on error.
195 * This can be called multiple times to re-traverse [zsp].
196 * XXX: Not thread-safe.
199 zed_strings_first(zed_strings_t
*zsp
)
205 zsp
->iteratorp
= avl_first(&zsp
->tree
);
209 return (((zed_strings_node_t
*)zsp
->iteratorp
)->val
);
214 * Return the next string in container [zsp].
215 * Return NULL after the last string, or on error.
216 * This must be called after zed_strings_first().
217 * XXX: Not thread-safe.
220 zed_strings_next(zed_strings_t
*zsp
)
229 zsp
->iteratorp
= AVL_NEXT(&zsp
->tree
, zsp
->iteratorp
);
233 return (((zed_strings_node_t
*)zsp
->iteratorp
)->val
);
237 * Return the number of strings in container [zsp], or -1 on error.
240 zed_strings_count(zed_strings_t
*zsp
)
246 return (avl_numnodes(&zsp
->tree
));