Access a table indexed by a table key in lua C++ - c++

Lua tables can have a table as a key, for instance:
a = {[{}]=true}
I'm wondering how I can index this from the lua C++ api. For instance, I can do:
lua_getfield(L, -1, variablename);
To get a string key'd value of a table on the stack. How would I put a table-valued key onto the stack?

lua_getfield is nothing more than syntactic sugar around a series of commands you could do on your own:
lua_pushstring(L, variablename);
lua_gettable(L -1 - 1); //The second minus one represents the fact that your table is actually one index below the top now.
You push the key onto the stack, then use lua_gettable to access it. This is true regardless of what kind of key it is.
The only question you have to answer is how to actually get that key in the first place. For that... you're on your own. Every Lua table has a different value from every other Lua table. And if your Lua script just jammed a freshly-created Lua table in the key like that, without handing a reference to the table to you or storing a reference globally, you're hosed.
Your only recourse then is to just iterate through the table with lua_next and hope that a key who's type is "table" is the key you're looking for.

I would say you need to iterate the table with lua_next.
This link describes the process: http://pgl.yoyo.org/luai/i/lua_next.
Investigate the iterated tables and determine if its the one that you are searching for.

Related

DynamoDB Query distinct attribute values

I'm trying to query DynamoDB and get a result similar to select distinct(address) from ... in SQL.
I know DynamoDB is a document-oriented DB and maybe I need to change the data structure.
I'm trying to avoid getting all the data first and filtering later.
My data looks like this:
Attribute
Datatype
ID
String
Var1
Map
VarN
Map
Address
String
So I want to get the distinct addresses in the entire table.
How it's the best way to do it?
Unfortunately, no. You'll need to Scan the entire table (you can use the ProjectionExpression or AttributesToGet options to ask just for the "Address" attribute, but anyway you'll pay for scanning the entire contents of the table).
If you need to do this scan often, you can add a secondary-index which projects only the keys and the "Address" attribute, to make it cheaper to scan. But unfortunately, using a GSI whose partition key is the "Address" does not give you an ability to eliminate duplicates: Each partition will still contain a list of duplicate items, and unfortunately there is no way to just listing the different partition keys in an index - Scaning the index will give you the same partition key multiple times, as many items there are in this partition.

What should be DynamoDB key schema for time sliding window data get scenario?

What I never understood about DynamoDB is how to design a table to effectively get all data with one particular field lying in some range. For example, time range - we would like to get data created from timestamp1 up to timestamp2. According to keys design, we can use only sort key for such a purpose. However, it automatically means that the primary key should be the same for all data. But according to documentation, it is an anti-pattern of DynamoDB usage. How to deal with the situation? Could be creating evenly distributed primary key and then a secondary key which primary part is the same for all items but sort part is different for all of them be a better solution?
You can use Global Secondary Index which in essence is
A global secondary index contains a selection of attributes from the base table, but they are organized by a primary key that is different from that of the table.
So you can query on other attributes that are unique.
I.e. as it might not be clear what I meant, is that you can choose something else as primary key that is possible to be unique and use a repetetive ID as GSI on which you are going to base your query.
NOTE: One of the widest applications of NoSQL DBs is to store timeseries, which you cannot expect to have a unique identifier as PK, unless you specify the timestamp.

DynamoDB create index on map or list type

I'm trying to add an index to an attribute inside of a map object in DynamoDB and can't seem to find a way to do so. Is this something that is supported or are indexes really only allowed on scalar values? The documentation around this seems to be quite sparse. I'm hoping that the indexing functionality is similar to MongoDB but so far the approaches I've taken of referencing the attribute to index using dot syntax has not been successful. Any help or additional info that can be provided is appreciated.
Indexes can be built only on top-level JSON attributes. In addition, range keys must be scalar values in DynamoDB (one of String, Number, Binary, or Boolean).
From http://aws.amazon.com/dynamodb/faqs/:
Q: Is querying JSON data in DynamoDB any different?
No. You can create a Global Secondary Index or Local Secondary Index
on any top-level JSON element. For example, suppose you stored a JSON
document that contained the following information about a person:
First Name, Last Name, Zip Code, and a list of all of their friends.
First Name, Last Name and Zip code would be top-level JSON elements.
You could create an index to let you query based on First Name, Last
Name, or Zip Code. The list of friends is not a top-level element,
therefore you cannot index the list of friends. For more information
on Global Secondary Indexing and its query capabilities, see the
Secondary Indexes section in this FAQ.
Q: What data types can be indexed?
All scalar data types (Number, String, Binary, and Boolean) can be
used for the range key element of the local secondary index key. Set,
list, and map types cannot be indexed.
I have tried doing hash(str(object)) while I store the object separately. This hash gives me an integer(Number) and I am able to use a secondary index on it. Below is a sample in python, it is important to use a hash function which generates the same hash key every time for the value. So I am using sha1.
# Generate a small integer hash:
import hashlib
def hash_8_digits(source):
return int(hashlib.sha1(source.encode()).hexdigest(), 16) % (10 ** 8)
The idea is to keep the entire object small while still the entity intact. i.e. rather than serializing and storing the object as string and changing whole way the object is used I am storing a smaller hash value along with the actual list or map.

Creating properties for Lua

I wasn't sure how to word the title, but here we go.
Let's say I made a Lua function to create a 2D box appear on the screen - for example:
box = createObject("Box")
How would I create properties for box that would subsequently change how box looks or reacts? For example I may want to do
box.PositionX = 0
box.PositionY = 60
How do I do that in C++?
Just answering the direct question itself, things are simple:
Just use the standard metatable-aware add/set-table-index API.
If we look at how box itself should look, things get interesting:
If createObject "Box" returns a Lua table and you don't need to react immediately on change, just don't do anything special.
If createObject "Box" returns a Lua table but you need to react immediately, let it act as a proxy object, aka force using the metatable function by never adding that element to the table itself. Remap to another index or another table saved at a dedicated index or in the metatable/metatable function closures.
If createObject "Box" returns a userdata, do the same as for 2, maybe saving non-lua-values in C for faster access/higher efficiency, using the environment table for all other values.

Beginner LuaPlus Metatables Question

I'm brand new to Lua/LuaPlus and trying to figure out how metatables work.
In this code taken from the manual:
LuaObject metaTableObj = state->GetGlobals().CreateTable("MultiObjectMetaTable");
metaTableObj.SetObject("__index", metaTableObj);
metaTableObj.RegisterObjectFunctor("Print", &MultiObject::Print);
In the first line we create a new table, but the second line is a little confusing. In this table we just created, we are setting the element with key __index equal to the table itself. Why is __index chosen as a key and why set an element of the table to be equal to the table itself?
And then in the next section of code:
MultiObject obj1(10);
LuaObject obj1Obj = state->BoxPointer(&obj1);
obj1Obj.SetMetaTable(metaTableObj);
state->GetGlobals().SetObject("obj1", obj1Obj);
We create a C++ object, associate its address with a LuaObject via the BoxPointer call, and set the metatable so that we can use the Print function.
But for the last line, is that just creating a global Lua variable called "obj1"? At this point "obj1" and "MultiObjectMetaTable" will be global Lua variables?
This is not standard Lua, it looks like you're using some C++ wrapper that I'm unfamiliar with, but I can make some guesses
In the first line we create a new table, but the second line is a
little confusing. In this table we just created, we are setting the
element with key __index equal to the table itself. Why is __index
chosen as a key and why set an element of the table to be equal to the
table itself?
__index is a special key when using metatables. If I have a table t and I try to index into it with a key of foo for example, naturally, I'll get back the value associated with that key. But lets say there's nothing there. Normally if you try to index into a spot that has nothing, you'll get nil back.
But not if you have a metatable with the special key __index in it! If you have a metatable with an __index function or table, it'll use that to find you your value. If you have a table assigned to __index as you do here, it'll look into that table and return the value at the key you provided. This allows you get inheritance-like behavior. i.e. if table t doesn't have this value, default to the value in this other table instead.
But for the last line, is that just creating a global Lua variable called "obj1"? At this point "obj1" and "MultiObjectMetaTable" will be global Lua variables?
As I mentioned, this is not standard Lua, so I'm not totally sure what's happening there. (Mixing C++ and Lua can get tricky though, so while you're still learning Lua it's probably better that you stick to the C interface so you can understand whats really happening. Once you understand that you can move on to more automated solutions)