Whamcloud - gitweb
b=16098
[fs/lustre-release.git] / lustre / include / class_hash.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see [sun.com URL with a
20  * copy of GPLv2].
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #ifndef __CLASS_HASH_H
38 #define __CLASS_HASH_H
39
40 #include <lustre_lib.h>
41
42 /* #define LUSTRE_HASH_DEBUG 1 */
43
44 /* define the hash bucket*/
45 struct lustre_hash_bucket { 
46         struct hlist_head lhb_head;
47         spinlock_t lhb_lock;
48 #ifdef LUSTRE_HASH_DEBUG
49         /* the number of hash item per bucket, 
50          * it will help us to analyse the hash distribute 
51          */
52         int lhb_item_count; 
53 #endif
54 };
55
56 struct lustre_hash_operations;
57
58 struct lustre_class_hash_body {
59         char hashname[128];
60         spinlock_t lchb_lock; /* body lock */
61         struct lustre_hash_bucket *lchb_hash_tables;
62         __u32 lchb_hash_max_size; /* define the hash tables size */
63         /* define the hash operations */
64         struct lustre_hash_operations *lchb_hash_operations;
65 };
66
67 /* hash operations method define */
68 struct lustre_hash_operations {
69         __u32 (*lustre_hashfn) (struct lustre_class_hash_body *hash_body, 
70                                 void *key);
71         int   (*lustre_hash_key_compare) (void *key, 
72                                           struct hlist_node *compared_hnode);
73         /* add refcount */ 
74         void* (*lustre_hash_object_refcount_get) (struct hlist_node *hash_item);
75         /* dec refcount */
76         void  (*lustre_hash_object_refcount_put) (struct hlist_node *hash_item);
77 };
78
79 static inline struct hlist_node * 
80 lustre_hash_getitem_in_bucket_nolock(struct lustre_class_hash_body *hash_body, 
81                                      int hashent, void *key)
82 {
83         struct lustre_hash_bucket *bucket;
84         struct hlist_node  *hash_item_node;
85         struct lustre_hash_operations *hop = hash_body->lchb_hash_operations;
86         int find = 0;
87         ENTRY;
88
89         bucket = &hash_body->lchb_hash_tables[hashent];
90         hlist_for_each(hash_item_node, &(bucket->lhb_head)) {
91                 find = hop->lustre_hash_key_compare(key, hash_item_node);
92                 if (find == 1)
93                         break;
94         }
95         RETURN(find == 1 ? hash_item_node : NULL);
96 }
97
98 static inline int 
99 lustre_hash_delitem_nolock(struct lustre_class_hash_body *hash_body, 
100                            int hashent, struct hlist_node * hash_item)
101 {
102         struct lustre_hash_operations *hop = hash_body->lchb_hash_operations;
103
104         hlist_del_init(hash_item);
105
106         hop->lustre_hash_object_refcount_put(hash_item);
107
108 #ifdef LUSTRE_HASH_DEBUG
109         hash_body->lchb_hash_tables[hashent].lhb_item_count--;
110         CDEBUG(D_INFO, "hashname[%s] bucket[%d] has [%d] hashitem\n", 
111                         hash_body->hashname, hashent, 
112                         hash_body->lchb_hash_tables[hashent].lhb_item_count);
113 #endif
114
115         RETURN(0);
116 }
117
118 typedef void (*hash_item_iterate_cb) (void *obj, void *data);
119
120 int lustre_hash_init(struct lustre_class_hash_body **hash_body,
121                      char *hashname, __u32 hashsize, 
122                      struct lustre_hash_operations *hash_operations);
123 void lustre_hash_exit(struct lustre_class_hash_body **hash_body);
124 int lustre_hash_additem_unique(struct lustre_class_hash_body *hash_body, 
125                                void *key, struct hlist_node *actual_hnode);
126 void *lustre_hash_findadd_unique(struct lustre_class_hash_body *hash_body,
127                                  void *key, struct hlist_node *actual_hnode);
128 int lustre_hash_additem(struct lustre_class_hash_body *hash_body, void *key, 
129                         struct hlist_node *actual_hnode);
130 int lustre_hash_delitem_by_key(struct lustre_class_hash_body *hash_body, 
131                                void *key);
132 int lustre_hash_delitem(struct lustre_class_hash_body *hash_body, void *key, 
133                         struct hlist_node *hash_item);
134 void lustre_hash_bucket_iterate(struct lustre_class_hash_body *hash_body,
135                                 void *key, hash_item_iterate_cb,
136                                 void *data);
137 void lustre_hash_iterate_all(struct lustre_class_hash_body *hash_body,
138                              hash_item_iterate_cb, void *data);
139
140 void * lustre_hash_get_object_by_key(struct lustre_class_hash_body *hash_body,
141                                       void *key);
142
143 __u32 djb2_hashfn(struct lustre_class_hash_body *hash_body, void* key,
144                   size_t size);
145
146 /* ( uuid <-> export ) hash operations define */
147 __u32 uuid_hashfn(struct lustre_class_hash_body *hash_body,  void * key);
148 int uuid_hash_key_compare(void *key, struct hlist_node * compared_hnode);
149 void * uuid_export_refcount_get(struct hlist_node * actual_hnode);
150 void uuid_export_refcount_put(struct hlist_node * actual_hnode);
151
152 /* ( nid <-> export ) hash operations define */
153 __u32 nid_hashfn(struct lustre_class_hash_body *hash_body,  void * key);
154 int nid_hash_key_compare(void *key, struct hlist_node * compared_hnode);
155 void * nid_export_refcount_get(struct hlist_node * actual_hnode);
156 void nid_export_refcount_put(struct hlist_node * actual_hnode);
157
158 /* ( net_peer <-> connection ) hash operations define */
159 __u32 conn_hashfn(struct lustre_class_hash_body *hash_body,  void * key);
160 int conn_hash_key_compare(void *key, struct hlist_node * compared_hnode);
161 void * conn_refcount_get(struct hlist_node * actual_hnode);
162 void conn_refcount_put(struct hlist_node * actual_hnode);
163
164 /* ( nid <-> nidstats ) hash operations define. uses nid_hashfn */
165 int nidstats_hash_key_compare(void *key, struct hlist_node * compared_hnode);
166 void* nidstats_refcount_get(struct hlist_node * actual_hnode);
167 void nidstats_refcount_put(struct hlist_node * actual_hnode);
168 extern struct lustre_hash_operations nid_stat_hash_operations;
169
170 #endif /* __CLASS_HASH_H */