21 Independent DGS nodes

Independent DGS nodes can have out-nodes but can't have in-nodes.

DGIndepNode

DGIndepNode
class DGIndepNode : public DGBaseNode
{
public:
    DGIndepNode();

    DGIndepNode(const DGIndepNode& rhs);
    DGIndepNode& operator=(const DGIndepNode& rhs) { return *this; }

    virtual bool IsEvictable() const { return true; }
    void OnChange() const;
    void ReadBarrier() const;

protected:
    virtual void EnsureNoInnodesOrOutnodes() const;
};

IObject.h

// Read/write barriers for an independent field that takes part in the Dependency Graph System
// (DGS)
// obj is an IObject that contains a field located at 'fieldAddress'.
// obj is (only) passed in order to allow the DGS to visit the object containing the field so
// that it is strongly reachable and therefore protected from GC.
// fieldAddress must not be nullptr.  It is permissible to call with obj = null, if visiting of
// the containing object is not required.
// The type of the field is irrelevant to the DGS - its identity is simply associated with its
// address in memory.  Note therefore that it cannot be relocated (e.g. be an element of an
// xvector).
@api void DataSourceEvict(const void* fieldAddress);
@api void DataSourceReadBarrier(const void* fieldAddress, ptr<const IObject> obj, const char* name);
@api void DataSourceWriteBarrier(const void* fieldAddress, ptr<const IObject> obj, const char* name);

/*
These functions all assume obj is not null and obj->GetReflectedClass() is not null
The path identifies the field which is accessed.
If the path is empty then DataSourceEvict() evicts all DGS nodes under the given object.
*/
@api void EvictIndepFieldsUnderObject(ptr<const IObject> obj);
@api void IndepFieldEvict(ptr<const IObject> obj, const Path& path);
@api void IndepFieldReadBarrier(ptr<const IObject> obj, const Path& path);
@api void IndepFieldWriteBarrier(ptr<const IObject> obj, const Path& path);

// Convenience functions for when we have a path to a model or array and an index into an element of the model or array
@api void IndepFieldReadBarrier(ptr<const IObject> obj, const Path& pathToModelOrArray, ssize_t elementIndex);
@api void IndepFieldWriteBarrier(ptr<const IObject> obj, const Path& pathToModelOrArray, ssize_t elementIndex);

DGSystem

A CSpace contains a single object instance of DGSystem. This has support for representing independent DGS nodes associated with fields of models.

There are two approaches implemented, one for where a model is part of an IPersistable object and allows a field to be identified by an (oid,path) pair, and one for where the address of the field in memory is used to identify the field.

class DGSystem
{
public:
    ///////////////// Indep nodes identified by path under object
    /*
    Used for models for which operations are generated

    These functions all assume obj is not null and obj->GetReflectedClass() is not null
    The path identifies the field which is accessed.
    If the path is empty then DataSourceEvict() evicts all DGS nodes under the given object.
    */
    void DeleteIndepField(ptr<const IObject> obj, const Path& path);
    void EvictIndepFieldsUnderObject(ptr<const IObject> obj);
    void IndepFieldEvict(ptr<const IObject> obj, const Path& path);
    void IndepFieldReadBarrier(ptr<const IObject> obj, const Path& path);
    void IndepFieldWriteBarrier(ptr<const IObject> obj, const Path& path);

    ///////////////// Indep nodes identified by address of the field in memory
    // Used for models for which operations are not generated

    void DataSourceEvict(const void* fieldAddress);
    void DataSourceReadBarrier(const void* fieldAddress, ptr<const IObject> obj, const char* name);
    void DataSourceWriteBarrier(const void* fieldAddress, ptr<const IObject> obj, const char* name);
    void DeleteIndepNode(const DGIndepNodeForDataModelField* node)
    {
        indepNodeMap_.Delete(node);
    }

private:
    // This is the newer implementation which uses a map keyed by ptr<const IObject> to a
    // tree of indep nodes organised by the path
    DGIndepNodeMap indepFieldNodeMap_;

    // This is the older implementation which uses the address in memory of the field
    // to identify it.
    DGActiveIndepNodeMap indepNodeMap_;
};

Links

Async $cache functions

Asynchronous $cache functions also represent independent nodes in the DGS. See DGAsyncIndepNode and DGKeyedAsyncIndepNode.