• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Trigger] I want to know Hashtable is necessory?

Status
Not open for further replies.
Level 11
Joined
May 31, 2008
Messages
698
You probably dont need hashtables for anything honestly. I've never used them or taken the time to learn how to use them and i have never ran into anything that i couldnt do without them. I think they just make things easier, but im just too lazy to learn how to use them :p
You should be fine without them, but its probably good to know how to use them
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Hashtables offer a far greater key range (and it's 2dimensional right off the bat or even 3d if you get the used table dynamically). Say you wanted to assign a value to a region for example. Regions belong to the parent agent. Their ids are above 2^20. That would be too big an index for an array. You may subtract the 2^20 offset but there are usually many agents in the game. They won't fit anymore when they count >8k (2^13) because arrays range from 0 to 8190/8191. Now think you wanted the region to have a list of values, saving the last hundred units that entered them. If you used a normal array for this task, each region would need a memory storage of 100 size, 8k / 100 --> a mere max of 80 possible regions. And it even gets easilier exhausted with more required dimensions. You not only want the last hundred units but the last hundred of each player. The 80 gets divided by another number of players.

There are some other advantages like flushing whole dimensions natively.
 
One hashtable can store 2^64 pieces of data. Since you'll never hit the limit, the maximum storage will always depend on your RAM ;)

One unit takes about 3KB of memory.
You can store up to 2^64 * 3 KBs worth of units in one hashtable ^_^
That would need several Hexabytes of RAM :D

An array on the other hand can only store 8192 pieces of data.
That's about 24MB worth of unit data.

Sometimes, you're going to need to use very large indices that may also be negative.
In these cases, you should use a hashtable.

When you know that the index you're going to use is below 8192 and at least 0, you should use an array.
Unit Handle Ids exceed 8192 for example. They usually range from 2^20 and above. That's why a lot of
people create Unit Indexers that assign a unique integer for every unit present on the map below 8192.
This way, you don't have to use hashtables whenever you're storing data for units, you can use arrays ^.^

There's a Hashtable limit: 255 hashtables per map.

That's why a lot of us use Bribe's Table library.
It uses one hashtable to store all the data you're ever going to need.
One hashtable is much more than enough.
Even if you fill it completely with integers, you're going to need a looooot of RAM ;) (We're talking several Petabytes)
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
It's not only about how much fits in overall but what are potential indizes. An example of physics: each spot in 3 dimensional room may be assigned a temperature. So let's say each terrain node is a spot and the whole is a dice, x, y and z dimension all have the same length of 257 (256x256 map). How would you give a combination of coordinates its temperature value? To not risk collisions, a possible solution would be to have a 3dimensional array (257^3). That's already a nearly 17million slots requirement. Now if we include another dimension for time, also a size of 257, that would be greater than the range of integer. So I did not say to really save those masses of values but they are possible memory space.
 
Here you go simple example :)

JASS:
globals
    hashtable hash = InitHashtable()
endglobals

function ExampleSetup takes nothing returns nothing
    call SaveInteger( hash, 1 , 1 , 100)
    call SaveInteger( hash, 1 , 2 , 75 )
    call SaveInteger( hash, 1 , 3 , 50 )
    call SaveInteger( hash, 1 , 4 , 25 )
    call SaveInteger( hash, 1 , 5 , 0 )
    call SaveStr( hash, 2 , 1 , "Hello" )
    call SaveStr( hash, 2 , 2 , "Hi" )
    call SaveStr( hash, 2 , 3 , "Yo" )
    call SaveStr( hash, 2 , 4 , "Hey" )
    call SaveStr( hash, 2 , 5 , "Bzzz" )
endfunction

function ExampleActions takes nothing returns nothing
    local integer i = GetRandomInt(1,5)
    local integer j = GetRandomInt(1, 100)
    if j < LoadInteger(hash, 1 , i ) then
        call BJDebugMsg( I2S(j) + " < " + I2S(LoadInteger(hash, 1 , i )) )
        call BJDebugMsg( LoadStr(hash, 2 , i ) )
        call BJDebugMsg( " " )
    endif
    
endfunction

//===========================================================================
function InitTrig_Example takes nothing returns nothing
    local trigger t = CreateTrigger( )
    call TriggerRegisterPlayerEvent(t, Player(0), EVENT_PLAYER_END_CINEMATIC)
    call TriggerAddAction( t, function ExampleActions )
    call ExampleSetup()
endfunction

Press ESC ingame and see how it work.

In this example you will never be able to see "Bzzz" because chance for j to be less than 0 is equal to 0.
 

Attachments

  • testmap.w3x
    16.6 KB · Views: 27
Status
Not open for further replies.
Top