That's because your use of -m instead of -m1 is using the default 100 buckets. When N buckets is greater than 1, it's going to assign them a sequence number that appears to be random, but that's caused by the items being shuffled out to the different buckets using a pseudo-random algorithm based on the itemname.

It appears that the actual number of buckets is always an odd number, in spite of the value returned by $hget(table).size, because you always get the same shuffling of items for N as you get from $or(N,1). (It's possible it does $and(N,-2) but I doubt it, and don't know how to check which it is.)

If your example had used buckets=1, you'd find that the 1st item is always the latest one created:

Code:
//hfree -w TEST | var %i = 1 | while (%i <= 1000) { hadd -m1 TEST test_ $+ %i 1 | inc %i } | echo -a IS: $hget(TEST,1).item



It appears /hadd creates new items by inserting them to the front of the sequential list. But if the item already exists, it instead gets updated in its current bucket, but I'm not sure whether it's deleted then added to the front of the bucket or continues to use its existing spot in the bucket.

If you want $hget(table,X).item to be item name test_X, you need to create them in reverse order:

Code:
//hfree -sw test | hmake -s test 1 | var %i 20 | while (%i) { hadd test item $+ %i data | dec %i } | var %N 1 | while ($hget(test,%N).item) { echo 4 -a $ord(%N) item is $hget(test,%N).item | inc %N }



If you change the buckets 1 to be 100 you'll see that the items are created out of sequence, which is how you ended up with the 1st item being 783. If you increase %i from 20 to also be 100, you'll see it appear more shuffled. The fact that N=100 and i=20 doesn't appear randomly shuffled tells me that the items are put in buckets using a simple method, and is not using a 'real' hash function like $sha1, nor even $crc. It appears to use a case-insensitive version of the itemname, because changing your example from using itemnames starting with "test_" and "TEst_" give the same sequence, but other strings have a huge chance of having something else be your 1st item.

If you need to hsave then hload your buckets=1 table, this causes your list to be in reverse order than created the next time you /hload, because it looks like /hload begins at the front of the file and /hadd's the info, then continues to the end of the file.

To get your /hload'ed data to be in the original 'correct' order, you'd need to either /hload + /hsave + /hfree + /hload, or /hload it into a dummy table and clone it from there.

To fix your issue would probably require a new switch for /hadd and /hload to append new items instead of inserting them. I see the -a switch is available.

Last edited by maroon; 13/10/18 10:24 PM.