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
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]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * dict.c - simple dictionary facility
32 * We maintain a dictionary, sorted by name to facilitate rapid id lookup by
33 * name. It is used by both the restarter and graph code.
35 * Right now, the dictionary is implemented as a sorted linked list which maps
36 * instance names to graph vertex ids. It should eventually be converted to a
37 * better representation for quick lookups.
39 * For now, FMRIs are never deleted from the dictionary. A service deletion
40 * and insertion of the same instance FMRI will result in reuse of the same
41 * id. To implement dictionary entry delete, the locking strategy for graph
42 * vertex dependency linking must be checked for accuracy, as assumptions may
43 * exist that FMRI to id mapping is retained even after an instance is deleted.
54 static uu_list_pool_t
*dict_pool
;
55 dictionary_t
*dictionary
;
57 static u_longlong_t dictionary_lookups
; /* number of lookups */
58 static u_longlong_t dictionary_ns_total
; /* nanoseconds spent */
62 dict_compare(const void *lc_arg
, const void *rc_arg
, void *private)
64 const char *lc_name
= ((const dict_entry_t
*)lc_arg
)->de_name
;
65 const char *rc_name
= ((const dict_entry_t
*)rc_arg
)->de_name
;
67 return (strcmp(lc_name
, rc_name
));
71 dict_lookup_byname(const char *name
)
74 dict_entry_t
*entry
, tmp
;
75 hrtime_t now
= gethrtime();
79 (void) pthread_mutex_lock(&dictionary
->dict_lock
);
80 if ((entry
= uu_list_find(dictionary
->dict_list
, &tmp
, NULL
,
86 (void) pthread_mutex_unlock(&dictionary
->dict_lock
);
89 dictionary_ns_total
+= gethrtime() - now
;
95 * int dict_insert(char *)
96 * Returns the ID for name.
99 dict_insert(const char *name
)
101 dict_entry_t
*entry
, tmp
;
104 assert(name
!= NULL
);
108 (void) pthread_mutex_lock(&dictionary
->dict_lock
);
110 if ((entry
= uu_list_find(dictionary
->dict_list
, &tmp
, NULL
,
112 (void) pthread_mutex_unlock(&dictionary
->dict_lock
);
113 return (entry
->de_id
);
116 entry
= startd_alloc(sizeof (dict_entry_t
));
118 entry
->de_id
= dictionary
->dict_new_id
++;
119 entry
->de_name
= startd_alloc(strlen(name
) + 1);
120 (void) strcpy((char *)entry
->de_name
, name
);
122 uu_list_node_init(entry
, &entry
->de_link
, dict_pool
);
124 uu_list_insert(dictionary
->dict_list
, entry
, idx
);
125 (void) pthread_mutex_unlock(&dictionary
->dict_lock
);
127 return (entry
->de_id
);
133 dictionary
= startd_zalloc(sizeof (dictionary_t
));
135 (void) pthread_mutex_init(&dictionary
->dict_lock
, NULL
);
137 dict_pool
= startd_list_pool_create("dict", sizeof (dict_entry_t
),
138 offsetof(dict_entry_t
, de_link
), dict_compare
, UU_LIST_POOL_DEBUG
);
139 assert(dict_pool
!= NULL
);
141 dictionary
->dict_new_id
= 0;
142 dictionary
->dict_list
= startd_list_create(dict_pool
, dictionary
,
144 assert(dictionary
->dict_list
!= NULL
);