/*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
#include <openssl/crypto.h>
#include <openssl/lhash.h>
#include <openssl/err.h>
-#include "lhash_lcl.h"
+#include "crypto/ctype.h"
+#include "crypto/lhash.h"
+#include "lhash_local.h"
/*
* A hashing implementation that appears to be based on the linear hashing
- * alogrithm:
+ * algorithm:
* https://en.wikipedia.org/wiki/Linear_hashing
*
* Litwin, Witold (1980), "Linear hashing: A new tool for file and table
* addressing", Proc. 6th Conference on Very Large Databases: 212-223
- * http://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf
+ * https://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf
*
- * From the wikipedia article "Linear hashing is used in the BDB Berkeley
+ * From the Wikipedia article "Linear hashing is used in the BDB Berkeley
* database system, which in turn is used by many software systems such as
* OpenLDAP, using a C implementation derived from the CACM article and first
* published on the Usenet in 1988 by Esmond Pitt."
}
void OPENSSL_LH_free(OPENSSL_LHASH *lh)
+{
+ if (lh == NULL)
+ return;
+
+ OPENSSL_LH_flush(lh);
+ OPENSSL_free(lh->b);
+ OPENSSL_free(lh);
+}
+
+void OPENSSL_LH_flush(OPENSSL_LHASH *lh)
{
unsigned int i;
OPENSSL_LH_NODE *n, *nn;
OPENSSL_free(n);
n = nn;
}
+ lh->b[i] = NULL;
}
- OPENSSL_free(lh->b);
- OPENSSL_free(lh);
}
void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data)
OPENSSL_LH_NODE **rn;
void *ret;
- lh->error = 0;
+ tsan_store((TSAN_QUALIFIER int *)&lh->error, 0);
+
rn = getrn(lh, data, &hash);
if (*rn == NULL) {
- lh->num_retrieve_miss++;
+ tsan_counter(&lh->num_retrieve_miss);
return NULL;
} else {
ret = (*rn)->data;
- lh->num_retrieve++;
+ tsan_counter(&lh->num_retrieve);
}
+
return ret;
}
OPENSSL_LH_COMPFUNC cf;
hash = (*(lh->hash)) (data);
- lh->num_hash_calls++;
+ tsan_counter(&lh->num_hash_calls);
*rhash = hash;
nn = hash % lh->pmax;
cf = lh->comp;
ret = &(lh->b[(int)nn]);
for (n1 = *ret; n1 != NULL; n1 = n1->next) {
- lh->num_hash_comps++;
+ tsan_counter(&lh->num_hash_comps);
if (n1->hash != hash) {
ret = &(n1->next);
continue;
}
- lh->num_comp_calls++;
+ tsan_counter(&lh->num_comp_calls);
if (cf(n1->data, data) == 0)
break;
ret = &(n1->next);
return (ret >> 16) ^ ret;
}
+unsigned long openssl_lh_strcasehash(const char *c)
+{
+ unsigned long ret = 0;
+ long n;
+ unsigned long v;
+ int r;
+
+ if (c == NULL || *c == '\0')
+ return ret;
+
+ for (n = 0x100; *c != '\0'; n += 0x100) {
+ v = n | ossl_tolower(*c);
+ r = (int)((v >> 2) ^ v) & 0x0f;
+ ret = (ret << r) | (ret >> (32 - r));
+ ret &= 0xFFFFFFFFL;
+ ret ^= v * v;
+ c++;
+ }
+ return (ret >> 16) ^ ret;
+}
+
unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh)
{
return lh ? lh->num_items : 0;