Merge changes If2510ab3,I811f3109
* changes:
MediaMetrics: Add copy constructor to TransactionLog
MediaMetrics: Add copy constructor to TimeMachine
diff --git a/services/mediametrics/TimeMachine.h b/services/mediametrics/TimeMachine.h
index 8682360..4d24ce4 100644
--- a/services/mediametrics/TimeMachine.h
+++ b/services/mediametrics/TimeMachine.h
@@ -60,7 +60,7 @@
*
* The TimeMachine is NOT thread safe.
*/
-class TimeMachine {
+class TimeMachine final { // made final as we have copy constructor instead of dup() override.
public:
using Elem = Item::Prop::Elem; // use the Item property element.
using PropertyHistory = std::multimap<int64_t /* time */, Elem>;
@@ -84,6 +84,8 @@
putValue(BUNDLE_UID, (int32_t)uid, time);
}
+ KeyHistory(const KeyHistory &other) = default;
+
status_t checkPermission(uid_t uidCheck) const {
return uidCheck != (uid_t)-1 && uidCheck != mUid ? PERMISSION_DENIED : NO_ERROR;
}
@@ -189,6 +191,34 @@
__func__, keyHighWaterMark, keyLowWaterMark);
}
+ // The TimeMachine copy constructor/assignment uses a deep copy,
+ // though the snapshot is not instantaneous nor isochronous.
+ //
+ // If there are concurrent operations ongoing in the other TimeMachine
+ // then there may be some history more recent than others (a time shear).
+ // This is expected to be a benign addition in history as small number of
+ // future elements are incorporated.
+ TimeMachine(const TimeMachine& other) {
+ *this = other;
+ }
+ TimeMachine& operator=(const TimeMachine& other) {
+ std::lock_guard lock(mLock);
+ mHistory.clear();
+
+ {
+ std::lock_guard lock2(other.mLock);
+ mHistory = other.mHistory;
+ }
+
+ // Now that we safely have our own shared pointers, let's dup them
+ // to ensure they are decoupled. We do this by acquiring the other lock.
+ for (const auto &[lkey, lhist] : mHistory) {
+ std::lock_guard lock2(other.getLockForKey(lkey));
+ mHistory[lkey] = std::make_shared<KeyHistory>(*lhist);
+ }
+ return *this;
+ }
+
/**
* Put all the properties from an item into the Time Machine log.
*/
diff --git a/services/mediametrics/TransactionLog.h b/services/mediametrics/TransactionLog.h
index 7a520d9..0c5d12b 100644
--- a/services/mediametrics/TransactionLog.h
+++ b/services/mediametrics/TransactionLog.h
@@ -36,7 +36,7 @@
*
* The TransactionLog is NOT thread safe.
*/
-class TransactionLog {
+class TransactionLog final { // made final as we have copy constructor instead of dup() override.
public:
// In long term run, the garbage collector aims to keep the
// Transaction Log between the Low Water Mark and the High Water Mark.
@@ -58,6 +58,30 @@
__func__, highWaterMark, lowWaterMark);
}
+ // The TransactionLog copy constructor/assignment is effectively an
+ // instantaneous, isochronous snapshot of the other TransactionLog.
+ //
+ // The contents of the Transaction Log are shared pointers to immutable instances -
+ // std::shared_ptr<const mediametrics::Item>, so we use a shallow copy,
+ // which is more efficient in space and execution time than a deep copy,
+ // and gives the same results.
+
+ TransactionLog(const TransactionLog &other) {
+ *this = other;
+ }
+
+ TransactionLog& operator=(const TransactionLog &other) {
+ std::lock_guard lock(mLock);
+ mLog.clear();
+ mItemMap.clear();
+
+ std::lock_guard lock2(other.mLock);
+ mLog = other.mLog;
+ mItemMap = other.mItemMap;
+
+ return *this;
+ }
+
/**
* Put an item in the TransactionLog.
*/