sd: remove 'ssd' driver support
[unleashed/tickless.git] / usr / src / lib / udapl / libdat / common / dat_dictionary.c
blob7ea7e99d269054f296cac1e1fe9f946f9c3c3b9b
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI"
35 * MODULE: dat_dictionary.c
37 * PURPOSE: dictionary data structure
39 * $Id: dat_dictionary.c,v 1.11 2003/08/05 19:01:48 jlentini Exp $
43 #include "dat_dictionary.h"
48 * Structures
52 typedef struct DAT_DICTIONARY_NODE
54 DAT_PROVIDER_INFO key;
55 DAT_DICTIONARY_DATA data;
56 struct DAT_DICTIONARY_NODE *prev;
57 struct DAT_DICTIONARY_NODE *next;
58 } DAT_DICTIONARY_NODE;
61 struct DAT_DICTIONARY
63 DAT_DICTIONARY_NODE *head;
64 DAT_DICTIONARY_NODE *tail;
65 DAT_COUNT size;
70 * Function Declarations
74 static DAT_RETURN
75 dat_dictionary_key_dup(
76 const DAT_PROVIDER_INFO *old_key,
77 DAT_PROVIDER_INFO *new_key);
79 static DAT_BOOLEAN
80 dat_dictionary_key_is_equal(
81 const DAT_PROVIDER_INFO *key_a,
82 const DAT_PROVIDER_INFO *key_b);
87 * External Functions
93 * Function: dat_dictionary_create
96 DAT_RETURN
97 dat_dictionary_create(
98 OUT DAT_DICTIONARY **pp_dictionary)
100 DAT_DICTIONARY *p_dictionary;
101 DAT_RETURN status;
103 dat_os_assert(NULL != pp_dictionary);
105 status = DAT_SUCCESS;
107 /* create the dictionary */
108 p_dictionary = dat_os_alloc(sizeof (DAT_DICTIONARY));
109 if (NULL == p_dictionary) {
110 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
111 DAT_RESOURCE_MEMORY);
112 goto bail;
115 (void) dat_os_memset(p_dictionary, '\0', sizeof (DAT_DICTIONARY));
117 /* create the head node */
118 p_dictionary->head = dat_os_alloc(sizeof (DAT_DICTIONARY_NODE));
119 if (NULL == p_dictionary->head) {
120 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
121 DAT_RESOURCE_MEMORY);
122 goto bail;
125 (void) dat_os_memset(p_dictionary->head, '\0',
126 sizeof (DAT_DICTIONARY_NODE));
128 /* create the tail node */
129 p_dictionary->tail = dat_os_alloc(sizeof (DAT_DICTIONARY_NODE));
130 if (NULL == p_dictionary->tail) {
131 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
132 DAT_RESOURCE_MEMORY);
133 goto bail;
136 (void) dat_os_memset(p_dictionary->tail, '\0',
137 sizeof (DAT_DICTIONARY_NODE));
139 p_dictionary->head->next = p_dictionary->tail;
140 p_dictionary->tail->prev = p_dictionary->head;
142 *pp_dictionary = p_dictionary;
144 bail:
145 if (DAT_SUCCESS != status) {
146 if (NULL != p_dictionary) {
147 dat_os_free(p_dictionary, sizeof (DAT_DICTIONARY));
149 if (NULL != p_dictionary->head) {
150 dat_os_free(p_dictionary->head,
151 sizeof (DAT_DICTIONARY_NODE));
154 if (NULL != p_dictionary->tail) {
155 dat_os_free(p_dictionary->tail,
156 sizeof (DAT_DICTIONARY_NODE));
161 return (status);
166 * Function: dat_dictionary_destroy
169 DAT_RETURN
170 dat_dictionary_destroy(
171 IN DAT_DICTIONARY *p_dictionary)
173 DAT_DICTIONARY_NODE *cur_node;
175 dat_os_assert(NULL != p_dictionary);
177 while (NULL != p_dictionary->head) {
178 cur_node = p_dictionary->head;
179 p_dictionary->head = cur_node->next;
181 dat_os_free(cur_node, sizeof (DAT_DICTIONARY_NODE));
184 dat_os_free(p_dictionary, sizeof (DAT_DICTIONARY));
186 return (DAT_SUCCESS);
191 * Function: dat_dictionary_size
194 DAT_RETURN
195 dat_dictionary_size(
196 IN DAT_DICTIONARY *p_dictionary,
197 OUT DAT_COUNT *p_size)
199 dat_os_assert(NULL != p_dictionary);
200 dat_os_assert(NULL != p_size);
202 *p_size = p_dictionary->size;
204 return (DAT_SUCCESS);
209 * Function: dat_dictionary_entry_create
212 DAT_RETURN
213 dat_dictionary_entry_create(
214 OUT DAT_DICTIONARY_ENTRY *p_entry)
216 DAT_DICTIONARY_NODE *node;
217 DAT_RETURN dat_status;
219 dat_os_assert(NULL != p_entry);
221 dat_status = DAT_SUCCESS;
223 node = dat_os_alloc(sizeof (DAT_DICTIONARY_NODE));
224 if (NULL == node) {
225 dat_status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES,
226 DAT_RESOURCE_MEMORY);
227 goto bail;
230 *p_entry = node;
232 bail:
233 return (dat_status);
238 * Function: dat_dictionary_entry_destroy
241 DAT_RETURN
242 dat_dictionary_entry_destroy(
243 OUT DAT_DICTIONARY_ENTRY entry)
245 dat_os_free(entry, sizeof (DAT_DICTIONARY_NODE));
246 return (DAT_SUCCESS);
251 * Function: dat_dictionary_insert
254 DAT_RETURN
255 dat_dictionary_insert(
256 IN DAT_DICTIONARY *p_dictionary,
257 IN DAT_DICTIONARY_ENTRY entry,
258 IN const DAT_PROVIDER_INFO *key,
259 IN DAT_DICTIONARY_DATA data)
261 DAT_RETURN dat_status;
262 DAT_DICTIONARY_NODE *cur_node, *prev_node, *next_node;
264 dat_os_assert(NULL != p_dictionary);
265 dat_os_assert(NULL != entry);
267 cur_node = entry;
269 if (DAT_SUCCESS == dat_dictionary_search(p_dictionary, key, NULL)) {
270 dat_status = DAT_ERROR(DAT_PROVIDER_ALREADY_REGISTERED, 0);
271 goto bail;
274 dat_status = dat_dictionary_key_dup(key, &cur_node->key);
275 if (DAT_SUCCESS != dat_status) {
276 goto bail;
279 /* insert node at end of list to preserve registration order */
280 prev_node = p_dictionary->tail->prev;
281 next_node = p_dictionary->tail;
283 cur_node->data = data;
284 cur_node->next = next_node;
285 cur_node->prev = prev_node;
287 prev_node->next = cur_node;
288 next_node->prev = cur_node;
290 p_dictionary->size++;
292 bail:
293 return (dat_status);
298 * Function: dat_dictionary_search
301 DAT_RETURN
302 dat_dictionary_search(
303 IN DAT_DICTIONARY *p_dictionary,
304 IN const DAT_PROVIDER_INFO *key,
305 OUT DAT_DICTIONARY_DATA *p_data)
307 DAT_DICTIONARY_NODE *cur_node;
308 DAT_RETURN status;
310 dat_os_assert(NULL != p_dictionary);
312 status = DAT_ERROR(DAT_NAME_NOT_FOUND, 0);
314 for (cur_node = p_dictionary->head->next;
315 p_dictionary->tail != cur_node;
316 cur_node = cur_node->next) {
317 if (DAT_TRUE == dat_dictionary_key_is_equal(&cur_node->key,
318 key)) {
319 if (NULL != p_data) {
320 *p_data = cur_node->data;
323 status = DAT_SUCCESS;
324 goto bail;
328 bail:
329 return (status);
334 * Function: dat_dictionary_enumerate
337 DAT_RETURN
338 dat_dictionary_enumerate(
339 IN DAT_DICTIONARY *p_dictionary,
340 IN DAT_DICTIONARY_DATA array[],
341 IN DAT_COUNT array_size)
343 DAT_DICTIONARY_NODE *cur_node;
344 DAT_COUNT i;
345 DAT_RETURN status;
347 dat_os_assert(NULL != p_dictionary);
348 dat_os_assert(NULL != array);
350 status = DAT_SUCCESS;
352 if (array_size < p_dictionary->size) {
353 status = DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0);
354 goto bail;
357 for (cur_node = p_dictionary->head->next, i = 0;
358 p_dictionary->tail != cur_node;
359 cur_node = cur_node->next, i++) {
360 array[i] = cur_node->data;
363 bail:
364 return (status);
369 * Function: dat_dictionary_remove
372 DAT_RETURN
373 dat_dictionary_remove(
374 IN DAT_DICTIONARY *p_dictionary,
375 IN DAT_DICTIONARY_ENTRY *p_entry,
376 IN const DAT_PROVIDER_INFO *key,
377 OUT DAT_DICTIONARY_DATA *p_data)
379 DAT_DICTIONARY_NODE *cur_node, *prev_node, *next_node;
380 DAT_RETURN status;
382 dat_os_assert(NULL != p_dictionary);
383 dat_os_assert(NULL != p_entry);
385 status = DAT_ERROR(DAT_NAME_NOT_FOUND, 0);
387 for (cur_node = p_dictionary->head->next;
388 p_dictionary->tail != cur_node;
389 cur_node = cur_node->next) {
390 if (DAT_TRUE == dat_dictionary_key_is_equal(&cur_node->key,
391 key)) {
392 if (NULL != p_data) {
393 *p_data = cur_node->data;
396 prev_node = cur_node->prev;
397 next_node = cur_node->next;
399 prev_node->next = next_node;
400 next_node->prev = prev_node;
402 *p_entry = cur_node;
404 p_dictionary->size--;
406 status = DAT_SUCCESS;
407 goto bail;
411 bail:
412 return (status);
418 * Internal Function Definitions
424 * Function: dat_dictionary_key_create
427 DAT_RETURN
428 dat_dictionary_key_dup(
429 const DAT_PROVIDER_INFO *old_key,
430 DAT_PROVIDER_INFO *new_key)
432 dat_os_assert(NULL != old_key);
433 dat_os_assert(NULL != new_key);
435 (void) dat_os_strncpy(new_key->ia_name, old_key->ia_name,
436 DAT_NAME_MAX_LENGTH);
437 new_key->dapl_version_major = old_key->dapl_version_major;
438 new_key->dapl_version_minor = old_key->dapl_version_minor;
439 new_key->is_thread_safe = old_key->is_thread_safe;
441 return (DAT_SUCCESS);
446 * Function: dat_dictionary_key_is_equal
449 DAT_BOOLEAN
450 dat_dictionary_key_is_equal(
451 const DAT_PROVIDER_INFO *key_a,
452 const DAT_PROVIDER_INFO *key_b)
454 if ((dat_os_strlen(key_a->ia_name) == dat_os_strlen(key_b->ia_name)) &&
455 (!dat_os_strncmp(key_a->ia_name, key_b->ia_name,
456 dat_os_strlen(key_a->ia_name))) &&
457 (key_a->dapl_version_major == key_b->dapl_version_major) &&
458 (key_a->dapl_version_minor == key_b->dapl_version_minor) &&
459 (key_a->is_thread_safe == key_b->is_thread_safe)) {
460 return (DAT_TRUE);
461 } else {
462 return (DAT_FALSE);