summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitri Pal <dpal@redhat.com>2009-09-10 18:02:51 -0400
committerStephen Gallagher <sgallagh@redhat.com>2009-09-11 12:14:27 -0400
commitf17121ad06de80f28dce98e89851da339963bbe1 (patch)
tree12066bf6ba8ad50744b56f1d67f9190d89b62b4a
parentf39d300e6b42ef3e86da6c4d3e5db68703023463 (diff)
downloadsssd-f17121ad06de80f28dce98e89851da339963bbe1.tar.gz
sssd-f17121ad06de80f28dce98e89851da339963bbe1.tar.xz
sssd-f17121ad06de80f28dce98e89851da339963bbe1.zip
COLLECTION Functions to deal with hash
The hashing logic was internal to the collection item. But if someone wants to effectively deal with the items and compare the property to a string he should compare hashes first. But it was not possible without the provided functions. As a result some of the ELAPI modules had to take advantage of knowledge of the item structure. This is bad. So this patch lays foundation for refactoring of the ELAPI code that was using internals of the item directly (file_util.c mostly). Also patch adds a unit test that was required for testing new functionality and for ticket #83
-rw-r--r--common/collection/collection.c57
-rw-r--r--common/collection/collection.h10
-rw-r--r--common/collection/collection_ut.c21
3 files changed, 71 insertions, 17 deletions
diff --git a/common/collection/collection.c b/common/collection/collection.c
index e87523757..bccb50df5 100644
--- a/common/collection/collection.c
+++ b/common/collection/collection.c
@@ -241,19 +241,12 @@ static int col_allocate_item(struct collection_item **ci, const char *property,
return ENOMEM;
}
- item->phash = FNV1a_base;
- item->property_len = 0;
-
- while (property[item->property_len] != 0) {
- item->phash = item->phash ^ toupper(property[item->property_len]);
- item->phash *= FNV1a_prime;
- item->property_len++;
- }
-
+ item->phash = col_make_hash(property, &(item->property_len));
TRACE_INFO_NUMBER("Item hash", item->phash);
TRACE_INFO_NUMBER("Item property length", item->property_len);
TRACE_INFO_NUMBER("Item property strlen", strlen(item->property));
+
/* Deal with data */
item->data = malloc(length);
if (item->data == NULL) {
@@ -2873,14 +2866,10 @@ int col_modify_item(struct collection_item *item,
}
/* Update property length and hash if we rename the property */
- item->phash = FNV1a_base;
- item->property_len = 0;
-
- while (property[item->property_len] != 0) {
- item->phash = item->phash ^ toupper(property[item->property_len]);
- item->phash *= FNV1a_prime;
- item->property_len++;
- }
+ item->phash = col_make_hash(property, &(item->property_len));
+ TRACE_INFO_NUMBER("Item hash", item->phash);
+ TRACE_INFO_NUMBER("Item property length", item->property_len);
+ TRACE_INFO_NUMBER("Item property strlen", strlen(item->property));
}
@@ -3343,3 +3332,37 @@ void *col_get_item_data(struct collection_item *ci)
{
return ci->data;
}
+
+/* Get hash */
+uint64_t col_get_item_hash(struct collection_item *ci)
+{
+ return ci->phash;
+}
+
+/* Calculates hash of the string using internal hashing
+ * algorithm. Populates "length" with length
+ * of the string not counting 0.
+ * Length argument can be NULL.
+ */
+uint64_t col_make_hash(const char *string, int *length)
+{
+ uint64_t hash = 0;
+ int str_len = 0;
+
+ TRACE_FLOW_STRING("col_make_hash called for string:", string);
+
+ if (string) {
+ hash = FNV1a_base;
+ while (string[str_len] != 0) {
+ hash = hash ^ toupper(string[str_len]);
+ hash *= FNV1a_prime;
+ str_len++;
+ }
+ }
+
+ if (length) *length = str_len;
+
+ TRACE_FLOW_NUMBER("col_make_hash returning hash:", hash);
+
+ return hash;
+}
diff --git a/common/collection/collection.h b/common/collection/collection.h
index 1ff038e15..dc59ea2f9 100644
--- a/common/collection/collection.h
+++ b/common/collection/collection.h
@@ -22,6 +22,8 @@
#ifndef COLLECTION_H
#define COLLECTION_H
+#include <stdint.h>
+
#ifndef EOK
#define EOK 0
#endif
@@ -490,6 +492,14 @@ const char *col_get_item_property(struct collection_item *ci, int *property_len)
int col_get_item_type(struct collection_item *ci);
int col_get_item_length(struct collection_item *ci);
void *col_get_item_data(struct collection_item *ci);
+uint64_t col_get_item_hash(struct collection_item *ci);
+
+/* Calculates hash of the string using internal hashing
+ * algorithm. Populates "length" with length
+ * of the string not counting 0.
+ * Length argument can be NULL.
+ */
+uint64_t col_make_hash(const char *string, int *length);
/* If you want to modify the item that you got as a result of iterating through collection
* or by calling col_get_item(). If you want to rename item provide a new name in the property
diff --git a/common/collection/collection_ut.c b/common/collection/collection_ut.c
index f1ec905ae..050c6ef1e 100644
--- a/common/collection/collection_ut.c
+++ b/common/collection/collection_ut.c
@@ -592,6 +592,7 @@ int iterator_test(void)
char binary_dump[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
int depth = 0;
int idepth = 0;
+ int len = 0;
printf("\n\n==== ITERATOR TEST ====\n\n");
@@ -767,6 +768,26 @@ int iterator_test(void)
col_destroy_collection(peer);
return error;
}
+
+ printf("Item name: %s\n", col_get_item_property(item, NULL));
+ printf("Item hash: %lu\n", (unsigned long int)col_get_item_hash(item));
+ error = col_modify_item_property(item, "new_name");
+ if (error) {
+ printf("We expected success but got error %d\n", error);
+ col_unbind_iterator(iterator);
+ col_destroy_collection(peer);
+ return error;
+ }
+ len = 0;
+ printf("Item name: %s\n", col_get_item_property(item, &len));
+ printf("Item hash: %lu\n", (unsigned long int)col_get_item_hash(item));
+ printf("Item length: %d\n", len);
+
+ len = 0;
+ printf("String name: %s\n", "new_name");
+ printf("String hash: %lu\n", (unsigned long int)col_make_hash("new_name", &len));
+ printf("String length: %d\n", len);
+
}
}
while(1);