November 22, 2013
Is this a plausible approach?
What I've sketched out so far is:
/**    cells2.d    */

import    std.concurrency;
import    std.stdio;

import    cellsdb;

Tid    tids[8];

void    cellLoop (int i)
{    Cells[ulong]    cells;
    bool    rcv    =    true;
    int    thisTin    =    i;
    for(;;)
    {    foreach    (k, v; cells)
        {
            while    (rcv)
            {    rcv    =    receiveTimeout (0,
                    //TODO  Write the messages that actually do the work.
                    (Variant    any)
                        {    writefln ("cellLoop couldn't handle receiving {0}".
                                    format(any.type);
                        }
            }
            //TODO    housekeeping on cells.
        }    //    foreach    (k, v; cells)
        //TODO    handle any deletions from cells
    }    //    for(;;)
}  // cellLoop

/**    Given an id#, return the index to the thread id in which it should be found.     */
Tin    idToTin (ulong    id)
{    return    (id / 2^13) % tids.length;    }

void    main()
{
    for    (int i = 0;    i < tids.length;    i++)    tids[i] =    spawn (&cellLoop, i);
   //TODO  start the threads working
}


There's a bunch of other code, but it's off the point.  Part of the reason for the idToTin method is that cells close together are expected to make mutual calls more often.  My expectation is that message passing is more expensive than subroutine calls, so if calls are within the same thread, they can be called directly rather than making message passing invocations.  I'm sharing the array of Tids, but it's only written once.  I'd make it immutable if I could figure out how...short of wrapping everything in a class with an init method.

The basic (questionable) idea here is that the best way to step through an AA is to use foreach, so the if I want to do the housekeeping in short runs (so the threads don't slow interaction) I need to have the receive within the foreach.  The alternative approach I came up with is to store the data in a RedBlack tree, which would make it easy to interrupt and resume whenever I needed, but which is less efficient for access than a hash table.  The penalty is that I ALWAY do at least one housekeeping task between each receive.  Also, when I need to break out of the inner loop to allow for cell deletion, I start over from the beginning, without ever having processed the end.  Not good, as cell deletions aren't expected to be all that rare.

-- 
Charles Hixson