Advertisement

Can you have to long of a hash string key.

Started by March 26, 2015 06:42 AM
7 comments, last by ankhd 9 years, 9 months ago

Hi.

I have this std::unordered_map<std::string, T> Listdata;

the string key is a guid converted to a string = "1C539C5A-BC4B-40B0-A612-21F61BF6BDE6"

the guid is a boost::uuid.

This all worked fine until I saved and loaded the strings to file and now the key cant find a match.

.


//------------------------------------------------------------------------------
	//this returns true if the passed in guid is supported by the server
	//------------------------------------------------------------------------------
	bool SupportedAplication(std::string &appguid)
	{
		if(appguid.empty())
			return false;//error

      //THIS IS MY FIX I CONVERT THE STRINGS TO UUID AND NOW STORE UUID AS KEY AND IT WORKS
		boost::uuids::string_generator gen;
		boost::uuids::uuid u1 = gen(appguid);

		//all we need to do is find the app guid if its there we can use this app on this server
		auto search = AvailableApplications.find(u1);//appguid);
		if(search == AvailableApplications.end())
		{
			return false;//failed
		}

		return true;//we can use it

	}//end SupportedAplication
	///////////////////////////////////////////////////////////////////////////////////

The(og geen text??) fix was to replace the string key with the uuid value and then converting the passed in string id to its value and it all worked.

The question is, is having long keys a bad idea.

Definitely not a bad idea since technically, the key is always a long. (well, a size_t , which usually is 64 or 32 bit depending on platform)

Also when you use a string as a key, it is first hashed into a size_t, and the size_t value is what is actually used to look up the value (that is how hash maps like unordered_map work)

So using something directly compatible with size_t for the key should be a small optimization, since you will no longer have to hash the key.

Advertisement

Are we talking about simple hash keys (32/64 bit) or uuids ?


So using something directly compatible with size_t for the key should be a small optimization, since you will no longer have to hash the key.

Thought a hash key is not unique (trap door), therefor using the hash key instead of the string could result in loosing data. A hash key is usally only a quick way to track down the set of potential key values quickly, but it is still necessary to check the real key versus the potential candidate set.

If you use a UUID (which is by definition unique), it would work, but a boost UUID is 128 bit, not 64 or 32.

Right, I should have seen that the uuid likely was not a long as the OP claims, even though I have not used boost...

As long as the key is actually compatible with a size_t you wouldn't need to hash it (and I'm sure the unordered_map recognizes this case).

If it is 128 bit, well.. then you would need to hash it. It should still be faster to hash a 128 bit value, then a 30-40 char string.

On another note, it is strange that the OP has problems with the string after saving it to file and reading it back. That shouldn't be a problem.

I'm guessing some change in character encoding.

What I mean is I use a uuid as a string created with GuidGen.exe. I then copy {1C539C5A-BC4B-40B0-A612-21F61BF6BDE6} to a text file 1 per line

Then I read in string = {1C539C5A-BC4B-40B0-A612-21F61BF6BDE6} from the file

and the string is then used as the key, what happens is it adds a entry but then later can't find that entry with the same string key.

The long was length of string not type long.

So how come the hash failed to find matching key.

I set a break point and both strings where the same.????

Why are you storing GUID's in memory as a string. Store them as a quadruplet of dwords (which is effectively what they are), or use the Win32 GUID structure..

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Advertisement

So how come the hash failed to find matching key.


My guess is that the format of the string you're reading in from guidgen is not the same format that boost::guid's string format uses, so the strings are different even though they represent the same GUID value. The Boost one is probably in lower-case, or missing the {}'s, or something like that.

You haven't given us enough context to say what for sure. The operations you describe will work perfectly. The size of the string is entirely not the issue; you can reliably hash a string that's 1GB in size and get the same result every time... assuming that the input string is the same every time. A GUID string isn't even "long" by any reasonable definition of the word. smile.png

Sean Middleditch – Game Systems Engineer – Join my team!

Oh

The size of the string is entirely not the issue; you can reliably hash a string that's 1GB in size and get the same result every time

Didn't want to here that.

Both of the string keys are the same I checked with a break point.

the UUID stored on file is in the form of {1C539C5A-BC4B-40B0-A612-21F61BF6BDE6}. The user who defines what app they want to run on the server fills this file out

they will then need the converter.exe that reads each line from the guid file just defined as a text file.

what the converter does is reads line by line each line gets put to boost::uuid::string_generator which accepts a range of string guids the one above is fine

and converts it to a lower case format with out the {} this 1c539c5a-bc4b-40b0-a612-21f61bf6bdE6 then this is now the key for adding and finding.

Saving and loading is done by google protocol buffers and data checks out fine.

Now the code that uses the string guid has a loadallowedapplications and a SupportedAplication which can't find the key

.




	//---------------------------------------------------------------------------
	//this will load the .ala file that has allowed application guids and names
	//-----------------------------------------------------------------------------
	bool LoadAllowedHostedApplications(std::string &filename)
	{
		std::string appguid;
		std::string appname;

		AllowedApps.Clear();

		

		//load the .ala file
		std::fstream input(filename, std::ios::in | std::ios::binary);    
		if(!AllowedApps.ParseFromIstream(&input)) 
		{      
			return false;//error
		}

		input.close();

		cSupportedApps sa;

		//we need to run the loaded guid through the gen to remove the {}
		boost::uuids::string_generator gen;
		boost::uuids::uuid u1;// = gen(appguid);

		std::stringstream ss;
		

		//testing loading by hand
		for(size_t ctr = 0; ctr < AllowedApps.appguid_size(); ++ctr)
		{
			appguid = AllowedApps.appguid(ctr);
			appname = AllowedApps.appname(ctr);

			u1 = gen(appguid);//the removes the {}
			ss.str("");
			ss << u1;

			sa.AppGuid = ss.str();
			sa.AppName = appname;

			sa.AvailableRoomLobby = boost::make_shared<cAvailableRoomLobbyServer>();
			//add new allowed app to the set
			AvailableApplications[u1] = sa;
		}

		return true;
	}//end LoadAllowedHostedApplications
	/////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////

..the supported application

.


//------------------------------------------------------------------------------
	//this returns true if the passed in guid is supported by the server
	//------------------------------------------------------------------------------
	bool SupportedAplication(std::string &appguid)
	{
		if(appguid.empty())
			return false;//error

		boost::uuids::string_generator gen;
		boost::uuids::uuid u1 = gen(appguid);

		//all we need to do is find the app guid if its there we can use this app on this server
		auto search = AvailableApplications.find(u1);//appguid);
		if(search == AvailableApplications.end())
		{
			return false;//failed
		}

		return true;//we can use it

	}//end SupportedAplication
	///////////////////////////////////////////////////////////////////////////////////

Famous last words

Both of the string keys are the same I checked with a break point.

Like looking for things on a shelf.....ohmy.png

Thanks all.

Found the problem I converted it all back to string keys

and when loadings the string from file did this

u1 = gen(appguid);//the removes the {}

ss.str("");

ss << u1;

sa.AppGuid = ss.str();//note new conversion

sa.AppName = appname;

assign to the map

AvailableApplications[appguid] = data;the key was the none converted string mmmmmm#$@#@

should be this

AvailableApplications[sa.AppGuid] = data;

What would you all recommend for the key the string or the uuid type

the string has issues like my above examples.

but what's the drawback for the uuid.

This topic is closed to new replies.

Advertisement