common lisp array and hashtable oddity? - hashtable

I am trying to store attack moves for chess pieces in a 64 square bitboard. Basically I am using any array of hash-tables to do this:
(defvar attacks (make-array '(64) :initial-element (make-hash-table))
However, I have noticed that when I fill up each hashtable in the array (with about 1000 elements each) it intersects with another hashtable. That is one hashtable has values from another hashtable, even though I didn't put it there.
Am I imagining things? Is this a bug?

You create a single hash table (with make-hash-table) that you then set in all elements of an array. To do what you want, you'd want to do one of:
Create an empty array, loop through and set each index to a fresh hash table
Create a list of 64 fresh hash tables and use :INITIAL-CONTENTS to populate the array on creation
That way, the hash tables would be separate instead of the same hash table stored 64 times.

You should use :INITFORM instead of :initial-element to get different hashtables
(My answer is wrong, see Vatine's)

Related

Delete a key-value pair in BerkeleyDB

Is there any way to delete key-value pair where the key start with sub-string1 and ends with sub-string2 in BerkeleyDB without iterating through all the keys in the DB?
For ex:
$sub1 = "B015";
$sub2 = "5646";
I want to delete
$key = "B015HGUJJ75646"
Note: It is guaranteed that there will be only one key for the combination of $sub1 and $sub2.
This can be done by taking an iterator of the DB and checking every key for the condition, but that will be very in-efficient for large DBs. Is there any way to do it without iterating through the complete DB?
If you're using a RECNO database, you're probably out of luck. But, if you can use a BTREE, you have a couple of options.
First, and probably easiest is to iterate over only the portion of the database that makes sense. Assuming you're using the default key comparison function, you can use DB_SET_RANGE to position the starting cursor (iterator) at the start of your partial key string. In your example, this might be "B0150000000000". You then scan forwards with DB_NEXT, looking at each key in turn. When either you find the key you're looking for, or if the key you find doesn't start with "B015", you're done.
Another technique that could be applicable to your situation is to redefine the key comparison function. If, as you state, there is only one combination of $sub1 and $sub2, then perhaps you only need to compare those sections of the keys to guarantee uniqueness? Here's an example of a full string comparison (I'm assuming you're using perl, just from the syntax you supplied above) from https://www2.informatik.hu-berlin.de/Themen/manuals/perl/DB_File.html :
sub Compare
{
my ($key1, $key2) = #_ ;
"\L$key1" cmp "\L$key2" ;
}
$DB_BTREE->{compare} = 'Compare' ;
So, if you can rig things such that you're only comparing the starting and ending four characters, you should be able to drop the database iterator directly onto the key you're interested in.

How to create three dimensional array with QHash?

I want to create QHash with three arguments:
QHash <int, QString, float> myhash;
I know that I have to use nested QHash, so I did:
QHash <int, QHash<QString, float> > myhash;
But I could not figure out how I can insert values to myhash.
I tried to create another Qhash and insert this into my myhash, but I does not make any sence, since I have exactly 1 pair data for one key.
What I want basically is :
0, "string1", 1.5
1, "string2", 1.2 etc.
How I can create efficiently (in terms of lookup time (the reason I am using QHash)) the above arrays. And how to insert values afterwards.
Thanks forward.
With QHash <int, QHash<QString, float> > myhash;, you can simply do this to set values:
myhash[42]["fortytwo"] = 42.42;
You can use the same syntax to access elements, but note that when accessed with non-const operator[], these entries will actually be created in the hash. So it's often better to use value() method:
if (myhash.value(43).value("fortytwo") >= 42) { /*...*/ }
Note that for QHash and QMap, accessing key which is not in the map is ok, default constructed value is returned in that case. Above for first it means and empty hash, and for second, value 0.0f.
To compare this to the method of using QPair from the other answer, this has the particular advantage that you can access elements by "rows" easily, if it matters for your use case (just make sure you have the nested hashes in the right order). Also, with this method, you could use different container for different dimensions, like if you need one dimension to be sorted use QMap (which is sorted by key) for that, and QHash (which is more efficient) for the dimension which doesn't need sorting. Additionally, you can have any number of dimensions easily, just add more nested containers.
On the other hand, if the key is logically a pair of values which are never separated, and data is not really (from programming perspective) organized as a two-dimensional table, then using QPair for key is probably better.
Unrelated to the question: to improve efficiency, in Qt 5 and C++11 you could use QStringLiteral("fortytwo") to have the QString created already at compile time.
Use a QPair as your key:
QHash<QPair<int,QString>,float> myhash;
Insert values:
myhash.insert(QPair<int,QString>(1,"string1"),12.);
or
QPair<int,QString> p(1,"string1");
myhash[p] = 12.

Alternative to search through a packed+unpacked array in systemverilog

I have this strange situation where i am currently doing this:
if (!this.randomize(delay) with {delay inside {strm};})
......
where
rand bit [2:0] delay;
bit [15:0] strm [bit [15:0]];
Now I want this delay to go in round robin from 0->....->7->0 and so on, but it should satisfy the condition that it should be present in strm. So I want something like
while (delay not in strm) begin
delay+=1;
end
Other than going though each and every index (2^16-1) is there any other way of finding if it exists in this packed+unpacked array? Thanks in advance!
If you are not aware, you are declaring strm as an associative array (aka a hash), where the key and the data are both 16 bit values.
If you want strm to be a fixed-size 2^16 entry array of 16-bit values, the declaration would be:
bit[15:0] strm [2**16];
With associative arrays you can use array.exists(key) to determine if the key is in the array. But it seems this may not be what you are trying to do.
With unpacked arrays, you can use the inside operator to test for set membership. But my simulator (Incisive) does not like this usage outside of a randomization call. So you may need to search for it yourself. However you don't have to iterate the entire array if you sort it first. And you can do that with array.sort().
I would also point out that you are looking for a 3-bit value in some sort of array of 16-bit values. This doesn't really make sense, so you may want to clarify your question.

Is there anything like pointers in Lua?

I'm new to Lua and I want to create a table [doh] which would store values like:
parent.child[1].value = "whaterver"
parent.child[2].value = "blah"
however, most often there's only one child, so it would be easier to access the value like this:
parent.child.value
To make things simpler, I would like to store my values, in a way, that
parent.child[1].value == parent.child.value
But to do this I would have to store this value twice in the memory.
Is there any way I could do it, so that:
parent.child.value points to parent.child[1].value
without storing the value twice in the memory?
Additional question is, how to check how much memory does a table take?
but the value will be stored as string, so it's a string that needs to
be referenced in both places, not table.
First, all types (except booleans, numbers and light userdata) are references - if t is a table and you do t2 = t, then both t and t2 are references to the same table in memory.
Second thing - string are interned in Lua. That means that all equal strings, like "abc" and the result of "ab".."c" are actually a single string. Lua also stores only references to strings. So you should not worry about memory - there is only a single instance of the string at a time.
You can safely do parent.child.value = parent.child[1].value, you will only use a memory for one slot in a table (a few bytes), no string will be copied, only referenced.
Lua tables (often used as objects) are not copied, but referenced.
(internally, a pointer is used to them)
This is a nice application for using metatables:
parent={
child={
{value="whatever"},
{value="blah"}
}
}
setmetatable(parent.child,{__index=parent.child[1]})
If an index is not found in the child table (like 'value'), it gets looked up in the table that's the value of __index of the metatable (the first element of child in this case).
Now there is a problem with the above code which we can see as folows:
print(parent.child.value) -- prints whatever
parent.child[1]=nil --remove first child
print(parent.child.value) -- still prints whatever!
This is because the metatable keeps a reference to the first child table, preventing it from being reaped. The workaround for this kind of stuff is A) making the metatable a weak table, or B) make the __index field a function, instead of referencing it to a table.
-- A)
setmetatable(parent.child, setmetatable(
{__index=parent.child[1]} -- metatable for the child table
{__mode='v'}-- metatable for the metatable, making it have weak keys
)
)
parent.child[1]=nil
print(parent.child.value) --returns nil
parent.child[1]={value='foo'}
print(parent.child.value) -- prints nil, the metatable references to a non-existant table.
-- hence solution B)
setmetatable(parent.child, {__index=function(t,k) return parent.child[1][k]})
print(parent.child.value) -- 'whatever'
parent.child[1]=nil
print(parent.child.value) -- nil
parent.child[1]={value='foobar'
print(parent.child.value) -- foobar, now it will always refer to the table at child[1], even when it changes.
If you're really interested to read up on metatables, try reading Programming in Lua, chapter 13 and chapter 17 (weak tables). Lua-Users wiki on MetaMethods might also be interesting.
With C arrays, parent.child and parent.child[0] are equivalent because of pointer arithmetic. You really shouldn't try to emulate one of the most error-prone, confusing and redundant features of C just because you like the style.

Annoyances of Flex - Associative Array

I have an associative array and while iterating through this array, using foreach loop. Flex is loosing the order. This is so annoying.
Why is this happening?
How can i avoid this?
Per the specification, the values in an associative array are not "ordered".
If you need to get values in a specified order, you'll need to sort the keys yourself.
Associative arrays are implementation of the Hash table data structure, and hence are unordered by nature.

Resources