Exemple #1
0
MtPair* mt_hash_search(MtHash* hash, MtString* key)
{
  assert(hash != NULL);
  assert(key != NULL);

  if (key->hash == 0)
    key->hash = Murmur3(mt_string_get_utf8(key), mt_string_get_length(key));

  size_t index = key->hash % hash->size;

  MtHashElement* element = &hash->buckets[index];
  assert(element != NULL);

  // Key Collides
  if (element->data != NULL)
  {
    // If it is a tree, search the tree for the key
    if (element->is_tree)
    {
      return mt_tree_search((MtTree*) element->data, key);
    }
    else if (mt_string_compare(((MtPair*) element->data)->key, key) == 0)
    {
      return (MtPair*) element->data;
    }
  }

  // Nothing was found
  return NULL;
}
Exemple #2
0
void
mt_hash_remove(MtHash* hash, MtString* key)
{
  assert(hash != NULL);
  assert(key != NULL);

  if (key->hash == 0)
    key->hash = Murmur3(mt_string_get_utf8(key), mt_string_get_length(key));

  size_t index = key->hash % hash->size;
  MtPair* element = hash->buckets[index];

  while (element != NULL)
  {
    if (mt_string_compare(key, element->key) == 0)
    {
      hash->buckets[index] = NULL;
      --hash->length;
      return;
    }

    ++index;
    index %= hash->size;
    element = hash->buckets[index];
  }
}
Exemple #3
0
void
mt_hash_insert(MtHash* hash, MtString* key, void* value)
{
  assert(hash != NULL);
  assert(key != NULL);

  if (key->hash == 0)
    key->hash = Murmur3(mt_string_get_utf8(key), mt_string_get_length(key));

  mt_hash_insert_pair(hash, mt_pair_new(key, value));
}
Exemple #4
0
void hkl_hash_insert(HklHash* hash, HklString* key, void* value)
{
  assert(hash != NULL);
  assert(key != NULL);

  // The string doesnt already have a hash
  // give it one
  if (key->hash == 0)
    key->hash = Murmur3(hkl_string_get_utf8(key), hkl_string_get_length(key));

  size_t index = key->hash % hash->size;

  HklHashElement* element = &hash->buckets[index];
  assert(element != NULL);

  // Collision
  if (element->data != NULL)
  {
    if (element->is_tree)
    {
      hkl_tree_insert((HklTree*) element->data, key, value);
    }
    else
    {
      // First Collision
      HklPair* pair = element->data;

      element->data = hkl_tree_new();
      hkl_tree_move_pair((HklTree*) element->data, pair);

      hkl_tree_insert((HklTree*) element->data, key, value);
      
      ++hash->length;

      // Mark the element as a tree
      element->is_tree = true;
    }
  }
  // No Collision
  else
  {
    // Nothing exists here. Make a pair
    element->data = hkl_pair_new_from_data(key, value);

    // The number of entries of the table increases
    ++hash->length;

    // If the hash table is 75% full
    if (hash->length >= 0.75*hash->size)
      hkl_hash_double(hash);
  }
}
Exemple #5
0
void
mt_hash_insert(MtHash* hash, MtString* key, void* value)
{
  assert(hash != NULL);
  assert(key != NULL);

  if (key->hash == 0)
    key->hash = Murmur3(mt_string_get_utf8(key), mt_string_get_length(key));

  size_t index = key->hash % hash->size;

  MtHashElement* element = &hash->buckets[index];
  assert(element != NULL);

  // Collision handling
  if (element->data != NULL)
  {
    if (element->is_tree)
    {
      // Collision, tree already made
      mt_tree_insert((MtTree *) element->data, key, value);
    }
    else
    {
      // First collision, make a tree
      MtPair* pair = element->data;

      element->data = mt_tree_new();
      mt_tree_move_pair((MtTree *) element->data, pair);
      
      ++hash->length;

      mt_tree_insert((MtTree *) element->data, key, value);

      element->is_tree = true;
    }
  }
  // No collision
  else
  {
    element->data = mt_pair_new(key, value);

    ++hash->length;

    if (hash->length >= 0.75 * hash->size)
      mt_hash_double_size(hash);
  }
}
Exemple #6
0
void hkl_hash_remove(HklHash* hash, HklString *key)
{
  assert(hash != NULL);
  assert(key != NULL);

  // The string doesnt already have a hash
  // give it one
  if (key->hash == 0)
    key->hash = Murmur3(hkl_string_get_utf8(key), hkl_string_get_length(key));

  size_t index = key->hash % hash->size;

  HklHashElement* element = &hash->buckets[index];
  assert(element != NULL);

  if (element->data != NULL)
  {

    if (element->is_tree)
    {
      HklTree* tree = element->data;
      
      // Keep track of the old tree size
      size_t old_size = tree->size;

      // Attempt to remove the element from the tree
      hkl_tree_remove(tree, key);

      // Subtract the difference between the old and new
      // tree sizes from the hash length
      assert((old_size - tree->size) <= 1);
      hash->length -= old_size - tree->size;
    }
    else
    {
      hkl_pair_free((HklPair*) element->data);
      --hash->length;
    }
  }
}
Exemple #7
0
HklPair* hkl_hash_search(const HklHash* hash, HklString *key)
{
  assert(hash != NULL);
  assert(key != NULL);

  // The string doesnt already have a hash
  // give it one
  if (key->hash == 0)
    key->hash = Murmur3(hkl_string_get_utf8(key), hkl_string_get_length(key));

  size_t index = key->hash % hash->size;

  HklHashElement* element = &hash->buckets[index];
  assert(element != NULL);

  // Found a collision
  if (element->data != NULL)
  {
    if (element->is_tree)
    {
      return hkl_tree_search((HklTree*) element->data, key);
    }
    // I'm an idiot for not thinking to put this here... -Scott
    else if (hkl_string_compare(((HklPair*) element->data)->key, key) == 0)
    {
      return (HklPair*) element->data;
    }
    else
    {
      return NULL;
    }
  }
  else
  {
    // No such element, do nothing
    return NULL;
  }
}
Exemple #8
0
void
mt_hash_remove(MtHash* hash, MtString* key)
{
  assert(hash != NULL);
  assert(key != NULL);

  if (key->hash == 0)
    key->hash = Murmur3(mt_string_get_utf8(key), mt_string_get_length(key));

  size_t index = key->hash % hash->size;

  MtHashElement* element = &hash->buckets[index];
  assert(element != NULL);

  if (element->data != NULL)
  {

    if (element->is_tree)
    {
      MtTree* tree = element->data;

      // Save the size before attempting to remove element from tree
      size_t old_size = tree->size;

      mt_tree_remove(tree, key);

      // Decrement the size of the hash by the difference in the
      // old and new sizes of the tree. This shouldn't ever be more than 1.
      assert((old_size - tree->size) <= 1);
      hash->length -= old_size - tree->size;
    }
    else
    {
      mt_pair_free((MtPair*) element->data);
      --hash->length;
    }
  }
}
Exemple #9
0
MtPair* mt_hash_search(MtHash* hash, MtString* key)
{
  assert(hash != NULL);
  assert(key != NULL);

  if (key->hash == 0)
    key->hash = Murmur3(mt_string_get_utf8(key), mt_string_get_length(key));

  size_t index = key->hash % hash->size;
  MtPair* element = hash->buckets[index];

  while (element != NULL)
  {
    if (mt_string_compare(key, element->key) == 0)
      return element;

    ++index;
    index %= hash->size;
    element = hash->buckets[index];
  }

  // Nothing was found
  return NULL;
}
Exemple #10
0
cell AMX_NATIVE_CALL amx_DC_CMD(AMX* amx, cell* params)
{
	cell *addr;
	int len;
	amx_GetAddr(amx, params[2], &addr);
	amx_StrLen(addr, &len);
	if(len>127) len=127;
	++len;
	char cmdtext[128];
	amx_GetString(cmdtext, addr, 0, len);
	cmdtext[0] = '_';
	// converting string to lower case
	int pos=0, cmd_end;
	do{
		++pos;
		if(('A' <= cmdtext[pos]) && (cmdtext[pos] <= 'Z'))
			cmdtext[pos] += ('a'-'A');
		else if(cmdtext[pos] == '\0')
			break;
		else if(cmdtext[pos] == ' ')
		{
			cmd_end = pos;
			cmdtext[pos++] = '\0';
			goto loop1_exit;
		}
	}while(1);
	cmd_end = 0;
loop1_exit:
	// search for command index in all AMX instances
	int pubidx;
	cell retval, params_addr;
	int i;
	for(i=0; i<=lastAMX; ++i)
	{
		if((amx_List[i].amx != NULL) && (amx_FindPublic(amx_List[i].amx, cmdtext, &pubidx) == AMX_ERR_NONE))
		{
			// if current AMX instance has OnPlayerCommandReceived callback - invoke it
			if(amx_List[i].OPCR != 0x7FFFFFFF)
			{
				// restore some symbols in cmdtext
				cmdtext[0] = '/';
				if(cmd_end>0)
					cmdtext[cmd_end] = ' ';
				amx_PushString(amx_List[i].amx, &params_addr, 0, cmdtext, 0, 0);
				amx_Push(amx_List[i].amx, params[1]);
				amx_Exec(amx_List[i].amx, &retval, amx_List[i].OPCR);
				amx_Release(amx_List[i].amx, params_addr);
				// if OPCR returned 0 - command execution rejected
				if(retval == 0)
					return 1;
				cmdtext[0] = '_';	// restore AMX-styled command name
				if(cmd_end>0)		// and separate it from parameters (again =/)
					cmdtext[cmd_end] = ' ';
			}
			// remove extra space characters between command name and parameters
			while(cmdtext[pos] == ' ') pos++;
			amx_PushString(amx_List[i].amx, &params_addr, 0, cmdtext+pos, 0, 0);
			amx_Push(amx_List[i].amx, params[1]);
			amx_Exec(amx_List[i].amx, &retval, pubidx);
			amx_Release(amx_List[i].amx, params_addr);
			// if current AMX instance has OnPlayerCommandPerformed callback - invoke it
			if(amx_List[i].OPCP != 0x7FFFFFFF)
			{
				cmdtext[0] = '/';
				if(cmd_end>0)
					cmdtext[cmd_end] = ' ';
				amx_Push(amx_List[i].amx, retval);
				amx_PushString(amx_List[i].amx, &params_addr, 0, cmdtext, 0, 0);
				amx_Push(amx_List[i].amx, params[1]);
				amx_Exec(amx_List[i].amx, &retval, amx_List[i].OPCP);
				amx_Release(amx_List[i].amx, params_addr);
			}
			return 1;
		}
	}
	// if command wasn't found - perhaps this is an alternative command
	if(Alts_n != 0)
	{
		int hash;
		// remove extra space characters between command name and parameters
		//logprintf("attempting to find alt %s, len = %d", cmdtext, (cmdtext[pos])?(pos-1):(pos));
		Murmur3(cmdtext, (cmdtext[pos])?(pos-1):(pos), &hash);
		if(cmdtext[pos])
		{
			pos--;
			while(cmdtext[++pos] == ' '){}
		}
		//logprintf((char*)"Murmur3(%s) = 0x%X", cmdtext, hash);
		boost::unordered_map<int,int>::const_iterator alt;
		for(i=0; i<=lastAMX; ++i)
		{
			if((amx_List[i].amx != NULL) && ((alt = Alts[i].find(hash)) != Alts[i].end()))
			{
				pubidx = alt->second;
				//logprintf("found alt: %s, amx = %d, idx = %d", cmdtext, (int)amx, pubidx);
				if(amx_List[i].OPCR != 0x7FFFFFFF)
				{
					// restore some symbols in cmdtext
					cmdtext[0] = '/';
					if(cmd_end>0)
						cmdtext[cmd_end] = ' ';
					amx_PushString(amx_List[i].amx, &params_addr, 0, cmdtext, 0, 0);
					amx_Push(amx_List[i].amx, params[1]);
					amx_Exec(amx_List[i].amx, &retval, amx_List[i].OPCR);
					amx_Release(amx_List[i].amx, params_addr);
					// if OPCR returned 0 - command execution rejected
					if(retval == 0)
						return 1;
					cmdtext[0] = '_';	// restore AMX-styled command name
					if(cmd_end>0)		// and separate it from parameters (again =/)
						cmdtext[cmd_end] = ' ';
				}
				// remove extra space characters between command name and parameters
				while(cmdtext[pos] == ' ') pos++;
				amx_PushString(amx_List[i].amx, &params_addr, 0, cmdtext+pos, 0, 0);
				amx_Push(amx_List[i].amx, params[1]);
				amx_Exec(amx_List[i].amx, &retval, pubidx);
				amx_Release(amx_List[i].amx, params_addr);
				// if current AMX instance has OnPlayerCommandPerformed callback - invoke it
				if(amx_List[i].OPCP != 0x7FFFFFFF)
				{
					cmdtext[0] = '/';
					if(cmd_end>0)
						cmdtext[cmd_end] = ' ';
					amx_Push(amx_List[i].amx, retval);
					amx_PushString(amx_List[i].amx, &params_addr, 0, cmdtext, 0, 0);
					amx_Push(amx_List[i].amx, params[1]);
					amx_Exec(amx_List[i].amx, &retval, amx_List[i].OPCP);
					amx_Release(amx_List[i].amx, params_addr);
				}
				return 1;
			}
		}
	}
	// if command not found - call OnPlayerCommandPerformed callback in gamemode AMX (success = -1)
	if(amx_List[0].OPCP != 0x7FFFFFFF)
	{
		cmdtext[0] = '/';
		if(cmd_end>0)
			cmdtext[cmd_end] = ' ';
		amx_Push(amx_List[0].amx, -1);
		amx_PushString(amx_List[0].amx, &params_addr, 0, cmdtext, 0, 0);
		amx_Push(amx_List[0].amx, params[1]);
		amx_Exec(amx_List[0].amx, &retval, amx_List[0].OPCP);
		amx_Release(amx_List[0].amx, params_addr);
	}
	return 1;
}
Exemple #11
0
cell AMX_NATIVE_CALL amx_RegisterAlt(AMX* amx, cell* params)
{
	int amx_n;
	for(amx_n=0; amx_n<=lastAMX; ++amx_n)
		if(amx == amx_List[amx_n].amx)
			break;
	if(amx_n>lastAMX) // if amx wasn't found in list
		return 0;
	cell *addr;
	int len;
	amx_GetAddr(amx, params[1], &addr);
	amx_StrLen(addr, &len);
	if(len>31) len=31;
	++len;
	char cmd[32];
	amx_GetString(cmd, addr, 0, len);
	cmd[0] = '_';
	// converting string to lower case
	int pos=0;
	do{
		++pos;
		if(('A' <= cmd[pos]) && (cmd[pos] <= 'Z'))
			cmd[pos] += ('a'-'A');
		else if(cmd[pos] == '\0')
			break;
		else if((cmd[pos] == ' ') || (cmd[pos] == '\t'))
		{
			cmd[pos] = '\0';
			break;
		}
	}while(1);
	int pubidx;
	if(amx_FindPublic(amx, cmd, &pubidx) != AMX_ERR_NONE)
	{
		//logprintf((char*)"RegisterAlt: Couldn't find function %s", cmd);
		return 1;
	}
	int alt_n = (params[0]/4), hash;
	//logprintf("RegisterAlt: alts = %d", alt_n-1);
	do{
		if(amx_GetAddr(amx, params[alt_n], &addr) != AMX_ERR_NONE)
			continue;
		amx_StrLen(addr, &len);
		if(len>31) len=31; // command length must be up to 31 chars
		++len;
		amx_GetString(cmd, addr, 0, len);
		cmd[0] = '_';
		pos = 0;
		do{
			++pos;
			if(('A' <= cmd[pos]) && (cmd[pos] <= 'Z'))
				cmd[pos] += ('a'-'A');
			else if(cmd[pos] == '\0')
				break;
			else if((cmd[pos] == ' ') || (cmd[pos] == '\t'))
			{
				cmd[pos] = '\0';
				break;
			}
		}while(1);
		//logprintf((char*)"%s, len = %d", cmd, pos);
		Murmur3(cmd, pos, &hash);
		//logprintf("RegisterAlt: Murmur3(%s) = 0x%X", cmd, hash);
		Alts[amx_n].insert(std::make_pair(hash, pubidx));
		Alts_n++;
		//logprintf((char*)"RegisterAlt: new alt - %s, amx = %d, pubidx = %d", cmd, amx, pubidx);
	}while(--alt_n > 1);
	return 1;
}