summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2018-05-17 20:24:51 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-05-17 20:24:51 +0200
commitc81fe1578e4151e230ffa08a6c5b26b535593ee7 (patch)
treeb301309f15b9f70f52b05a13af756352bced84cb
parenteb54f3795fb276046c1a4c0e81fb5426f0659550 (diff)
downloadsink-c81fe1578e4151e230ffa08a6c5b26b535593ee7.tar.gz
sink-c81fe1578e4151e230ffa08a6c5b26b535593ee7.zip
Copy the entity when we return it.
Otherwise we easily end up copying it and then have an entity that points into nowhere. Callback -> no copy, no callback -> copy.
-rw-r--r--common/entitybuffer.h11
-rw-r--r--common/storage/entitystore.cpp8
-rw-r--r--common/storage/entitystore.h10
3 files changed, 25 insertions, 4 deletions
diff --git a/common/entitybuffer.h b/common/entitybuffer.h
index 4162605..d73a138 100644
--- a/common/entitybuffer.h
+++ b/common/entitybuffer.h
@@ -12,7 +12,18 @@ struct Entity;
12class SINK_EXPORT EntityBuffer 12class SINK_EXPORT EntityBuffer
13{ 13{
14public: 14public:
15 /**
16 * Creates an entity buffer from @param dataValue.
17 *
18 * Note that @param dataValue will need to remain valid and the data is not copied.
19 */
15 EntityBuffer(const void *dataValue, int size); 20 EntityBuffer(const void *dataValue, int size);
21
22 /**
23 * Creates an entity buffer from @param data.
24 *
25 * Note that @param data will need to remain valid and the data is not copied.
26 */
16 EntityBuffer(const QByteArray &data); 27 EntityBuffer(const QByteArray &data);
17 const uint8_t *resourceBuffer(); 28 const uint8_t *resourceBuffer();
18 const uint8_t *metadataBuffer(); 29 const uint8_t *metadataBuffer();
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp
index 638be6e..4560b13 100644
--- a/common/storage/entitystore.cpp
+++ b/common/storage/entitystore.cpp
@@ -249,7 +249,7 @@ bool EntityStore::add(const QByteArray &type, ApplicationDomain::ApplicationDoma
249 249
250ApplicationDomain::ApplicationDomainType EntityStore::applyDiff(const QByteArray &type, const ApplicationDomain::ApplicationDomainType &current, const ApplicationDomain::ApplicationDomainType &diff, const QByteArrayList &deletions) const 250ApplicationDomain::ApplicationDomainType EntityStore::applyDiff(const QByteArray &type, const ApplicationDomain::ApplicationDomainType &current, const ApplicationDomain::ApplicationDomainType &diff, const QByteArrayList &deletions) const
251{ 251{
252 auto newEntity = *ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<ApplicationDomain::ApplicationDomainType>(current, current.availableProperties()); 252 auto newEntity = *ApplicationDomainType::getInMemoryRepresentation<ApplicationDomainType>(current, current.availableProperties());
253 253
254 SinkTraceCtx(d->logCtx) << "Modified entity: " << newEntity; 254 SinkTraceCtx(d->logCtx) << "Modified entity: " << newEntity;
255 255
@@ -512,7 +512,7 @@ ApplicationDomain::ApplicationDomainType EntityStore::readLatest(const QByteArra
512{ 512{
513 ApplicationDomain::ApplicationDomainType dt; 513 ApplicationDomain::ApplicationDomainType dt;
514 readLatest(type, uid, [&](const ApplicationDomain::ApplicationDomainType &entity) { 514 readLatest(type, uid, [&](const ApplicationDomain::ApplicationDomainType &entity) {
515 dt = entity; 515 dt = *ApplicationDomainType::getInMemoryRepresentation<ApplicationDomainType>(entity, entity.availableProperties());
516 }); 516 });
517 return dt; 517 return dt;
518} 518}
@@ -539,7 +539,7 @@ ApplicationDomain::ApplicationDomainType EntityStore::readEntity(const QByteArra
539{ 539{
540 ApplicationDomain::ApplicationDomainType dt; 540 ApplicationDomain::ApplicationDomainType dt;
541 readEntity(type, uid, [&](const ApplicationDomain::ApplicationDomainType &entity) { 541 readEntity(type, uid, [&](const ApplicationDomain::ApplicationDomainType &entity) {
542 dt = entity; 542 dt = *ApplicationDomainType::getInMemoryRepresentation<ApplicationDomainType>(entity, entity.availableProperties());
543 }); 543 });
544 return dt; 544 return dt;
545} 545}
@@ -601,7 +601,7 @@ ApplicationDomain::ApplicationDomainType EntityStore::readPrevious(const QByteAr
601{ 601{
602 ApplicationDomain::ApplicationDomainType dt; 602 ApplicationDomain::ApplicationDomainType dt;
603 readPrevious(type, uid, revision, [&](const ApplicationDomain::ApplicationDomainType &entity) { 603 readPrevious(type, uid, revision, [&](const ApplicationDomain::ApplicationDomainType &entity) {
604 dt = entity; 604 dt = *ApplicationDomainType::getInMemoryRepresentation<ApplicationDomainType>(entity, entity.availableProperties());
605 }); 605 });
606 return dt; 606 return dt;
607} 607}
diff --git a/common/storage/entitystore.h b/common/storage/entitystore.h
index 003a2ca..c89c095 100644
--- a/common/storage/entitystore.h
+++ b/common/storage/entitystore.h
@@ -39,6 +39,8 @@ public:
39 EntityStore(const ResourceContext &resourceContext, const Sink::Log::Context &); 39 EntityStore(const ResourceContext &resourceContext, const Sink::Log::Context &);
40 ~EntityStore() = default; 40 ~EntityStore() = default;
41 41
42 using ApplicationDomainType = ApplicationDomain::ApplicationDomainType;
43
42 void initialize(); 44 void initialize();
43 45
44 //Only the pipeline may call the following functions outside of tests 46 //Only the pipeline may call the following functions outside of tests
@@ -63,10 +65,14 @@ public:
63 return indexLookup(ApplicationDomain::getTypeName<EntityType>(), PropertyType::name, value, callback); 65 return indexLookup(ApplicationDomain::getTypeName<EntityType>(), PropertyType::name, value, callback);
64 } 66 }
65 67
68 ///Returns the uid and buffer. Note that the memory only remains valid until the next operation or transaction end.
66 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback); 69 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback);
70 ///Returns an entity. Note that the memory only remains valid until the next operation or transaction end.
67 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback); 71 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback);
72 ///Returns an entity and operation. Note that the memory only remains valid until the next operation or transaction end.
68 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity, Sink::Operation)> callback); 73 void readLatest(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity, Sink::Operation)> callback);
69 74
75 ///Returns a copy
70 ApplicationDomain::ApplicationDomainType readLatest(const QByteArray &type, const QByteArray &uid); 76 ApplicationDomain::ApplicationDomainType readLatest(const QByteArray &type, const QByteArray &uid);
71 77
72 template<typename T> 78 template<typename T>
@@ -74,8 +80,11 @@ public:
74 return T(readLatest(ApplicationDomain::getTypeName<T>(), uid)); 80 return T(readLatest(ApplicationDomain::getTypeName<T>(), uid));
75 } 81 }
76 82
83 ///Returns the uid and buffer. Note that the memory only remains valid until the next operation or transaction end.
77 void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback); 84 void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback);
85 ///Returns an entity. Note that the memory only remains valid until the next operation or transaction end.
78 void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback); 86 void readEntity(const QByteArray &type, const QByteArray &uid, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback);
87 ///Returns a copy
79 ApplicationDomain::ApplicationDomainType readEntity(const QByteArray &type, const QByteArray &key); 88 ApplicationDomain::ApplicationDomainType readEntity(const QByteArray &type, const QByteArray &key);
80 89
81 template<typename T> 90 template<typename T>
@@ -86,6 +95,7 @@ public:
86 95
87 void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback); 96 void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const QByteArray &uid, const EntityBuffer &entity)> callback);
88 void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback); 97 void readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision, const std::function<void(const ApplicationDomain::ApplicationDomainType &entity)> callback);
98 ///Returns a copy
89 ApplicationDomain::ApplicationDomainType readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision); 99 ApplicationDomain::ApplicationDomainType readPrevious(const QByteArray &type, const QByteArray &uid, qint64 revision);
90 100
91 template<typename T> 101 template<typename T>