string_hasher.cpp

Go to the documentation of this file.
00001 #ifndef STRING_HASHER_IMPLEMENTATION_FILE
00002 #define STRING_HASHER_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : string_hasher                                                     *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 2001-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 #include "static_memory_gremlin.h"
00019 #include "string_hasher.h"
00020 
00021 #include <basis/function.h>
00022 #include <basis/istring.h>
00023 
00024 #include <stdio.h>//temp
00025 
00026 const int MAX_STRING_CHARS_USED = 3;
00027   // we use this many characters from the string in question (if they
00028   // exist) at each end of the string.
00029 
00031 
00032 hashing_algorithm *string_hasher::clone() const
00033 { return new string_hasher; }
00034 
00035 u_int string_hasher::hash(const void *key_data, int key_length_in) const
00036 {
00037   if (!key_data) return 0;  // error!
00038   if (key_length_in <= 1) return 0;  // ditto!
00039 
00040   byte *our_key = (byte *)key_data;
00041   byte hashed[4] = { 0, 0, 0, 0 };
00042 
00043   int key_length = minimum(key_length_in - 1, MAX_STRING_CHARS_USED);
00044 
00045   int fill_posn = 0;
00046   // add the characters from the beginning of the string.
00047   for (int i = 0; i < key_length; i++) {
00048     // add to the primary area.
00049     hashed[fill_posn] = hashed[fill_posn] + our_key[i];
00050     fill_posn++;
00051     if (fill_posn >= 4) fill_posn = 0;
00052     // add to the secondary area (the next in rotation after primary).
00053     hashed[fill_posn] = hashed[fill_posn] + (our_key[i] / 4);
00054   }
00055   // add the characters from the end of the string.
00056   for (int k = key_length_in - 2;
00057       (k >= 0) && (k >= key_length_in - 1 - key_length); k--) {
00058     // add to the primary area.
00059     hashed[fill_posn] = hashed[fill_posn] + our_key[k];
00060     fill_posn++;
00061     if (fill_posn >= 4) fill_posn = 0;
00062     // add to the secondary area (the next in rotation after primary).
00063     hashed[fill_posn] = hashed[fill_posn] + (our_key[k] / 4);
00064   }
00065   
00066   u_int to_return = 0;
00067   for (int j = 0; j < 4; j++) to_return = (to_return << 8) + hashed[j];
00068   return to_return;
00069 }
00070 
00072 
00073 hashing_algorithm *istring_hasher::clone() const
00074 { return new istring_hasher; }
00075 
00076 u_int istring_hasher::hash(const void *key_data, int key_length_in) const
00077 {
00078   if (!key_data) return 0;  // error.
00079   const istring *real_key = (const istring *)key_data;
00080   if (real_key->length() + 1 != key_length_in) {
00081 //    printf("differing key lengths, string len=%d, key len=%d\n",
00082 //        real_key->length() + 1, key_length_in);
00083   }
00084   return string_hasher().hash((const void *)real_key->observe(),
00085       real_key->length() + 1);
00086 }
00087 
00088 
00089 #endif //STRING_HASHER_IMPLEMENTATION_FILE
00090 

Generated on Fri Nov 21 04:29:42 2008 for HOOPLE Libraries by  doxygen 1.5.1