1 /*****************************************************************************
2 * Copyright (C) 2004 The Regents of the University of California.
3 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
4 * Written by Jim Garlick <garlick@llnl.gov>
5 * UCRL-CODE-2002-008.
6 *
7 * This file is part of PowerMan, a remote power management program.
8 * For details, see http://code.google.com/p/powerman/
9 *
10 * PowerMan is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 * PowerMan is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with PowerMan; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 \*****************************************************************************/
24
25 /* Args used to be stored in a List, but gprof showed that very large
26 * configurations spent a lot of time doing linear search of arg list for
27 * each arg->state update. The List was traded for a hash, but as we still
28 * want to iterate through args in the client in order, we keep the hostlist
29 * representation of the nodes in the ArgList, and use it to implement an
30 * 'iterator' interface.
31 */
32
33 #if HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36 #include <errno.h>
37 #include <sys/time.h>
38 #include <time.h>
39 #include <fcntl.h>
40 #include <ctype.h>
41 #include <string.h>
42 #include <stdarg.h>
43 #include <assert.h>
44 #include <unistd.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47
48 #include "list.h"
49 #include "xmalloc.h"
50 #include "hostlist.h"
51 #include "hash.h"
52 #include "arglist.h"
53
54 struct arglist_iterator {
55 hostlist_iterator_t itr;
56 ArgList arglist;
57 };
58
59 struct arglist {
60 hash_t args;
61 hostlist_t hl;
62 int refcount; /* free when refcount == 0 */
63 };
64
_destroy_arg(Arg * arg)65 static void _destroy_arg(Arg * arg)
66 {
67 assert(arg != NULL);
68 assert(arg->node != NULL);
69 xfree(arg->node);
70 if (arg->val)
71 xfree(arg->val);
72 xfree(arg);
73 }
74
_create_arg(char * node)75 static Arg *_create_arg(char *node)
76 {
77 Arg *arg = (Arg *) xmalloc(sizeof(Arg));
78
79 arg->node = xstrdup(node);
80 arg->state = ST_UNKNOWN;
81 arg->val = NULL;
82
83 return arg;
84 }
85
arglist_create(hostlist_t hl)86 ArgList arglist_create(hostlist_t hl)
87 {
88 ArgList new = (ArgList) xmalloc(sizeof(struct arglist));
89 hostlist_iterator_t itr;
90 char *node;
91 int hash_size;
92
93 new->refcount = 1;
94 hash_size = hostlist_count(hl); /* reasonable? */
95 new->args = hash_create(hash_size, (hash_key_f)hash_key_string,
96 (hash_cmp_f)strcmp, (hash_del_f)_destroy_arg);
97
98 if ((itr = hostlist_iterator_create(hl)) == NULL) {
99 arglist_unlink(new);
100 return NULL;
101 }
102 while ((node = hostlist_next(itr)) != NULL) {
103 Arg *arg = _create_arg(node);
104
105 hash_insert(new->args, arg->node, arg);
106 free(node); /* hostlist_next strdups returned string */
107 }
108 hostlist_iterator_destroy(itr);
109 new->hl = hostlist_copy(hl);
110
111 return new;
112 }
113
arglist_unlink(ArgList arglist)114 void arglist_unlink(ArgList arglist)
115 {
116 if (--arglist->refcount == 0) {
117 hash_destroy(arglist->args);
118 hostlist_destroy(arglist->hl);
119 xfree(arglist);
120 }
121 }
122
arglist_link(ArgList arglist)123 ArgList arglist_link(ArgList arglist)
124 {
125 arglist->refcount++;
126
127 return arglist;
128 }
129
arglist_find(ArgList arglist,char * node)130 Arg *arglist_find(ArgList arglist, char *node)
131 {
132 Arg *arg = NULL;
133
134 if (node != NULL)
135 arg = hash_find(arglist->args, node);
136
137 return arg;
138 }
139
arglist_iterator_create(ArgList arglist)140 ArgListIterator arglist_iterator_create(ArgList arglist)
141 {
142 ArgListIterator itr = (ArgListIterator)xmalloc(sizeof(struct arglist_iterator));
143
144 itr->arglist = arglist;
145 itr->itr = hostlist_iterator_create(arglist->hl);
146
147 return itr;
148 }
149
arglist_iterator_destroy(ArgListIterator itr)150 void arglist_iterator_destroy(ArgListIterator itr)
151 {
152 hostlist_iterator_destroy(itr->itr);
153 xfree(itr);
154 }
155
arglist_next(ArgListIterator itr)156 Arg *arglist_next(ArgListIterator itr)
157 {
158 Arg *arg = NULL;
159 char *node;
160
161 node = hostlist_next(itr->itr);
162 if (node != NULL) {
163 arg = hash_find(itr->arglist->args, node);
164 free(node); /* hostlist_next strdups returned string */
165 }
166
167 return arg;
168 }
169
170 /*
171 * vi:tabstop=4 shiftwidth=4 expandtab
172 */
173