Eep, seems I hit send...

On Thursday, 10 January 2013 at 05:47:01 UTC, H. S. Teoh wrote:
The basic idea behind static AA literals is to use CTFE to compute the hashes of the keys, and therefore which slot(s) they will fall in, at compile time. Armed with this information, we can create an array of slots at compile-time that contains the AA entries by declaring each slot as a static variable and using the slot assignment information to initialize the hash table (array of pointers to slots) to point to these slots.

Hmmm somehow that doesn't seem like a good idea; I mean it will work....

Alternative is to sorta have a pair of static arrays, then either use a balanced tree, or a modulus to best hold (and separate) the values.

 Modulus based: It could be like...

  //T obviously replace with appropriate type
  ref T AA_lookup(name publicName)(uint hash) {
    //offset for part1
    //could be external to..
immutable static int offsets[]; //no need for pointers, right?
    immutable static T values[]; //contains actual item data

    enum mod; //divider for table.
    uint result = hash % mod;

    //or branch to return empty? But can't be ref then...
    assert(offsets[result] != -1);

    return values[offsets[result]];
  }

Then your CTFE increases the mod in it's calculations until every element can fit only once, and make the offsets based on them. Default values would be -1 (range error if called), course if it's mod is rather large and wastes a lot of space then perhaps it falls back on the tree structure (in those cases, > 3x of array size)


Tree: I don't mind a minor performance hit, log(n) is a very small hit in my mind. In that case a statically created tree is rather easy. AA's created ahead of time are likely rather small (<1 Million elements). So a tree structure of:

 struct Node(T) {
   //pointers don't seem like they are needed;
   //Can even be ushorts or ubytes if small enough.
   uint left, right;
   T* value;
 }

 You get the idea.

Reply via email to