Data Access Layer

The Data Access Layer is the only object that interfaces directly with the Data Store. It ensures thread-safety via Data Element Accessors (class: EcDataElementAccessor)

Available Operations

  • Add an element to data store
  • Create an accessor to an element in the data store

Methods

The Data Access Layer provides methods for getting and setting element data by

  • Value
    • Using getValue() and setValue() methods
    • Implicit mutex locking
  • Reference
    • Using uniqueLockHandle() and sharedLockHandle() methods
    • Explicit mutex locking

An accessor provides safe access to the data store to read and write data values including primitive (int, double, float, string) as well as objects and resource references.

// check that the accessor is valid and compare the value with the provided value
if(accessor)
{
    EcBoolean retVal = EcTrue;

    ValueType valueCopy = value;

    // accessors provide direct thread safe access through four methods
    // *  accessor->setValue
    // *  accessor->getValue
    // *  accessor->sharedLockHandle
    // *  accessor->uniqueLockHandle

    // The setValue and getValue methods perform implicit mutex locking
    // The sharedLockHandle and uniqueLockHandle perform explicit mutex locking

    // we will now test all access methods

    // Try using a shared handle for read only access
    // A shared lock is obtained when the handle is created and released when it is destroyed.
    {
        EcSharedLockDataHandle<ValueType> handle = accessor->sharedLockHandle();
        const ValueType& valueConstRef = handle.value();
        retVal &= (valueConstRef == value);
    }

    // Next try using a unique handle for read/write access
    // A unique lock is obtained when the handle is created and released when it is destroyed.
    {
        EcUniqueLockDataHandle<ValueType> handle = accessor->uniqueLockHandle();
        ValueType& valueRef = handle.value();
        retVal &= (valueRef == value);
    }

    // setValue returns true if the value is set.
    // A unique lock is obtained implicitly while the copy operation is performed.
    retVal &= accessor->setValue(valueCopy);

    // getValue returns true if the value is retrieved.
    // A shared lock is obtained implicitly while the copy operation is performed
    retVal &= accessor->getValue(valueCopy);

    // check the retrieved value
    retVal &= (valueCopy == value);

    return retVal;
}

Source code: examples/dataStoreConfigExample/ecDataStoreConfigExample.h The code snapshot in figure 1 shows how to lock the resource for either reading or writing, and then how to set or get the element of interest.

Accessing Data Element Groups

Accessing groups of data elements can be done through the EcDataGroupAccessor class. This reduces the possibility of deadlocks by locking elements in the same order.

A group lock is constructed from a tuple of EcDataElementAccessor

typename EcDataGroupAccessor<AccessorTuple>::shared_ptr pGroupAccessor( new EcDataGroupAccessor<AccessorTuple>(accessorTuple));

if(!pGroupAccessor->isValid())
{
    return EcFalse;
}

// First try using a shared lock group handle for read/write access
// The group's mutexes are locked in order based on address of the mutex and unlocked in the reverse order.
EcBoolean retVal = EcTrue;

EcPrint(Info) << "  --Group Shared Lock Test:" << std::endl;
{
    EcSharedLockGroupHandle<AccessorTuple> handle = pGroupAccessor->sharedLockHandle();

    // Use the test helper to iterate through all the tuple elements and
    // check if the accessed value is equal to the test value
    retVal &= EcDataGroupTestHelper<
        EcSharedLockGroupHandle<AccessorTuple>,
    ValueTuple,
    ecboost::tuples::length<ValueTuple>::value
        >::test
            (
            handle,
            valueTuple
        );
}

EcPrint(Info) << "  --Group Unique Lock Test:" << std::endl;
// Next try using a unique handle for read/write access
// The group's mutexes are locked in order based on address of the mutex and unlocked in the reverse order.
{
    EcUniqueLockGroupHandle<AccessorTuple> handle = pGroupAccessor->uniqueLockHandle();

    // Use the test helper to iterate through all the tuple elements and
    // check if the accessed value is equal to the test value
    retVal &= EcDataGroupTestHelper<
        EcUniqueLockGroupHandle<AccessorTuple>,
    ValueTuple,
    ecboost::tuples::length<ValueTuple>::value
        >::test
            (
            handle,
            valueTuple
        );
}

Source code: examples/dataStoreConfigExample/ecDataStoreConfigExample.h

Adding a Data Element to the Data Store

EcDataAccessLayer           m_DataAccessLayer; 
...
m_DataAccessLayer.addDataElement(COUNT,    EcU32(0) );