14 \$cache functions

Class hierarchy of DGS nodes

There are two subclasses of DGIndepNode and 4 subclasses of DGDepNode giving rise to 6 specialised DGS node classes corresponding to 6 kinds of $cache functions.

Kinds of $cache functions

The following table shows how these 6 classes relate to properties of the $cache functions:

Classsynchronous/asynchronous?function arguments?With input?
DGSyncDepNode synchronous none no
DGKeyedSyncDepNode synchronous one or moreno
DGAsyncIndepNode asynchronous none no
DGKeyedAsyncIndepNode asynchronous one or moreno
DGAsyncNodeOnInput asynchronous none yes
DGKeyedAsyncNodeOnInput asynchronous one or moreyes

Example usage

ClassExample
DGSyncDepNode
$cache int y() const
DGKeyedSyncDepNode
$cache int y(int a) const
DGAsyncIndepNode
$cache <<async>> int y() const
DGKeyedAsyncIndepNode
$cache <<async>> int y(int a) const
DGAsyncNodeOnInput
$cache <<async>> int y() const with int x = f();
DGKeyedAsyncNodeOnInput
$cache <<async>> int y(int a) const with int x = f();

UpdateOutput

All 4 asynchronous $cache functions need to update the cached output when the calculation is complete. The template function UpdateOutput is used for this purpose. By default swap is used. It can be specialised on specific types if swap isn't appropriate.


template<typename Output>
void UpdateOutput(Output& dst, Output& src)
{
    using namespace std;
    swap(dst, src);
}

Setting thread local storage for the asynchronous task

All 4 asynchronous $cache functions need to set thread local storage as required for the thread that will execute the code to calculate a new output then update it with a CSpaceTxn.

For that purpose the following function is provided by the cxObject library, which calls a hook provided in either the cxPersistStore or cxOperation libraries:


// Declared in IObject.h, implemented in IObject.cpp
@api void PrepareThreadLocalStorage(ptr<const IObject> p)
{
    if (CSpace* cspace = GetAssociatedCSpace(p))
    {
        OCB_SetThreadLocalStorage(cspace);
    }
}

// OperationCallBacks.cpp
@api void OCB_SetThreadLocalStorage(CSpace* cspace)
{
    cxAssert(cspace);
    SetThreadPtr<CSpace>(cspace);
    if (s_operationCallBacks)
    {
        s_operationCallBacks->SetThreadLocalStorage(cspace);
    }
}

// PersistOperationCallbacks.cpp
void PersistOperationCallbacks::SetThreadLocalStorage(CSpace* cspace)
{
    cxAssert(cspace);
    if (PSpace* pspace = GetPSpaceOfCSpace(cspace))
    {
        SetThreadPtr<PSpace>(pspace);
    }
}

// WorkingSetMachine.cpp
void OperationCallbacks::SetThreadLocalStorage(CSpace* cspace)
{
    cxAssert(cspace);
    if (PSpace* pspace = GetPSpaceOfCSpace(cspace))
    {
        SetThreadPtr<PSpace>(pspace);
    }
}

There was a time when the working set had to be set in thread local storage but that is no longer the case. Therefore both cxPersistStore or cxOperation only set the PSpace in TLS.

Disable visiting of the mapped variables

<<-visit>> can be used to disable visiting of the mapped variables

$cache functions with void return type

Return type can be void, but in that case