Whamcloud - gitweb
Update copyrights on source files changed since 2010-02-15.
[fs/lustre-release.git] / libcfs / include / libcfs / libcfs_hash.h
index 73cfe01..f94c7dc 100644 (file)
@@ -26,7 +26,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -141,6 +141,7 @@ typedef struct cfs_hash {
         struct cfs_hash_bucket    **hs_buckets;     /* hash buckets */
         struct cfs_hash_ops        *hs_ops;         /* hash operations */
         cfs_rwlock_t                hs_rwlock;      /* cfs_hash */
+        cfs_atomic_t                hs_refcount;
         char                        hs_name[CFS_MAX_HASH_NAME];
 } cfs_hash_t;
 
@@ -156,86 +157,44 @@ typedef struct cfs_hash_ops {
 #define CFS_HASH_DEBUG          0x0001  /* Enable expensive debug checks */
 #define CFS_HASH_REHASH         0x0002  /* Enable dynamic hash resizing */
 
-#define CFS_HO(hs)             (hs)->hs_ops
 #define CFS_HOP(hs, op)        (hs)->hs_ops->hs_ ## op
 
 static inline unsigned
 cfs_hash_id(cfs_hash_t *hs, void *key, unsigned mask)
 {
-        LASSERT(hs);
-        LASSERT(CFS_HO(hs));
-        LASSERT(CFS_HOP(hs, hash));
-
         return CFS_HOP(hs, hash)(hs, key, mask);
 }
 
 static inline void *
 cfs_hash_key(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
 {
-        LASSERT(hs);
-        LASSERT(hnode);
-        LASSERT(CFS_HO(hs));
-        LASSERT(CFS_HOP(hs, key));
-
         return CFS_HOP(hs, key)(hnode);
 }
 
-/* Returns 1 on a match,
- * XXX: This would be better if it returned, -1, 0, or 1 for
- *      <, =, > respectivly.  It could then be used to implement
- *      a CFS_HASH_SORT feature flags which could keep each hash
- *      bucket in order.  This would increase insertion times
- *      but could reduce lookup times for deep chains.  Ideally,
- *      the rehash should keep chain depth short but if that
- *      ends up not being the case this would be a nice feature.
- */
+/* Returns TRUE on a match. */
 static inline int
 cfs_hash_compare(cfs_hash_t *hs, void *key, cfs_hlist_node_t *hnode)
 {
-        LASSERT(hs);
-        LASSERT(hnode);
-        LASSERT(CFS_HO(hs));
-
-        if (CFS_HOP(hs, compare))
-                return CFS_HOP(hs, compare)(key, hnode);
-
-        return -EOPNOTSUPP;
+        return CFS_HOP(hs, compare)(key, hnode);
 }
 
 static inline void *
 cfs_hash_get(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
 {
-        LASSERT(hs);
-        LASSERT(hnode);
-        LASSERT(CFS_HO(hs));
-
-        if (CFS_HOP(hs, get))
-                return CFS_HOP(hs, get)(hnode);
-
-        return NULL;
+        return CFS_HOP(hs, get)(hnode);
 }
 
 static inline void *
 cfs_hash_put(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
 {
-        LASSERT(hs);
-        LASSERT(hnode);
-        LASSERT(CFS_HO(hs));
-
-        if (CFS_HOP(hs, put))
-                return CFS_HOP(hs, put)(hnode);
-
-        return NULL;
+        return CFS_HOP(hs, put)(hnode);
 }
 
 static inline void
 cfs_hash_exit(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
 {
-        LASSERT(hs);
-        LASSERT(hnode);
-        LASSERT(CFS_HO(hs));
-
-        if (CFS_HOP(hs, exit))
+        /* This is allowed to be a NOOP */
+        if (CFS_HOP(hs, exit) != NULL)
                 return CFS_HOP(hs, exit)(hnode);
 }
 
@@ -245,7 +204,7 @@ __cfs_hash_key_validate(cfs_hash_t *hs, void *key,
                         cfs_hlist_node_t *hnode)
 {
         if (unlikely(hs->hs_flags & CFS_HASH_DEBUG))
-                LASSERT(cfs_hash_compare(hs, key, hnode) > 0);
+                LASSERT(cfs_hash_compare(hs, key, hnode));
 }
 
 /* Validate hnode is in the correct bucket */
@@ -268,7 +227,7 @@ __cfs_hash_bucket_lookup(cfs_hash_t *hs,
         cfs_hlist_node_t *hnode;
 
         cfs_hlist_for_each(hnode, &hsb->hsb_head)
-                if (cfs_hash_compare(hs, key, hnode) > 0)
+                if (cfs_hash_compare(hs, key, hnode))
                         return hnode;
 
         return NULL;
@@ -304,7 +263,8 @@ __cfs_hash_bucket_del(cfs_hash_t *hs,
 cfs_hash_t *cfs_hash_create(char *name, unsigned int cur_bits,
                             unsigned int max_bits,
                             cfs_hash_ops_t *ops, int flags);
-void cfs_hash_destroy(cfs_hash_t *hs);
+cfs_hash_t *cfs_hash_getref(cfs_hash_t *hs);
+void cfs_hash_putref(cfs_hash_t *hs);
 
 /* Hash addition functions */
 void cfs_hash_add(cfs_hash_t *hs, void *key,
@@ -326,6 +286,8 @@ void cfs_hash_for_each_safe(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
 void cfs_hash_for_each_empty(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
 void cfs_hash_for_each_key(cfs_hash_t *hs, void *key,
                            cfs_hash_for_each_cb_t, void *data);
+typedef int (*cfs_hash_cond_opt_cb_t)(void *obj, void *data);
+void cfs_hash_cond_del(cfs_hash_t *hs, cfs_hash_cond_opt_cb_t, void *data);
 
 /*
  * Rehash - Theta is calculated to be the average chained