DataSetIF: Add read() and commit() to interface and move code to base class #97

Closed
opened 2020-06-01 18:43:55 +02:00 by muellerr · 3 comments
Owner

Both dataset variants (global and local) have an almost identical code base. I moved common code into a base class. All datasets implemented so far had the read() and commit() calls so maybe these should be added to the interface.

Code which is implementation specific is the lock of the underlying data structure.
I suggest adding read(millis_t lockTimeout) and commit(millis_t lockTimeout) to the interface as these functions are the core methods of the dataset class.

This is not an API change, data set implemention can set the default block timeout as MutexIF::MAX_TIMEOUT which blocks the mutex (indefinitely) until it becomes available.,

Both dataset variants (global and local) have an almost identical code base. I moved common code into a base class. All datasets implemented so far had the `read()` and `commit()` calls so maybe these should be added to the interface. Code which is implementation specific is the lock of the underlying data structure. I suggest adding `read(millis_t lockTimeout)` and `commit(millis_t lockTimeout)` to the interface as these functions are the core methods of the dataset class. This is not an API change, data set implemention can set the default block timeout as MutexIF::MAX_TIMEOUT which blocks the mutex (indefinitely) until it becomes available.,
muellerr added the
feature
label 2020-06-01 18:43:55 +02:00
Author
Owner

UPDATE: Base class will not provide a static buffer of pool variables. Instead, it will store a pointer to the pool variables while a child class will supply the underlying data structure to store the pool variables.

For example, a StaticDataSet class might still use the static buffer with 63 pointers, while a different DataSet class will use a vector and reserve the maximum expected length in advance. This way, a dataset which is initialized at compile time on the heap will be a lot more memory efficient and could for example be used to access housekeeping data.

Example base class ctor:

DataSetBase::DataSetBase(PoolVariableIF** registeredVariablesArray,
        const size_t maxFillCount):
        registeredVariables(registeredVariablesArray),
        maxFillCount(maxFillCount) {
	for (uint8_t count = 0; count < maxFillCount; count++) {
		registeredVariables[count] = nullptr;
	}
}

LocalDataSet ctor, which uses a vector of PoolVariableIF pointers

LocalDataSet::LocalDataSet(OwnsLocalDataPoolIF *hkOwner,
        const size_t maxNumberOfVariables):
        DataSetBase(poolVarList.data(), maxNumberOfVariables) {
    poolVarList.reserve(maxNumberOfVariables);
    poolVarList.resize(maxNumberOfVariables);
    if(hkOwner == nullptr) {
        sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!"
                << std::endl;
        return;
    }
    hkManager = hkOwner->getHkManagerHandle();
}
UPDATE: Base class will not provide a static buffer of pool variables. Instead, it will store a pointer to the pool variables while a child class will supply the underlying data structure to store the pool variables. For example, a StaticDataSet class might still use the static buffer with 63 pointers, while a different DataSet class will use a vector and reserve the maximum expected length in advance. This way, a dataset which is initialized at compile time on the heap will be a lot more memory efficient and could for example be used to access housekeeping data. Example base class ctor: ```cpp DataSetBase::DataSetBase(PoolVariableIF** registeredVariablesArray, const size_t maxFillCount): registeredVariables(registeredVariablesArray), maxFillCount(maxFillCount) { for (uint8_t count = 0; count < maxFillCount; count++) { registeredVariables[count] = nullptr; } } ``` LocalDataSet ctor, which uses a vector of PoolVariableIF pointers ```cpp LocalDataSet::LocalDataSet(OwnsLocalDataPoolIF *hkOwner, const size_t maxNumberOfVariables): DataSetBase(poolVarList.data(), maxNumberOfVariables) { poolVarList.reserve(maxNumberOfVariables); poolVarList.resize(maxNumberOfVariables); if(hkOwner == nullptr) { sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" << std::endl; return; } hkManager = hkOwner->getHkManagerHandle(); } ```
Author
Owner

UPDATE: DataSet will propably be split up into a StaticLocalDataSet and normal LocalDataSet which will both implement DataSetBase. StaticLocalDataSet will use a fixed size buffer of pointers while the normal implementation will use a vector (initialization on start-up) to reduce memory usage for data sets hwich are created once on the heap

UPDATE: DataSet will propably be split up into a StaticLocalDataSet and normal LocalDataSet which will both implement DataSetBase. StaticLocalDataSet will use a fixed size buffer of pointers while the normal implementation will use a vector (initialization on start-up) to reduce memory usage for data sets hwich are created once on the heap
Owner

Part of #280

Part of #280
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: fsfw/fsfw#97
No description provided.