// StrHash.cpp
// Incorporate Ksilyan's shared string library into the base

#include <iostream>
#include "strhash.h"
#include <sharedstr/sharedstr_hashtable.h>

#ifdef TEST_HASH
 #include "log.h"
#endif

using namespace std;

SharedString::HashTable * gStrTable;
ASSOCIATE_MANAGER_WRAPPER(HashTableWrapper, gStrTable);

// copied from the test program
// A better hash function than the silly hash SMAUG uses.
// Not 'perfect' but much better.
size_t StrHash(const char * str)
{
	int i = strlen (str);

	switch (i)
    {
		case 0:
			return 0;
		case 1:  // hash on the character
			return *str;
		default:
			/*
			 * hash on first two characters and length.
			 * Ensure that "ab" hashes differently than "ba"
			 * Ignore overflows
			 */
			return (((str[0] & 0xff) << 8) | (str[1] & 0xff)) * i;
	}
}

bool InitStrHash()
{
	gStrTable = new SharedString::HashTable(&StrHash);

	cout << "\nInitializing string hash table...";
	
	if ( !gStrTable )
     return false;

#ifdef TEST_HASH
  		s_str s;

		s = "hello";
        s += " there";

        glog( "InitStrHash: %d strings, s = %s", gStrTable->numStrings(), s.c_str());

		s = "hello";
        s += s_str(" there");

        glog( "InitStrHash: s = %s", s.c_str());

		s = "hello";
        s += std::string(" there");

        glog( "InitStrHash: %d strings, s = %s", gStrTable->numStrings(), s.c_str());

     	s = s_str("hello") + s_str(" there");
        glog( "InitStrHash: %d strings, s = %s", gStrTable->numStrings(), s.c_str());

		s = s_str("hello") + " there";
        glog( "InitStrHash: %d strings, s = %s", gStrTable->numStrings(), s.c_str());

		s = s_str("hello") + std::string(" there");
        glog( "InitStrHash: %d strings, s = %s", gStrTable->numStrings(), s.c_str());

    // wipe it and start over
    delete gStrTable;
    
    gStrTable = new SharedString::HashTable(&StrHash);
    
    if ( !gStrTable )
     return false;
#endif

    cout << " Done.\n\n";

    return true;
}