diff --git a/cppcache/include/geode/Region.hpp b/cppcache/include/geode/Region.hpp index 4b10a1e22a..1c3d7148f1 100644 --- a/cppcache/include/geode/Region.hpp +++ b/cppcache/include/geode/Region.hpp @@ -314,13 +314,13 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { * @throws RegionDestroyedException if the method is called on a destroyed *region **/ - virtual std::shared_ptr get( + virtual std::shared_ptr get( const std::shared_ptr& key, const std::shared_ptr& aCallbackArgument = nullptr) = 0; /** Convenience method allowing key to be a const char* */ template - inline std::shared_ptr get( + inline std::shared_ptr get( const KEYTYPE& key, const std::shared_ptr& callbackArg = nullptr) { return get(CacheableKey::create(key), callbackArg); @@ -373,7 +373,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { */ virtual void put( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument = nullptr) = 0; /** Convenience method allowing both key and value to be a const char* */ @@ -385,7 +385,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { /** Convenience method allowing key to be a const char* */ template - inline void put(const KEYTYPE& key, const std::shared_ptr& value, + inline void put(const KEYTYPE& key, const std::shared_ptr& value, const std::shared_ptr& arg = nullptr) { put(CacheableKey::create(key), value, arg); } @@ -398,6 +398,11 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { put(key, Serializable::create(value), arg); } + virtual std::shared_ptr putIfAbsent( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& aCallbackArgument = nullptr) = 0; + /** * Places a set of new values in this region with the specified keys * given as a map of key/value pairs. @@ -447,7 +452,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { */ virtual void localPut( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument = nullptr) = 0; /** Convenience method allowing both key and value to be a const char* */ @@ -460,7 +465,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { /** Convenience method allowing key to be a const char* */ template inline void localPut(const KEYTYPE& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& arg = nullptr) { localPut(CacheableKey::create(key), value, arg); } @@ -521,7 +526,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { */ virtual void create( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument = nullptr) = 0; /** Convenience method allowing both key and value to be a const char* */ @@ -534,7 +539,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { /** Convenience method allowing key to be a const char* */ template inline void create(const KEYTYPE& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& arg = nullptr) { create(CacheableKey::create(key), value, arg); } @@ -574,7 +579,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { */ virtual void localCreate( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument = nullptr) = 0; /** Convenience method allowing both key and value to be a const char* */ @@ -587,7 +592,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { /** Convenience method allowing key to be a const char* */ template inline void localCreate(const KEYTYPE& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& arg = nullptr) { localCreate(CacheableKey::create(key), value, arg); } @@ -804,7 +809,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { */ virtual bool remove( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument = nullptr) = 0; /** Convenience method allowing both key and value to be a const char* */ @@ -817,7 +822,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { /** Convenience method allowing key to be a const char* */ template inline bool remove(const KEYTYPE& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& arg = nullptr) { return remove(CacheableKey::create(key), value, arg); } @@ -926,7 +931,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { */ virtual bool localRemove( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument = nullptr) = 0; /** Convenience method allowing both key and value to be a const char* */ @@ -940,7 +945,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { /** Convenience method allowing key to be a const char* */ template inline bool localRemove(const KEYTYPE& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& arg = nullptr) { return localRemove(CacheableKey::create(key), value, arg); } @@ -1027,7 +1032,7 @@ class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this { * Return all values in the local process for this region. No value is * included for entries that are invalidated. */ - virtual std::vector> values() = 0; + virtual std::vector> values() = 0; virtual std::vector> entries(bool recursive) = 0; diff --git a/cppcache/integration/test/CMakeLists.txt b/cppcache/integration/test/CMakeLists.txt index 6eeee7abb6..8157f6f786 100644 --- a/cppcache/integration/test/CMakeLists.txt +++ b/cppcache/integration/test/CMakeLists.txt @@ -55,6 +55,7 @@ add_executable(cpp-integration-test PositionKey.cpp PositionKey.hpp RegionGetAllTest.cpp + RegionPutTest.cpp RegionPutAllTest.cpp RegionPutGetAllTest.cpp RegisterKeysTest.cpp @@ -71,6 +72,7 @@ add_executable(cpp-integration-test WanDeserializationTest.cpp WritablePdxInstanceTest.cpp ) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") target_compile_options(cpp-integration-test PUBLIC diff --git a/cppcache/integration/test/RegionPutTest.cpp b/cppcache/integration/test/RegionPutTest.cpp new file mode 100644 index 0000000000..c5b32b5cfb --- /dev/null +++ b/cppcache/integration/test/RegionPutTest.cpp @@ -0,0 +1,294 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "CacheRegionHelper.hpp" +#include "framework/Cluster.h" +#include "framework/Framework.h" +#include "framework/Gfsh.h" + +namespace { + +using apache::geode::client::Cache; +using apache::geode::client::Cacheable; +using apache::geode::client::CacheableKey; +using apache::geode::client::CacheableString; +using apache::geode::client::CommitConflictException; +using apache::geode::client::Pool; +using apache::geode::client::Region; +using apache::geode::client::RegionShortcut; + +using std::chrono::minutes; + +using ::testing::Eq; +using ::testing::IsNull; +using ::testing::NotNull; + +Cache createCache() { + using apache::geode::client::CacheFactory; + + auto cache = CacheFactory() + .set("log-level", "debug") + .set("statistic-sampling-enabled", "false") + .create(); + + return cache; +} + +std::shared_ptr createPool(Cluster& cluster, Cache& cache) { + auto poolFactory = cache.getPoolManager().createFactory(); + cluster.applyLocators(poolFactory); + return poolFactory.create("default"); +} + +std::shared_ptr setupRegion(Cache& cache, + const std::shared_ptr& pool) { + auto region = cache.createRegionFactory(RegionShortcut::PROXY) + .setPoolName(pool->getName()) + .create("region"); + + return region; +} + +std::shared_ptr setupCachingRegion(Cache& cache, + const std::shared_ptr& pool) { + auto region = cache.createRegionFactory(RegionShortcut::CACHING_PROXY) + .setPoolName(pool->getName()) + .create("region"); + + return region; +} + +TEST(RegionPutTest, testPutIfAbsentNotExistingEntry) { + Cluster cluster{LocatorCount{1}, ServerCount{1}}; + + cluster.start(); + + cluster.getGfsh() + .create() + .region() + .withName("region") + .withType("REPLICATE") + .execute(); + + auto cache = createCache(); + auto pool = createPool(cluster, cache); + auto region = setupRegion(cache, pool); + auto key = CacheableKey::create("key-1"); + auto value = CacheableString::create("value"); + + EXPECT_THAT(region->putIfAbsent(key, value), IsNull()); + + auto retrieved = region->get(key); + EXPECT_THAT(retrieved, NotNull()); + + auto converted = std::dynamic_pointer_cast(retrieved); + EXPECT_THAT(converted, NotNull()); + EXPECT_THAT(converted->toString(), Eq(value->toString())); +} + +TEST(RegionPutTest, testPutIfAbsentNotExistingEntryWithCaching) { + Cluster cluster{LocatorCount{1}, ServerCount{1}}; + + cluster.start(); + + cluster.getGfsh() + .create() + .region() + .withName("region") + .withType("REPLICATE") + .execute(); + + auto cache = createCache(); + auto pool = createPool(cluster, cache); + auto region = setupCachingRegion(cache, pool); + auto key = CacheableKey::create("key-1"); + auto value = CacheableString::create("value"); + + EXPECT_THAT(region->putIfAbsent(key, value), IsNull()); + + auto retrieved = region->get(key); + EXPECT_THAT(retrieved, NotNull()); + + auto converted = std::dynamic_pointer_cast(retrieved); + EXPECT_THAT(converted, NotNull()); + EXPECT_THAT(converted->toString(), Eq(value->toString())); + + // Verify cached value matches expected + auto entry = region->getEntry(key); + EXPECT_THAT(entry, NotNull()); + + retrieved = entry->getValue(); + EXPECT_THAT(converted, NotNull()); + + converted = std::dynamic_pointer_cast(retrieved); + EXPECT_THAT(converted, NotNull()); + EXPECT_THAT(converted->toString(), Eq(value->toString())); +} + +TEST(RegionPutTest, testPutIfAbsentExistingEntry) { + Cluster cluster{LocatorCount{1}, ServerCount{1}}; + + cluster.start(); + + cluster.getGfsh() + .create() + .region() + .withName("region") + .withType("REPLICATE") + .execute(); + + auto cache = createCache(); + auto pool = createPool(cluster, cache); + auto region = setupRegion(cache, pool); + auto key = CacheableKey::create("key-1"); + + EXPECT_NO_THROW(region->put(key, CacheableString::create("previous-value"))); + + auto value = std::dynamic_pointer_cast(region->get(key)); + + auto previous = + region->putIfAbsent(key, CacheableString::create("new-value")); + EXPECT_THAT(previous, NotNull()); + + auto converted = std::dynamic_pointer_cast(previous); + EXPECT_THAT(converted, NotNull()); + EXPECT_THAT(converted->toString(), Eq(value->toString())); +} + +TEST(RegionPutTest, testPutIfAbsentExistingEntryCaching) { + Cluster cluster{LocatorCount{1}, ServerCount{1}}; + + cluster.start(); + + cluster.getGfsh() + .create() + .region() + .withName("region") + .withType("REPLICATE") + .execute(); + + auto cache = createCache(); + auto pool = createPool(cluster, cache); + auto region = setupCachingRegion(cache, pool); + auto key = CacheableKey::create("key-1"); + + EXPECT_NO_THROW(region->put(key, CacheableString::create("previous-value"))); + + auto value = std::dynamic_pointer_cast(region->get(key)); + + auto previous = + region->putIfAbsent(key, CacheableString::create("new-value")); + EXPECT_THAT(previous, NotNull()); + + auto converted = std::dynamic_pointer_cast(previous); + EXPECT_THAT(converted, NotNull()); + EXPECT_THAT(converted->toString(), Eq(value->toString())); + + // Verify cached value matches expected + auto entry = region->getEntry(key); + EXPECT_THAT(entry, NotNull()); + + auto retrieved = entry->getValue(); + EXPECT_THAT(converted, NotNull()); + + converted = std::dynamic_pointer_cast(retrieved); + EXPECT_THAT(converted, NotNull()); + EXPECT_THAT(converted->toString(), Eq(value->toString())); +} + +TEST(RegionPutTest, testPutIfAbsentWIthinTxAndOutOfTx) { + Cluster cluster{LocatorCount{1}, ServerCount{1}}; + + cluster.start(); + + cluster.getGfsh() + .create() + .region() + .withName("region") + .withType("REPLICATE") + .execute(); + + auto cache = createCache(); + auto pool = createPool(cluster, cache); + auto region = setupRegion(cache, pool); + auto key = CacheableKey::create("key-1"); + auto value = CacheableString::create("value"); + auto txMgr = cache.getCacheTransactionManager(); + + txMgr->begin(); + EXPECT_THAT(region->putIfAbsent(key, value), IsNull()); + + auto retrieved = region->get(key); + EXPECT_THAT(retrieved, NotNull()); + + auto converted = std::dynamic_pointer_cast(retrieved); + EXPECT_THAT(converted, NotNull()); + EXPECT_THAT(converted->toString(), Eq(value->toString())); + auto& txId = txMgr->suspend(); + + EXPECT_THAT(region->putIfAbsent(key, value), IsNull()); + + txMgr->resume(txId); + EXPECT_THROW(txMgr->commit(), CommitConflictException); +} + +TEST(RegionPutTest, testPutIfAbsentExistingEntryTX) { + Cluster cluster{LocatorCount{1}, ServerCount{1}}; + + cluster.start(); + + cluster.getGfsh() + .create() + .region() + .withName("region") + .withType("REPLICATE") + .execute(); + + auto cache = createCache(); + auto pool = createPool(cluster, cache); + auto region = setupRegion(cache, pool); + auto key = CacheableKey::create("key-1"); + EXPECT_NO_THROW(region->put(key, CacheableString::create("previous-value"))); + + auto value = std::dynamic_pointer_cast(region->get(key)); + + auto previous = + region->putIfAbsent(key, CacheableString::create("new-value")); + EXPECT_THAT(previous, NotNull()); + + auto converted = std::dynamic_pointer_cast(previous); + EXPECT_THAT(converted, NotNull()); + EXPECT_THAT(converted->toString(), Eq(value->toString())); +} + +} // namespace diff --git a/cppcache/src/AdminRegion.cpp b/cppcache/src/AdminRegion.cpp index 87b7963665..29c6e3fdad 100644 --- a/cppcache/src/AdminRegion.cpp +++ b/cppcache/src/AdminRegion.cpp @@ -23,6 +23,7 @@ #include "CacheImpl.hpp" #include "TcrConnectionManager.hpp" +#include "TcrMessagePut.hpp" #include "ThinClientCacheDistributionManager.hpp" #include "ThinClientPoolDM.hpp" #include "ThinClientRegion.hpp" @@ -76,8 +77,8 @@ GfErrType AdminRegion::putNoThrow(const std::shared_ptr& keyPtr, TcrMessagePut request( new DataOutput(m_connectionMgr->getCacheImpl()->createDataOutput()), - nullptr, keyPtr, valuePtr, nullptr, false, m_distMngr, true, false, - m_fullPath.c_str()); + nullptr, keyPtr, valuePtr, nullptr, EventOperation::UPDATE, false, + m_distMngr, true, false, m_fullPath.c_str()); request.setMetaRegion(true); TcrMessageReply reply(true, m_distMngr); reply.setMetaRegion(true); diff --git a/cppcache/src/CacheEventFlags.cpp b/cppcache/src/CacheEventFlags.cpp new file mode 100644 index 0000000000..b65e9af00e --- /dev/null +++ b/cppcache/src/CacheEventFlags.cpp @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CacheEventFlags.hpp" + +namespace apache { +namespace geode { +namespace client { + +const CacheEventFlags CacheEventFlags::NORMAL(CacheEventFlags::GF_NORMAL); +const CacheEventFlags CacheEventFlags::LOCAL(CacheEventFlags::GF_LOCAL); +const CacheEventFlags CacheEventFlags::NOTIFICATION( + CacheEventFlags::GF_NOTIFICATION); +const CacheEventFlags CacheEventFlags::NOTIFICATION_UPDATE( + CacheEventFlags::GF_NOTIFICATION_UPDATE); +const CacheEventFlags CacheEventFlags::EVICTION(CacheEventFlags::GF_EVICTION); +const CacheEventFlags CacheEventFlags::EXPIRATION( + CacheEventFlags::GF_EXPIRATION); +const CacheEventFlags CacheEventFlags::CACHE_CLOSE( + CacheEventFlags::GF_CACHE_CLOSE); +const CacheEventFlags CacheEventFlags::NOCACHEWRITER( + CacheEventFlags::GF_NOCACHEWRITER); +const CacheEventFlags CacheEventFlags::NOCALLBACKS( + CacheEventFlags::GF_NOCALLBACKS); + +} // namespace client +} // namespace geode +} // namespace apache diff --git a/cppcache/src/CacheEventFlags.hpp b/cppcache/src/CacheEventFlags.hpp new file mode 100644 index 0000000000..6d419bcc84 --- /dev/null +++ b/cppcache/src/CacheEventFlags.hpp @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef GEODE_CACHE_EVENT_FLAGS_H_ +#define GEODE_CACHE_EVENT_FLAGS_H_ + +#include + +namespace apache { +namespace geode { +namespace client { + + +/** + * @class CacheEventFlags + * + * This class encapsulates the flags (e.g. notification, expiration, local) + * for cache events for various NoThrow methods. + * + * + */ +class CacheEventFlags { + public: + static const CacheEventFlags NORMAL; + static const CacheEventFlags LOCAL; + static const CacheEventFlags NOTIFICATION; + static const CacheEventFlags NOTIFICATION_UPDATE; + static const CacheEventFlags EVICTION; + static const CacheEventFlags EXPIRATION; + static const CacheEventFlags CACHE_CLOSE; + static const CacheEventFlags NOCACHEWRITER; + static const CacheEventFlags NOCALLBACKS; + + CacheEventFlags(const CacheEventFlags& flags) = default; + + CacheEventFlags() = delete; + CacheEventFlags& operator=(const CacheEventFlags&) = delete; + + CacheEventFlags operator|(const CacheEventFlags& other) const { + return CacheEventFlags(flags_ | other.flags_); + } + + uint32_t operator&(const CacheEventFlags& other) const { + return (flags_ & other.flags_); + } + + bool operator==(const CacheEventFlags& other) const { + return (flags_ == other.flags_); + } + + bool isNormal() const { return flags_ & GF_NORMAL; } + + bool isLocal() const { return flags_ & GF_LOCAL; } + + bool isNotification() const { return flags_ & GF_NOTIFICATION; } + + bool isNotificationUpdate() const { return flags_ & GF_NOTIFICATION_UPDATE; } + + bool isEviction() const { return flags_ & GF_EVICTION; } + + bool isExpiration() const { return flags_ & GF_EXPIRATION; } + + bool isCacheClose() const { return flags_ & GF_CACHE_CLOSE; } + + bool isNoCacheWriter() const { return flags_ & GF_NOCACHEWRITER; } + + bool isNoCallbacks() const { return flags_ & GF_NOCALLBACKS; } + + bool isEvictOrExpire() const { + return flags_ & (GF_EVICTION | GF_EXPIRATION); + } + + // special optimized method for CacheWriter invocation condition + bool invokeCacheWriter() const { + return (flags_ & (GF_NOTIFICATION | GF_EVICTION | GF_EXPIRATION | + GF_NOCACHEWRITER | GF_NOCALLBACKS)) == 0; + } + + protected: + enum : uint16_t { + GF_NORMAL = 0x01, + GF_LOCAL = 0x02, + GF_NOTIFICATION = 0x04, + GF_NOTIFICATION_UPDATE = 0x08, + GF_EVICTION = 0x10, + GF_EXPIRATION = 0x20, + GF_CACHE_CLOSE = 0x40, + GF_NOCACHEWRITER = 0x80, + GF_NOCALLBACKS = 0x100 + }; + + protected: + explicit CacheEventFlags(int16_t flags) : flags_(flags) {} + + protected: + uint16_t flags_; +}; + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHE_EVENT_FLAGS_H_ diff --git a/cppcache/src/CreateAction.cpp b/cppcache/src/CreateAction.cpp new file mode 100644 index 0000000000..b61f9601bf --- /dev/null +++ b/cppcache/src/CreateAction.cpp @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CreateAction.hpp" + +#include "LocalRegion.hpp" +#include "TSSTXStateWrapper.hpp" +#include "Utils.hpp" +#include "VersionTag.hpp" + +namespace apache { +namespace geode { +namespace client { + +CreateAction::CreateAction(LocalRegion& region) + : region_{region}, txState_{TSSTXStateWrapper::get().getTXState()} {} + +void CreateAction::getCallbackOldValue(bool, + const std::shared_ptr&, + std::shared_ptr&, + std::shared_ptr&) const {} + +GfErrType CreateAction::remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr&, + std::shared_ptr& versionTag) { + return region_.remoteCreate(key, value, cbArg, versionTag); +} + +GfErrType CreateAction::localUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, + bool cachingEnabled, const CacheEventFlags, + int updateCount, + std::shared_ptr versionTag, + DataInput*, std::shared_ptr, + bool) { + return region_.putLocal(name(), true, key, value, oldValue, cachingEnabled, + updateCount, 0, versionTag); +} + +GfErrType CreateAction::checkArgs(const std::shared_ptr& key, + const std::shared_ptr&, + DataInput*) { + if (!key) { + return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; + } + + return GF_NOERR; +} + +void CreateAction::logCacheWriterFailure( + const std::shared_ptr& key, + const std::shared_ptr&) { + LOGFINER("Cache writer vetoed create for key %s", + Utils::nullSafeToString(key).c_str()); +} + +} // namespace client +} // namespace geode +} // namespace apache diff --git a/cppcache/src/CreateAction.hpp b/cppcache/src/CreateAction.hpp new file mode 100644 index 0000000000..ac0074d6b3 --- /dev/null +++ b/cppcache/src/CreateAction.hpp @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef GEODE_CREATE_ACTION_H_ +#define GEODE_CREATE_ACTION_H_ + +#include + +#include "CacheEventFlags.hpp" +#include "ErrType.hpp" +#include "EventType.hpp" + +namespace apache { +namespace geode { +namespace client { + +class CacheableKey; +class DataInput; +class EventId; +class LocalRegion; +class MapEntryImpl; +class Serializable; +class TXState; +class VersionTag; + +// encapsulates actions that need to be taken for a create() operation +class CreateAction { + public: + static const EntryEventType s_beforeEventType = BEFORE_CREATE; + static const EntryEventType s_afterEventType = AFTER_CREATE; + static const bool s_addIfAbsent = true; + static const bool s_failIfPresent = true; + + public: + explicit CreateAction(LocalRegion& region); + + void getCallbackOldValue(bool cachingEnabled, + const std::shared_ptr& key, + std::shared_ptr& entry, + std::shared_ptr& oldValue) const; + + GfErrType remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& retValue, + std::shared_ptr& versionTag); + + GfErrType localUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, + bool cachingEnabled, const CacheEventFlags eventFlags, + int updateCount, std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr, + bool afterRemote = false); + + TXState* getTxState() const { return txState_; } + + public: + static const char* name() { return "Region::create"; } + + static GfErrType checkArgs(const std::shared_ptr& key, + const std::shared_ptr& value, + DataInput* delta); + + static void logCacheWriterFailure( + const std::shared_ptr& key, + const std::shared_ptr& oldValue); + + protected: + LocalRegion& region_; + TXState* txState_; +}; + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CREATE_ACTION_H_ diff --git a/cppcache/src/DestroyAction.cpp b/cppcache/src/DestroyAction.cpp new file mode 100644 index 0000000000..d45c5810ea --- /dev/null +++ b/cppcache/src/DestroyAction.cpp @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DestroyAction.hpp" + +#include "CacheImpl.hpp" +#include "LocalRegion.hpp" +#include "TSSTXStateWrapper.hpp" +#include "Utils.hpp" +#include "VersionTag.hpp" + +namespace apache { +namespace geode { +namespace client { + +DestroyAction::DestroyAction(LocalRegion& region) + : region_{region}, txState_{TSSTXStateWrapper::get().getTXState()} {} + +void DestroyAction::getCallbackOldValue( + bool cachingEnabled, const std::shared_ptr& key, + std::shared_ptr& entry, + std::shared_ptr& oldValue) const { + if (cachingEnabled) { + region_.getEntryMap()->getEntry(key, entry, oldValue); + } +} + +GfErrType DestroyAction::remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr&, + const std::shared_ptr& cbArg, + std::shared_ptr&, + std::shared_ptr& versionTag) { + return region_.remoteDestroy(key, cbArg, versionTag); +} + +GfErrType DestroyAction::localUpdate( + const std::shared_ptr& key, const std::shared_ptr&, + std::shared_ptr& oldValue, bool cachingEnabled, + const CacheEventFlags eventFlags, int updateCount, + std::shared_ptr versionTag, DataInput*, + std::shared_ptr, bool afterRemote) { + auto& cachePerfStats = region_.getCacheImpl()->getCachePerfStats(); + + if (cachingEnabled) { + std::shared_ptr entry; + // for notification invoke the listener even if the key does + // not exist locally + GfErrType err; + LOGDEBUG("Region::destroy: region [%s] destroying key [%s]", + region_.getFullPath().c_str(), + Utils::nullSafeToString(key).c_str()); + if ((err = region_.getEntryMap()->remove(key, oldValue, entry, updateCount, + versionTag, afterRemote)) != + GF_NOERR) { + if (eventFlags.isNotification()) { + LOGDEBUG( + "Region::destroy: region [%s] destroy key [%s] for " + "notification having value [%s] failed with %d", + region_.getFullPath().c_str(), Utils::nullSafeToString(key).c_str(), + Utils::nullSafeToString(oldValue).c_str(), err); + err = GF_NOERR; + } + + return err; + } + + if (oldValue != nullptr) { + LOGDEBUG( + "Region::destroy: region [%s] destroyed key [%s] having " + "value [%s]", + region_.getFullPath().c_str(), Utils::nullSafeToString(key).c_str(), + Utils::nullSafeToString(oldValue).c_str()); + // any cleanup required for the entry (e.g. removing from LRU list) + if (entry != nullptr) { + entry->cleanup(eventFlags); + } + // entry/region expiration + if (!eventFlags.isEvictOrExpire()) { + region_.updateAccessAndModifiedTime(true); + } + // update the stats + region_.getRegionStats()->setEntries(region_.getEntryMap()->size()); + cachePerfStats.incEntries(-1); + } + } + + // update the stats + region_.getRegionStats()->incDestroys(); + cachePerfStats.incDestroys(); + return GF_NOERR; +} + +GfErrType DestroyAction::checkArgs(const std::shared_ptr& key, + const std::shared_ptr&, + DataInput*) { + if (!key) { + return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; + } + + return GF_NOERR; +} + +void DestroyAction::logCacheWriterFailure( + const std::shared_ptr& key, + const std::shared_ptr&) { + LOGFINER("Cache writer vetoed destroy for key %s", + Utils::nullSafeToString(key).c_str()); +} + +} // namespace client +} // namespace geode +} // namespace apache diff --git a/cppcache/src/DestroyAction.hpp b/cppcache/src/DestroyAction.hpp new file mode 100644 index 0000000000..f26d51b90a --- /dev/null +++ b/cppcache/src/DestroyAction.hpp @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef GEODE_DESTROY_ACTION_H_ +#define GEODE_DESTROY_ACTION_H_ + +#include + +#include "CacheEventFlags.hpp" +#include "ErrType.hpp" +#include "EventType.hpp" + +namespace apache { +namespace geode { +namespace client { + +class CacheableKey; +class DataInput; +class EventId; +class LocalRegion; +class MapEntryImpl; +class Serializable; +class TXState; +class VersionTag; + +// encapsulates actions that need to be taken for a destroy() operation +class DestroyAction { + public: + static const EntryEventType s_beforeEventType = BEFORE_DESTROY; + static const EntryEventType s_afterEventType = AFTER_DESTROY; + static const bool s_addIfAbsent = true; + static const bool s_failIfPresent = false; + + explicit DestroyAction(LocalRegion& region); + + void getCallbackOldValue(bool cachingEnabled, + const std::shared_ptr& key, + std::shared_ptr& entry, + std::shared_ptr& oldValue) const; + + GfErrType remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& retValue, + std::shared_ptr& versionTag); + + GfErrType localUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, + bool cachingEnabled, const CacheEventFlags eventFlags, + int updateCount, std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr, + bool afterRemote = false); + + TXState* getTxState() const { return txState_; } + + public: + static const char* name() { return "Region::destroy"; } + + static GfErrType checkArgs(const std::shared_ptr& key, + const std::shared_ptr& value, + DataInput* delta); + + static void logCacheWriterFailure(const std::shared_ptr& key, + const std::shared_ptr& oldValue); + + protected: + LocalRegion& region_; + TXState* txState_; +}; + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_DESTROY_ACTION_H_ diff --git a/cppcache/src/EventOperation.hpp b/cppcache/src/EventOperation.hpp new file mode 100644 index 0000000000..53e1fe0718 --- /dev/null +++ b/cppcache/src/EventOperation.hpp @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef GEODE_EVENT_OPERATION_H_ +#define GEODE_EVENT_OPERATION_H_ + +#include +#include +#include +#include +#include + +#include "TcrMessage.hpp" + +namespace apache { +namespace geode { +namespace client { + +enum class EventOperation { + MARKER = 0 /* 0 */, + CREATE /* 1 */, + PUTALL_CREATE /* 2 */, + GET /* 3 */, + GET_ENTRY /* 4 */, + CONTAINS_KEY /* 5 */, + CONTAINS_VALUE /* 6 */, + CONTAINS_VALUE_FOR_KEY /* 7 */, + FUNCTION_EXECUTION /* 8 */, + SEARCH_CREATE /* 9 */, + LOCAL_LOAD_CREATE /* 10 */, + NET_LOAD_CREATE /* 11 */, + UPDATE /* 12 */, + PUTALL_UPDATE /* 13 */, + SEARCH_UPDATE /* 14 */, + LOCAL_LOAD_UPDATE /* 15 */, + NET_LOAD_UPDATE /* 16 */, + INVALIDATE /* 17 */, + LOCAL_INVALIDATE /* 18 */, + DESTROY /* 19 */, + LOCAL_DESTROY /* 20 */, + EVICT_DESTROY /* 21 */, + REGION_LOAD_SNAPSHOT /* 22 */, + REGION_LOAD_DESTROY /* 23 */, + REGION_CREATE /* 24 */, + REGION_CLOSE /* 25 */, + REGION_DESTROY /* 26 */, + EXPIRE_DESTROY /* 27 */, + EXPIRE_LOCAL_DESTROY /* 28 */, + EXPIRE_INVALIDATE /* 29 */, + EXPIRE_LOCAL_INVALIDATE /* 30 */, + REGION_EXPIRE_DESTROY /* 31 */, + REGION_EXPIRE_LOCAL_DESTROY /* 32 */, + REGION_EXPIRE_INVALIDATE /* 33 */, + REGION_EXPIRE_LOCAL_INVALIDATE /* 34 */, + REGION_LOCAL_INVALIDATE /* 35 */, + REGION_INVALIDATE /* 36 */, + REGION_CLEAR /* 37 */, + REGION_LOCAL_CLEAR /* 38 */, + CACHE_CREATE /* 39 */, + CACHE_CLOSE /* 40 */, + FORCED_DISCONNECT /* 41 */, + REGION_REINITIALIZE /* 42 */, + CACHE_RECONNECT /* 43 */, + PUT_IF_ABSENT /* 44 */, + REPLACE /* 45 */, + REMOVE /* 46 */, + UPDATE_VERSION_STAMP /* 47 */, + REMOVEALL_DESTROY /* 48 */, + GET_FOR_REGISTER_INTEREST /* 49 */ +}; + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_EVENT_OPERATION_H_ diff --git a/cppcache/src/InvalidateAction.cpp b/cppcache/src/InvalidateAction.cpp new file mode 100644 index 0000000000..cd3f1bf152 --- /dev/null +++ b/cppcache/src/InvalidateAction.cpp @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "InvalidateAction.hpp" + +#include "LocalRegion.hpp" +#include "TSSTXStateWrapper.hpp" +#include "Utils.hpp" +#include "VersionTag.hpp" + +namespace apache { +namespace geode { +namespace client { + +InvalidateAction::InvalidateAction(LocalRegion& region) + : region_{region}, txState_{TSSTXStateWrapper::get().getTXState()} {} + +void InvalidateAction::getCallbackOldValue( + bool cachingEnabled, const std::shared_ptr& key, + std::shared_ptr& entry, + std::shared_ptr& oldValue) const { + if (cachingEnabled) { + region_.getEntryMap()->getEntry(key, entry, oldValue); + } +} + +GfErrType InvalidateAction::remoteUpdate( + const std::shared_ptr& key, + const std::shared_ptr&, + const std::shared_ptr& cbArg, std::shared_ptr&, + std::shared_ptr& versionTag) { + // propagate the invalidate to remote server, if any + return region_.remoteInvalidate(key, cbArg, versionTag); +} + +GfErrType InvalidateAction::localUpdate( + const std::shared_ptr& key, + const std::shared_ptr& value, std::shared_ptr&, + bool, const CacheEventFlags eventFlags, int, + std::shared_ptr versionTag, DataInput*, + std::shared_ptr, bool) { + return region_.invalidateLocal(name(), key, value, eventFlags, versionTag); +} + +GfErrType InvalidateAction::checkArgs(const std::shared_ptr& key, + const std::shared_ptr&, + DataInput*) { + if (key == nullptr) { + return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; + } + return GF_NOERR; +} + +void InvalidateAction::logCacheWriterFailure( + const std::shared_ptr& key, + const std::shared_ptr& oldValue) { + bool isUpdate = (oldValue != nullptr); + LOGFINER("Cache writer vetoed %s for key %s", + (isUpdate ? "update" : "invalidate"), + Utils::nullSafeToString(key).c_str()); +} + +} // namespace client +} // namespace geode +} // namespace apache diff --git a/cppcache/src/InvalidateAction.hpp b/cppcache/src/InvalidateAction.hpp new file mode 100644 index 0000000000..55651c02ba --- /dev/null +++ b/cppcache/src/InvalidateAction.hpp @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef GEODE_INVALIDATE_ACTION_H_ +#define GEODE_INVALIDATE_ACTION_H_ + +#include + +#include "CacheEventFlags.hpp" +#include "ErrType.hpp" +#include "EventType.hpp" + +namespace apache { +namespace geode { +namespace client { + +class CacheableKey; +class DataInput; +class EventId; +class LocalRegion; +class MapEntryImpl; +class Serializable; +class TXState; +class VersionTag; + +// encapsulates actions that need to be taken for a invalidate() operation +class InvalidateAction { + public: + static const EntryEventType s_beforeEventType = BEFORE_INVALIDATE; + static const EntryEventType s_afterEventType = AFTER_INVALIDATE; + static const bool s_addIfAbsent = true; + static const bool s_failIfPresent = false; + + public: + explicit InvalidateAction(LocalRegion& region); + + void getCallbackOldValue(bool cachingEnabled, + const std::shared_ptr& key, + std::shared_ptr& entry, + std::shared_ptr& oldValue) const; + + GfErrType remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& retValue, + std::shared_ptr& versionTag); + + GfErrType localUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, + bool cachingEnabled, const CacheEventFlags eventFlags, + int updateCount, std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr, + bool afterRemote = false); + + TXState* getTxState() const { return txState_; } + + public: + static const char* name() { return "Region::invalidate"; } + + static GfErrType checkArgs(const std::shared_ptr& key, + const std::shared_ptr& value, + DataInput* delta = nullptr); + + static void logCacheWriterFailure(const std::shared_ptr& key, + const std::shared_ptr& oldValue); + + protected: + LocalRegion& region_; + TXState* txState_; +}; + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_INVALIDATE_ACTION_H_ diff --git a/cppcache/src/LocalRegion.cpp b/cppcache/src/LocalRegion.cpp index 38c2096420..9d5da8a889 100644 --- a/cppcache/src/LocalRegion.cpp +++ b/cppcache/src/LocalRegion.cpp @@ -29,13 +29,18 @@ #include "CacheImpl.hpp" #include "CacheRegionHelper.hpp" #include "CacheableToken.hpp" +#include "CreateAction.hpp" +#include "DestroyAction.hpp" #include "EntriesMapFactory.hpp" #include "EntryExpiryTask.hpp" #include "ExpiryTaskManager.hpp" #include "InterestResultPolicy.hpp" +#include "InvalidateAction.hpp" #include "LRUEntriesMap.hpp" +#include "PutAction.hpp" #include "RegionExpiryTask.hpp" #include "RegionGlobalLocks.hpp" +#include "RemoveAction.hpp" #include "SerializableHelper.hpp" #include "TXState.hpp" #include "TcrConnectionManager.hpp" @@ -317,7 +322,7 @@ std::shared_ptr LocalRegion::getEntry( GF_NOTSUP); } std::shared_ptr rptr; - std::shared_ptr valuePtr; + std::shared_ptr valuePtr; getEntry(key, valuePtr); if (valuePtr != nullptr) { rptr = createRegionEntry(key, valuePtr); @@ -326,7 +331,7 @@ std::shared_ptr LocalRegion::getEntry( } void LocalRegion::getEntry(const std::shared_ptr& key, - std::shared_ptr& valuePtr) { + std::shared_ptr& valuePtr) { if (key == nullptr) { throw IllegalArgumentException("LocalRegion::getEntry: null key"); } @@ -337,10 +342,10 @@ void LocalRegion::getEntry(const std::shared_ptr& key, m_entries->getEntry(key, mePtr, valuePtr); } } -std::shared_ptr LocalRegion::get( +std::shared_ptr LocalRegion::get( const std::shared_ptr& key, const std::shared_ptr& aCallbackArgument) { - std::shared_ptr rptr; + std::shared_ptr rptr; int64_t sampleStartNanos = startStatOpTime(); GfErrType err = getNoThrow(key, rptr, aCallbackArgument); updateStatOpTime(m_regionStats->getStat(), m_regionStats->getGetTimeId(), @@ -354,9 +359,9 @@ std::shared_ptr LocalRegion::get( } void LocalRegion::put(const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument) { - std::shared_ptr oldValue; + std::shared_ptr oldValue; int64_t sampleStartNanos = startStatOpTime(); std::shared_ptr versionTag; GfErrType err = putNoThrow(key, value, aCallbackArgument, oldValue, -1, @@ -367,11 +372,27 @@ void LocalRegion::put(const std::shared_ptr& key, throwExceptionIfError("Region::put", err); } +std::shared_ptr LocalRegion::putIfAbsent( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg) { + auto opTime = startStatOpTime(); + std::shared_ptr retValue; + std::shared_ptr versionTag; + GfErrType err = putIfAbsentImpl(key, value, cbArg, retValue, -1, + CacheEventFlags::NORMAL, versionTag); + + updateStatOpTime(m_regionStats->getStat(), m_regionStats->getPutTimeId(), + opTime); + throwExceptionIfError("Region::putIfAbsent", err); + return retValue; +} + void LocalRegion::localPut( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument) { - std::shared_ptr oldValue; + std::shared_ptr oldValue; std::shared_ptr versionTag; GfErrType err = putNoThrow(key, value, aCallbackArgument, oldValue, -1, CacheEventFlags::LOCAL, versionTag); @@ -406,7 +427,7 @@ void LocalRegion::removeAll( void LocalRegion::create( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument) { std::shared_ptr versionTag; GfErrType err = createNoThrow(key, value, aCallbackArgument, -1, @@ -417,7 +438,7 @@ void LocalRegion::create( void LocalRegion::localCreate( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument) { std::shared_ptr versionTag; GfErrType err = createNoThrow(key, value, aCallbackArgument, -1, @@ -473,7 +494,7 @@ void LocalRegion::localDestroy( bool LocalRegion::remove( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument) { std::shared_ptr versionTag; GfErrType err = removeNoThrow(key, value, aCallbackArgument, -1, @@ -509,7 +530,7 @@ bool LocalRegion::removeEx( bool LocalRegion::localRemove( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument) { std::shared_ptr versionTag; GfErrType err = removeNoThrow(key, value, aCallbackArgument, -1, @@ -554,10 +575,10 @@ std::vector> LocalRegion::serverKeys() { "serverKeys is not supported for local regions."); } -std::vector> LocalRegion::values() { +std::vector> LocalRegion::values() { CHECK_DESTROY_PENDING(shared_lock, LocalRegion::values); - std::vector> values; + std::vector> values; if (m_regionAttributes.getCachingEnabled()) { // invalidToken should not be added by the MapSegments. @@ -643,7 +664,7 @@ bool LocalRegion::containsValueForKey_remote( if (!m_regionAttributes.getCachingEnabled()) { return false; } - std::shared_ptr valuePtr; + std::shared_ptr valuePtr; std::shared_ptr mePtr; m_entries->getEntry(keyPtr, mePtr, valuePtr); if (mePtr == nullptr) { @@ -850,7 +871,7 @@ std::vector> LocalRegion::subregions_internal( GfErrType LocalRegion::getNoThrow( const std::shared_ptr& keyPtr, - std::shared_ptr& value, + std::shared_ptr& value, const std::shared_ptr& aCallbackArgument) { CHECK_DESTROY_PENDING_NOTHROW(shared_lock); GfErrType err = GF_NOERR; @@ -887,7 +908,7 @@ GfErrType LocalRegion::getNoThrow( bool isLoaderInvoked = false; bool isLocal = false; bool cachingEnabled = m_regionAttributes.getCachingEnabled(); - std::shared_ptr localValue = nullptr; + std::shared_ptr localValue = nullptr; if (cachingEnabled) { isLocal = m_entries->get(keyPtr, value, me); if (isLocal && (value != nullptr && !CacheableToken::isInvalid(value))) { @@ -967,7 +988,7 @@ GfErrType LocalRegion::getNoThrow( } } - std::shared_ptr oldValue; + std::shared_ptr oldValue; // Found it somehow, so store it. if (value != nullptr /*&& value != CacheableToken::invalid( )*/ && cachingEnabled && @@ -1033,7 +1054,7 @@ GfErrType LocalRegion::getAllNoThrow( const std::shared_ptr& aCallbackArgument) { CHECK_DESTROY_PENDING_NOTHROW(shared_lock); GfErrType err = GF_NOERR; - std::shared_ptr value; + std::shared_ptr value; TXState* txState = getTXState(); if (txState != nullptr) { @@ -1092,572 +1113,32 @@ GfErrType LocalRegion::getAllNoThrow( return err; } -// encapsulates actions that need to be taken for a put() operation -class PutActions { - public: - static const EntryEventType s_beforeEventType = BEFORE_UPDATE; - static const EntryEventType s_afterEventType = AFTER_UPDATE; - static const bool s_addIfAbsent = true; - static const bool s_failIfPresent = false; - TXState* m_txState; - - inline explicit PutActions(LocalRegion& region) : m_region(region) { - m_txState = TSSTXStateWrapper::get().getTXState(); - } - - inline static const char* name() { return "Region::put"; } - - inline static GfErrType checkArgs(const std::shared_ptr& key, - const std::shared_ptr& value, - DataInput* delta = nullptr) { - if (key == nullptr || (value == nullptr && delta == nullptr)) { - return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; - } - return GF_NOERR; - } - - inline void getCallbackOldValue(bool cachingEnabled, - const std::shared_ptr& key, - std::shared_ptr& entry, - std::shared_ptr& oldValue) const { - if (cachingEnabled) { - m_region.m_entries->getEntry(key, entry, oldValue); - } - } - - inline static void logCacheWriterFailure( - const std::shared_ptr& key, - const std::shared_ptr& oldValue) { - bool isUpdate = (oldValue != nullptr); - LOGFINER("Cache writer vetoed %s for key %s", - (isUpdate ? "update" : "create"), - Utils::nullSafeToString(key).c_str()); - } - - inline GfErrType remoteUpdate( - const std::shared_ptr& key, - const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { - // propagate the put to remote server, if any - return m_region.putNoThrow_remote(key, value, aCallbackArgument, - versionTag); - } - - inline GfErrType localUpdate(const std::shared_ptr& key, - const std::shared_ptr& value, - std::shared_ptr& oldValue, - bool cachingEnabled, - const CacheEventFlags /*eventFlags*/, - int updateCount, - std::shared_ptr versionTag, - DataInput* delta = nullptr, - std::shared_ptr eventId = nullptr, - bool /*afterRemote*/ = false) { - return m_region.putLocal(name(), false, key, value, oldValue, - cachingEnabled, updateCount, 0, versionTag, delta, - eventId); - } - - private: - LocalRegion& m_region; -}; - -// encapsulates actions that need to be taken for a put() operation. This -// implementation allows -// null values in Put during transaction. See defect #743 -class PutActionsTx : public PutActions { - public: - inline explicit PutActionsTx(LocalRegion& region) : PutActions(region) {} - inline static GfErrType checkArgs(const std::shared_ptr& key, - const std::shared_ptr& /*value*/, - DataInput* /*delta*/ = nullptr) { - if (key == nullptr) { - return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; - } - return GF_NOERR; - } -}; - -// encapsulates actions that need to be taken for a create() operation -class CreateActions { - public: - static const EntryEventType s_beforeEventType = BEFORE_CREATE; - static const EntryEventType s_afterEventType = AFTER_CREATE; - static const bool s_addIfAbsent = true; - static const bool s_failIfPresent = true; - TXState* m_txState; - - inline explicit CreateActions(LocalRegion& region) : m_region(region) { - m_txState = TSSTXStateWrapper::get().getTXState(); - } - - inline static const char* name() { return "Region::create"; } - - inline static GfErrType checkArgs(const std::shared_ptr& key, - const std::shared_ptr& /*value*/, - DataInput* /*delta*/) { - if (key == nullptr) { - return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; - } - return GF_NOERR; - } - - inline void getCallbackOldValue( - bool /*cachingEnabled*/, const std::shared_ptr& /*key*/, - std::shared_ptr& /*entry*/, - std::shared_ptr& /*oldValue*/) const {} - - inline static void logCacheWriterFailure( - const std::shared_ptr& key, - const std::shared_ptr& /*oldValue*/) { - LOGFINER("Cache writer vetoed create for key %s", - Utils::nullSafeToString(key).c_str()); - } - - inline GfErrType remoteUpdate( - const std::shared_ptr& key, - const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { - return m_region.createNoThrow_remote(key, value, aCallbackArgument, - versionTag); - } - - inline GfErrType localUpdate(const std::shared_ptr& key, - const std::shared_ptr& value, - std::shared_ptr& oldValue, - bool cachingEnabled, - const CacheEventFlags /*eventFlags*/, - int updateCount, - std::shared_ptr versionTag, - DataInput* /*delta*/ = nullptr, - std::shared_ptr /*eventId*/ = nullptr, - bool /*afterRemote*/ = false) { - return m_region.putLocal(name(), true, key, value, oldValue, cachingEnabled, - updateCount, 0, versionTag); - } - - private: - LocalRegion& m_region; -}; - -// encapsulates actions that need to be taken for a destroy() operation -class DestroyActions { - public: - static const EntryEventType s_beforeEventType = BEFORE_DESTROY; - static const EntryEventType s_afterEventType = AFTER_DESTROY; - static const bool s_addIfAbsent = true; - static const bool s_failIfPresent = false; - TXState* m_txState; - - inline explicit DestroyActions(LocalRegion& region) : m_region(region) { - m_txState = TSSTXStateWrapper::get().getTXState(); - } - - inline static const char* name() { return "Region::destroy"; } - - inline static GfErrType checkArgs(const std::shared_ptr& key, - const std::shared_ptr& /*value*/, - DataInput* /*delta*/) { - if (key == nullptr) { - return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; - } - return GF_NOERR; - } - - inline void getCallbackOldValue(bool cachingEnabled, - const std::shared_ptr& key, - std::shared_ptr& entry, - std::shared_ptr& oldValue) const { - if (cachingEnabled) { - m_region.m_entries->getEntry(key, entry, oldValue); - } - } - - inline static void logCacheWriterFailure( - const std::shared_ptr& key, - const std::shared_ptr& /*oldValue*/) { - LOGFINER("Cache writer vetoed destroy for key %s", - Utils::nullSafeToString(key).c_str()); - } - - inline GfErrType remoteUpdate( - const std::shared_ptr& key, - const std::shared_ptr& /*value*/, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { - return m_region.destroyNoThrow_remote(key, aCallbackArgument, versionTag); - } - - inline GfErrType localUpdate(const std::shared_ptr& key, - const std::shared_ptr& /*value*/, - std::shared_ptr& oldValue, - bool cachingEnabled, - const CacheEventFlags eventFlags, - int updateCount, - std::shared_ptr versionTag, - DataInput* /*delta*/ = nullptr, - std::shared_ptr /*eventId*/ = nullptr, - bool afterRemote = false) { - auto& cachePerfStats = m_region.m_cacheImpl->getCachePerfStats(); - - if (cachingEnabled) { - std::shared_ptr entry; - // for notification invoke the listener even if the key does - // not exist locally - GfErrType err; - LOGDEBUG("Region::destroy: region [%s] destroying key [%s]", - m_region.getFullPath().c_str(), - Utils::nullSafeToString(key).c_str()); - if ((err = m_region.m_entries->remove(key, oldValue, entry, updateCount, - versionTag, afterRemote)) != - GF_NOERR) { - if (eventFlags.isNotification()) { - LOGDEBUG( - "Region::destroy: region [%s] destroy key [%s] for " - "notification having value [%s] failed with %d", - m_region.getFullPath().c_str(), - Utils::nullSafeToString(key).c_str(), - Utils::nullSafeToString(oldValue).c_str(), err); - err = GF_NOERR; - } - return err; - } - - if (oldValue != nullptr) { - LOGDEBUG( - "Region::destroy: region [%s] destroyed key [%s] having " - "value [%s]", - m_region.getFullPath().c_str(), - Utils::nullSafeToString(key).c_str(), - Utils::nullSafeToString(oldValue).c_str()); - // any cleanup required for the entry (e.g. removing from LRU list) - if (entry != nullptr) { - entry->cleanup(eventFlags); - } - // entry/region expiration - if (!eventFlags.isEvictOrExpire()) { - m_region.updateAccessAndModifiedTime(true); - } - // update the stats - m_region.m_regionStats->setEntries(m_region.m_entries->size()); - cachePerfStats.incEntries(-1); - } - } - // update the stats - m_region.m_regionStats->incDestroys(); - cachePerfStats.incDestroys(); - return GF_NOERR; - } - - private: - LocalRegion& m_region; -}; - -// encapsulates actions that need to be taken for a remove() operation -class RemoveActions { - public: - static const EntryEventType s_beforeEventType = BEFORE_DESTROY; - static const EntryEventType s_afterEventType = AFTER_DESTROY; - static const bool s_addIfAbsent = true; - static const bool s_failIfPresent = false; - TXState* m_txState; - bool allowNULLValue; - - inline explicit RemoveActions(LocalRegion& region) - : m_region(region), m_ServerResponse(GF_ENOENT) { - m_txState = TSSTXStateWrapper::get().getTXState(); - allowNULLValue = false; - } - - inline static const char* name() { return "Region::remove"; } - - inline static GfErrType checkArgs(const std::shared_ptr& key, - const std::shared_ptr& /*value*/, - DataInput* /*delta*/) { - if (key == nullptr) { - return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; - } - return GF_NOERR; - } - - inline void getCallbackOldValue(bool cachingEnabled, - const std::shared_ptr& key, - std::shared_ptr& entry, - std::shared_ptr& oldValue) const { - if (cachingEnabled) { - m_region.m_entries->getEntry(key, entry, oldValue); - } - } - - inline static void logCacheWriterFailure( - const std::shared_ptr& key, - const std::shared_ptr& /*oldValue*/) { - LOGFINER("Cache writer vetoed remove for key %s", - Utils::nullSafeToString(key).c_str()); - } - - bool serializedEqualTo(const std::shared_ptr& lhs, - const std::shared_ptr& rhs) { - auto&& cache = *(m_region.getCacheImpl()); - - if (const auto dataSerializablePrimitive = - std::dynamic_pointer_cast(lhs)) { - return SerializableHelper{}.equalTo( - cache, dataSerializablePrimitive, - std::dynamic_pointer_cast(rhs)); - } else if (const auto dataSerializable = - std::dynamic_pointer_cast(lhs)) { - return SerializableHelper{}.equalTo( - cache, dataSerializable, - std::dynamic_pointer_cast(rhs)); - } else if (const auto pdxSerializable = - std::dynamic_pointer_cast(lhs)) { - return SerializableHelper{}.equalTo( - cache, pdxSerializable, - std::dynamic_pointer_cast(rhs)); - } else if (const auto dataSerializableInternal = - std::dynamic_pointer_cast(lhs)) { - return SerializableHelper{}.equalTo( - cache, dataSerializableInternal, - std::dynamic_pointer_cast(rhs)); - } else { - throw UnsupportedOperationException( - "Serialization type not implemented."); - } - } - - inline GfErrType remoteUpdate( - const std::shared_ptr& key, - const std::shared_ptr& newValue, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { - // propagate the remove to remote server, if any - std::shared_ptr oldValue; - GfErrType err = GF_NOERR; - if (!allowNULLValue && m_region.getAttributes().getCachingEnabled()) { - m_region.getEntry(key, oldValue); - if (oldValue != nullptr && newValue != nullptr) { - if (!serializedEqualTo(oldValue, newValue)) { - err = GF_ENOENT; - return err; - } - } else if ((oldValue == nullptr || CacheableToken::isInvalid(oldValue))) { - m_ServerResponse = m_region.removeNoThrow_remote( - key, newValue, aCallbackArgument, versionTag); - - return m_ServerResponse; - } else if (oldValue != nullptr && newValue == nullptr) { - err = GF_ENOENT; - return err; - } - } - if (allowNULLValue) { - m_ServerResponse = - m_region.removeNoThrowEX_remote(key, aCallbackArgument, versionTag); - } else { - m_ServerResponse = m_region.removeNoThrow_remote( - key, newValue, aCallbackArgument, versionTag); - } - LOGDEBUG("serverResponse::%d", m_ServerResponse); - return m_ServerResponse; - } - - inline GfErrType localUpdate(const std::shared_ptr& key, - const std::shared_ptr& value, - std::shared_ptr& oldValue, - bool cachingEnabled, - const CacheEventFlags eventFlags, - int updateCount, - std::shared_ptr versionTag, - DataInput* /*delta*/ = nullptr, - std::shared_ptr /*eventId*/ = nullptr, - bool afterRemote = false) { - std::shared_ptr valuePtr; - GfErrType err = GF_NOERR; - if (!allowNULLValue && cachingEnabled) { - m_region.getEntry(key, valuePtr); - if (valuePtr != nullptr && value != nullptr) { - if (!serializedEqualTo(valuePtr, value)) { - err = GF_ENOENT; - return err; - } - } else if (value == nullptr && (!CacheableToken::isInvalid(valuePtr) || - valuePtr == nullptr)) { - err = (m_ServerResponse == 0 && valuePtr == nullptr) ? GF_NOERR - : GF_ENOENT; - if (updateCount >= 0 && - !m_region.getAttributes().getConcurrencyChecksEnabled()) { - // This means server has deleted an entry & same entry has been - // destroyed locally - // So call removeTrackerForEntry to remove key that - // was added in the map during addTrackerForEntry call. - m_region.m_entries->removeTrackerForEntry(key); - } - return err; - } else if (valuePtr == nullptr && value != nullptr && - m_ServerResponse != 0) { - err = GF_ENOENT; - return err; - } - } - auto& cachePerfStats = m_region.m_cacheImpl->getCachePerfStats(); - - if (cachingEnabled) { - std::shared_ptr entry; - // for notification invoke the listener even if the key does - // not exist locally - LOGDEBUG("Region::remove: region [%s] removing key [%s]", - m_region.getFullPath().c_str(), - Utils::nullSafeToString(key).c_str()); - if ((err = m_region.m_entries->remove(key, oldValue, entry, updateCount, - versionTag, afterRemote)) != - GF_NOERR) { - if (eventFlags.isNotification()) { - LOGDEBUG( - "Region::remove: region [%s] remove key [%s] for " - "notification having value [%s] failed with %d", - m_region.getFullPath().c_str(), - Utils::nullSafeToString(key).c_str(), - Utils::nullSafeToString(oldValue).c_str(), err); - err = GF_NOERR; - } - return err; - } - if (oldValue != nullptr) { - LOGDEBUG( - "Region::remove: region [%s] removed key [%s] having " - "value [%s]", - m_region.getFullPath().c_str(), - Utils::nullSafeToString(key).c_str(), - Utils::nullSafeToString(oldValue).c_str()); - // any cleanup required for the entry (e.g. removing from LRU list) - if (entry != nullptr) { - entry->cleanup(eventFlags); - } - // entry/region expiration - if (!eventFlags.isEvictOrExpire()) { - m_region.updateAccessAndModifiedTime(true); - } - // update the stats - m_region.m_regionStats->setEntries(m_region.m_entries->size()); - cachePerfStats.incEntries(-1); - } - } - // update the stats - m_region.m_regionStats->incDestroys(); - cachePerfStats.incDestroys(); - return GF_NOERR; - } - - private: - LocalRegion& m_region; - GfErrType m_ServerResponse; -}; - -class RemoveActionsEx : public RemoveActions { - public: - inline explicit RemoveActionsEx(LocalRegion& region) : RemoveActions(region) { - allowNULLValue = true; - } -}; - -// encapsulates actions that need to be taken for a invalidate() operation -class InvalidateActions { - public: - static const EntryEventType s_beforeEventType = BEFORE_INVALIDATE; - static const EntryEventType s_afterEventType = AFTER_INVALIDATE; - static const bool s_addIfAbsent = true; - static const bool s_failIfPresent = false; - TXState* m_txState; - - inline explicit InvalidateActions(LocalRegion& region) : m_region(region) { - m_txState = TSSTXStateWrapper::get().getTXState(); - } - - inline static const char* name() { return "Region::invalidate"; } - - inline static GfErrType checkArgs(const std::shared_ptr& key, - const std::shared_ptr& /*value*/, - DataInput* /*delta*/ = nullptr) { - if (key == nullptr) { - return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; - } - return GF_NOERR; - } - - inline void getCallbackOldValue(bool cachingEnabled, - const std::shared_ptr& key, - std::shared_ptr& entry, - std::shared_ptr& oldValue) const { - if (cachingEnabled) { - m_region.m_entries->getEntry(key, entry, oldValue); - } - } - - inline static void logCacheWriterFailure( - const std::shared_ptr& key, - const std::shared_ptr& oldValue) { - bool isUpdate = (oldValue != nullptr); - LOGFINER("Cache writer vetoed %s for key %s", - (isUpdate ? "update" : "invalidate"), - Utils::nullSafeToString(key).c_str()); - } - - inline GfErrType remoteUpdate( - const std::shared_ptr& key, - const std::shared_ptr& /*value*/, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { - // propagate the invalidate to remote server, if any - return m_region.invalidateNoThrow_remote(key, aCallbackArgument, - versionTag); - } - - inline GfErrType localUpdate(const std::shared_ptr& key, - const std::shared_ptr& value, - std::shared_ptr& /*oldValue*/, - bool /*cachingEnabled*/, - const CacheEventFlags eventFlags, - int /*updateCount*/, - std::shared_ptr versionTag, - DataInput* /*delta*/ = nullptr, - std::shared_ptr /*eventId*/ = nullptr, - bool /*afterRemote*/ = false) { - return m_region.invalidateLocal(name(), key, value, eventFlags, versionTag); - } - - private: - LocalRegion& m_region; -}; - -template -GfErrType LocalRegion::updateNoThrow( - const std::shared_ptr& key, - const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& oldValue, int updateCount, - const CacheEventFlags eventFlags, std::shared_ptr versionTag, - DataInput* delta, std::shared_ptr eventId) { +template +GfErrType LocalRegion::update(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& retValue, + std::shared_ptr& oldValue, + int updateCount, const CacheEventFlags eventFlags, + std::shared_ptr versionTag, + DataInput* delta, + std::shared_ptr eventId) noexcept { GfErrType err = GF_NOERR; - if ((err = TAction::checkArgs(key, value, delta)) != GF_NOERR) { + if ((err = Action_::checkArgs(key, value, delta)) != GF_NOERR) { return err; } CHECK_DESTROY_PENDING_NOTHROW(shared_lock); - TAction action(*this); - TXState* txState = action.m_txState; + Action_ action{*this}; + + auto txState = action.getTxState(); if (txState != nullptr) { if (isLocalOp(&eventFlags)) { return GF_NOTSUP; } - /* adongre - Coverity II - * CID 29194 (6): Parse warning (PW.PARAMETER_HIDDEN) - */ - // std::shared_ptr versionTag; - err = action.remoteUpdate(key, value, aCallbackArgument, versionTag); + + err = action.remoteUpdate(key, value, cbArg, retValue, versionTag); if (err == GF_NOERR) { txState->setDirty(); } @@ -1665,8 +1146,8 @@ GfErrType LocalRegion::updateNoThrow( return err; } - bool cachingEnabled = m_regionAttributes.getCachingEnabled(); std::shared_ptr entry; + bool cachingEnabled = m_regionAttributes.getCachingEnabled(); // do not invoke the writer in case of notification/eviction // or expiration @@ -1675,13 +1156,13 @@ GfErrType LocalRegion::updateNoThrow( // invokeCacheWriterForEntryEvent method has the check that if oldValue // is a CacheableToken then it sets it to nullptr; also determines if it // should be BEFORE_UPDATE or BEFORE_CREATE depending on oldValue - if (!invokeCacheWriterForEntryEvent(key, oldValue, value, aCallbackArgument, - eventFlags, - TAction::s_beforeEventType)) { - TAction::logCacheWriterFailure(key, oldValue); + if (!invokeCacheWriterForEntryEvent(key, oldValue, value, cbArg, eventFlags, + Action_::s_beforeEventType)) { + Action_::logCacheWriterFailure(key, oldValue); return GF_CACHEWRITER_ERROR; } } + bool remoteOpDone = false; // try the remote update; but if this fails (e.g. due to security // exception) do not do the local update @@ -1694,7 +1175,7 @@ GfErrType LocalRegion::updateNoThrow( !m_regionAttributes.getConcurrencyChecksEnabled()) { // add a tracking for the entry if ((updateCount = m_entries->addTrackerForEntry( - key, oldValue, TAction::s_addIfAbsent, TAction::s_failIfPresent, + key, oldValue, Action_::s_addIfAbsent, Action_::s_failIfPresent, true)) < 0) { if (oldValue != nullptr) { // fail for "create" when entry exists @@ -1702,44 +1183,49 @@ GfErrType LocalRegion::updateNoThrow( } } } + // propagate the update to remote server, if any - err = action.remoteUpdate(key, value, aCallbackArgument, versionTag); + err = action.remoteUpdate(key, value, cbArg, retValue, versionTag); if (err != GF_NOERR) { if (updateCount >= 0 && !m_regionAttributes.getConcurrencyChecksEnabled()) { m_entries->removeTrackerForEntry(key); } + return err; } + remoteOpDone = true; } + if (!eventFlags.isNotification() || getProcessedMarker()) { - if ((err = action.localUpdate(key, value, oldValue, cachingEnabled, - eventFlags, updateCount, versionTag, delta, - eventId, remoteOpDone)) == - GF_CACHE_ENTRY_UPDATED) { + err = action.localUpdate(key, value, oldValue, cachingEnabled, eventFlags, + updateCount, versionTag, delta, eventId, + remoteOpDone); + + if (err == GF_CACHE_ENTRY_UPDATED) { LOGFINEST( "%s: did not change local value for key [%s] since it has " "been updated by another thread while operation was in progress", - TAction::name(), Utils::nullSafeToString(key).c_str()); + Action_::name(), Utils::nullSafeToString(key).c_str()); err = GF_NOERR; } else if (err == GF_CACHE_CONCURRENT_MODIFICATION_EXCEPTION) { LOGDEBUG( - "Region::localUpdate: updateNoThrow<%s> for key [%s] failed because the cache already contains \ - an entry with higher version. The cache listener will not be invoked.", - TAction::name(), Utils::nullSafeToString(key).c_str()); + "Region::localUpdate: update<%s> for key [%s] failed because the " + "cache already contains an entry with higher version. The cache " + "listener will not be invoked.", + Action_::name(), Utils::nullSafeToString(key).c_str()); // Cache listener won't be called in this case return GF_NOERR; } else if (err == GF_INVALID_DELTA) { LOGDEBUG( - "Region::localUpdate: updateNoThrow<%s> for key [%s] failed " - "because " - "of invalid delta.", - TAction::name(), Utils::nullSafeToString(key).c_str()); + "Region::localUpdate: update<%s> for key [%s] failed " + "because of invalid delta.", + Action_::name(), Utils::nullSafeToString(key).c_str()); m_cacheImpl->getCachePerfStats().incFailureOnDeltaReceived(); // Get full object from server. - std::shared_ptr& newValue1 = - const_cast&>(value); + std::shared_ptr& newValue1 = + const_cast&>(value); std::shared_ptr versionTag1; err = getNoThrow_FullObject(eventId, newValue1, versionTag1); if (err == GF_NOERR && newValue1 != nullptr) { @@ -1747,9 +1233,10 @@ GfErrType LocalRegion::updateNoThrow( versionTag1 != nullptr ? versionTag1 : versionTag); if (err == GF_CACHE_CONCURRENT_MODIFICATION_EXCEPTION) { LOGDEBUG( - "Region::localUpdate: updateNoThrow<%s> for key [%s] failed because the cache already contains \ - an entry with higher version. The cache listener will not be invoked.", - TAction::name(), Utils::nullSafeToString(key).c_str()); + "Region::localUpdate: update<%s> for key [%s] failed because the " + "cache already contains an entry with higher version. The cache " + "listener will not be invoked.", + Action_::name(), Utils::nullSafeToString(key).c_str()); // Cache listener won't be called in this case return GF_NOERR; } else if (err != GF_NOERR) { @@ -1770,29 +1257,29 @@ GfErrType LocalRegion::updateNoThrow( // invokeCacheListenerForEntryEvent method has the check that if oldValue // is a CacheableToken then it sets it to nullptr; also determines if it // should be AFTER_UPDATE or AFTER_CREATE depending on oldValue - err = invokeCacheListenerForEntryEvent(key, oldValue, value, - aCallbackArgument, eventFlags, - TAction::s_afterEventType); + err = invokeCacheListenerForEntryEvent( + key, oldValue, value, cbArg, eventFlags, Action_::s_afterEventType); } + oldValue = retValue; return err; } -template -GfErrType LocalRegion::updateNoThrowTX( +template +GfErrType LocalRegion::updateTX( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument, - std::shared_ptr& oldValue, int updateCount, + std::shared_ptr& oldValue, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag, - DataInput* delta, std::shared_ptr eventId) { + DataInput* delta, std::shared_ptr eventId) noexcept { GfErrType err = GF_NOERR; - if ((err = TAction::checkArgs(key, value, delta)) != GF_NOERR) { + if ((err = Action_::checkArgs(key, value, delta)) != GF_NOERR) { return err; } CHECK_DESTROY_PENDING_NOTHROW(shared_lock); - TAction action(*this); + Action_ action(*this); bool cachingEnabled = m_regionAttributes.getCachingEnabled(); std::shared_ptr entry; @@ -1804,7 +1291,7 @@ GfErrType LocalRegion::updateNoThrowTX( LOGFINEST( "%s: did not change local value for key [%s] since it has " "been updated by another thread while operation was in progress", - TAction::name(), Utils::nullSafeToString(key).c_str()); + Action_::name(), Utils::nullSafeToString(key).c_str()); err = GF_NOERR; } else if (err == GF_CACHE_ENTRY_NOT_FOUND) { // Entry not found. Possibly because the entry was added and removed in @@ -1814,7 +1301,7 @@ GfErrType LocalRegion::updateNoThrowTX( "%s: No entry found. Possibly because the entry was added and " "removed in the same transaction. " "Ignoring this error. ", - TAction::name(), Utils::nullSafeToString(key).c_str()); + Action_::name(), Utils::nullSafeToString(key).c_str()); err = GF_NOERR; } else if (err != GF_NOERR) { return err; @@ -1830,102 +1317,118 @@ GfErrType LocalRegion::updateNoThrowTX( // should be AFTER_UPDATE or AFTER_CREATE depending on oldValue err = invokeCacheListenerForEntryEvent(key, oldValue, value, aCallbackArgument, - eventFlags, TAction::s_afterEventType); + eventFlags, Action_::s_afterEventType); return err; } -GfErrType LocalRegion::putNoThrow( +GfErrType LocalRegion::putNoThrow(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& oldValue, + int updateCount, + const CacheEventFlags eventFlags, + std::shared_ptr versionTag, + DataInput* delta, + std::shared_ptr eventId) { + std::shared_ptr retValue; + return update(key, value, cbArg, retValue, oldValue, updateCount, + eventFlags, versionTag, delta, eventId); +} + +GfErrType LocalRegion::putIfAbsentImpl( const std::shared_ptr& key, - const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& oldValue, int updateCount, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& retValue, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag, - DataInput* delta, std::shared_ptr eventId) { - return updateNoThrow(key, value, aCallbackArgument, oldValue, + DataInput* delta, std::shared_ptr eventId) noexcept { + std::shared_ptr oldValue; + return update(key, value, cbArg, retValue, oldValue, updateCount, eventFlags, versionTag, delta, eventId); } GfErrType LocalRegion::putNoThrowTX( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument, - std::shared_ptr& oldValue, int updateCount, + std::shared_ptr& oldValue, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag, DataInput* delta, std::shared_ptr eventId) { - return updateNoThrowTX(key, value, aCallbackArgument, oldValue, - updateCount, eventFlags, versionTag, - delta, eventId); + return updateTX(key, value, aCallbackArgument, oldValue, + updateCount, eventFlags, versionTag, delta, + eventId); } GfErrType LocalRegion::createNoThrow( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) { - std::shared_ptr oldValue; - return updateNoThrow(key, value, aCallbackArgument, oldValue, - updateCount, eventFlags, versionTag); + std::shared_ptr retValue; + std::shared_ptr oldValue; + return update(key, value, aCallbackArgument, retValue, oldValue, + updateCount, eventFlags, versionTag); } GfErrType LocalRegion::destroyNoThrow( const std::shared_ptr& key, const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) { - std::shared_ptr oldValue; - return updateNoThrow(key, nullptr, aCallbackArgument, - oldValue, updateCount, eventFlags, - versionTag); + std::shared_ptr retValue; + std::shared_ptr oldValue; + return update(key, nullptr, aCallbackArgument, retValue, + oldValue, updateCount, eventFlags, versionTag); } GfErrType LocalRegion::destroyNoThrowTX( const std::shared_ptr& key, const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) { - std::shared_ptr oldValue; - return updateNoThrowTX(key, nullptr, aCallbackArgument, - oldValue, updateCount, eventFlags, - versionTag); + std::shared_ptr oldValue; + return updateTX(key, nullptr, aCallbackArgument, oldValue, + updateCount, eventFlags, versionTag); } GfErrType LocalRegion::removeNoThrow( const std::shared_ptr& key, - const std::shared_ptr& value, + const std::shared_ptr& value, const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) { - std::shared_ptr oldValue; - return updateNoThrow(key, value, aCallbackArgument, oldValue, - updateCount, eventFlags, versionTag); + std::shared_ptr retValue; + std::shared_ptr oldValue; + return update(key, value, aCallbackArgument, retValue, oldValue, + updateCount, eventFlags, versionTag); } GfErrType LocalRegion::removeNoThrowEx( const std::shared_ptr& key, const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) { - std::shared_ptr oldValue; - return updateNoThrow(key, nullptr, aCallbackArgument, - oldValue, updateCount, eventFlags, - versionTag); + std::shared_ptr retValue; + std::shared_ptr oldValue; + return update(key, nullptr, aCallbackArgument, retValue, + oldValue, updateCount, eventFlags, versionTag); } GfErrType LocalRegion::invalidateNoThrow( const std::shared_ptr& key, const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) { - std::shared_ptr oldValue; - return updateNoThrow(key, nullptr, aCallbackArgument, - oldValue, updateCount, eventFlags, - versionTag); + std::shared_ptr retValue; + std::shared_ptr oldValue; + return update(key, nullptr, aCallbackArgument, retValue, + oldValue, updateCount, eventFlags, + versionTag); } GfErrType LocalRegion::invalidateNoThrowTX( const std::shared_ptr& key, const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) { - std::shared_ptr oldValue; - return updateNoThrowTX(key, nullptr, aCallbackArgument, - oldValue, updateCount, eventFlags, - versionTag); + std::shared_ptr oldValue; + return updateTX(key, nullptr, aCallbackArgument, oldValue, + updateCount, eventFlags, versionTag); } GfErrType LocalRegion::putAllNoThrow( @@ -1977,7 +1480,7 @@ GfErrType LocalRegion::putAllNoThrow( } _removeTracking(oldValueMap, *this); if (cachingEnabled || m_writer != nullptr) { - std::shared_ptr oldValue; + std::shared_ptr oldValue; for (const auto& iter : map) { const auto& key = iter.first; if (cachingEnabled && !m_regionAttributes.getConcurrencyChecksEnabled()) { @@ -1994,7 +1497,7 @@ GfErrType LocalRegion::putAllNoThrow( if (!invokeCacheWriterForEntryEvent( key, oldValue, iter.second, aCallbackArgument, CacheEventFlags::LOCAL, BEFORE_UPDATE)) { - PutActions::logCacheWriterFailure(key, oldValue); + PutAction::logCacheWriterFailure(key, oldValue); return GF_CACHEWRITER_ERROR; } } @@ -2019,7 +1522,7 @@ GfErrType LocalRegion::putAllNoThrow( versionedObjPartListPtr->getSucceededKeys()->at(keyIndex); const auto& mapIter = map.find(valPtr); std::shared_ptr key = nullptr; - std::shared_ptr value = nullptr; + std::shared_ptr value = nullptr; if (mapIter != map.end()) { key = mapIter->first; @@ -2040,7 +1543,7 @@ GfErrType LocalRegion::putAllNoThrow( versionedObjPartListPtr->getVersionedTagptr()[keyIndex]; } } - std::pair, int>& p = oldValueMap[key]; + std::pair, int>& p = oldValueMap[key]; if ((localErr = LocalRegion::putNoThrow( key, value, aCallbackArgument, p.first, p.second, CacheEventFlags::LOCAL | CacheEventFlags::NOCACHEWRITER, @@ -2227,8 +1730,8 @@ GfErrType LocalRegion::localClearNoThrow( GfErrType LocalRegion::invalidateLocal( const std::string& name, const std::shared_ptr& keyPtr, - const std::shared_ptr& value, const CacheEventFlags eventFlags, - std::shared_ptr versionTag) { + const std::shared_ptr& value, + const CacheEventFlags eventFlags, std::shared_ptr versionTag) { if (keyPtr == nullptr) { return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; } @@ -2237,7 +1740,7 @@ GfErrType LocalRegion::invalidateLocal( GfErrType err = GF_NOERR; bool cachingEnabled = m_regionAttributes.getCachingEnabled(); - std::shared_ptr oldValue; + std::shared_ptr oldValue; std::shared_ptr me; if (!eventFlags.isNotification() || getProcessedMarker()) { @@ -2321,7 +1824,7 @@ GfErrType LocalRegion::invalidateRegionNoThrow( std::shared_ptr me; for (decltype(size) i = 0; i < size; i++) { { - std::shared_ptr oldValue; + std::shared_ptr oldValue; // invalidate all the entries with a nullptr versionTag std::shared_ptr versionTag; m_entries->invalidate(v.at(i), me, oldValue, versionTag); @@ -2470,8 +1973,8 @@ GfErrType LocalRegion::destroyRegionNoThrow( GfErrType LocalRegion::putLocal(const std::string& name, bool isCreate, const std::shared_ptr& key, - const std::shared_ptr& value, - std::shared_ptr& oldValue, + const std::shared_ptr& value, + std::shared_ptr& oldValue, bool cachingEnabled, int updateCount, int destroyTracker, std::shared_ptr versionTag, @@ -2495,8 +1998,8 @@ GfErrType LocalRegion::putLocal(const std::string& name, bool isCreate, if (err == GF_INVALID_DELTA) { cachePerfStats.incFailureOnDeltaReceived(); // PXR: Get full object from server. - std::shared_ptr& newValue1 = - const_cast&>(value); + std::shared_ptr& newValue1 = + const_cast&>(value); std::shared_ptr versionTag1; err = getNoThrow_FullObject(eventId, newValue1, versionTag1); if (err == GF_NOERR && newValue1 != nullptr) { @@ -2572,8 +2075,8 @@ void LocalRegion::removeRegion(const std::string& name) { bool LocalRegion::invokeCacheWriterForEntryEvent( const std::shared_ptr& key, - std::shared_ptr& oldValue, - const std::shared_ptr& newValue, + std::shared_ptr& oldValue, + const std::shared_ptr& newValue, const std::shared_ptr& aCallbackArgument, CacheEventFlags eventFlags, EntryEventType type) { // Check if we have a local cache writer. If so, invoke and return. @@ -2692,8 +2195,8 @@ bool LocalRegion::invokeCacheWriterForRegionEvent( GfErrType LocalRegion::invokeCacheListenerForEntryEvent( const std::shared_ptr& key, - std::shared_ptr& oldValue, - const std::shared_ptr& newValue, + std::shared_ptr& oldValue, + const std::shared_ptr& newValue, const std::shared_ptr& aCallbackArgument, CacheEventFlags eventFlags, EntryEventType type, bool isLocal) { GfErrType err = GF_NOERR; @@ -3034,16 +2537,18 @@ std::chrono::seconds LocalRegion::getEntryExpiryDuration() const { GfErrType LocalRegion::unregisterKeysBeforeDestroyRegion() { return GF_NOERR; } GfErrType LocalRegion::getNoThrow_remote(const std::shared_ptr&, - std::shared_ptr&, + std::shared_ptr&, const std::shared_ptr&, std::shared_ptr&) { return GF_NOERR; } -GfErrType LocalRegion::putNoThrow_remote(const std::shared_ptr&, - const std::shared_ptr&, - const std::shared_ptr&, - std::shared_ptr&, bool) { +GfErrType LocalRegion::remotePut(const std::shared_ptr&, + const std::shared_ptr&, + const std::shared_ptr&, + std::shared_ptr&, + std::shared_ptr&, EventOperation, + bool) noexcept { return GF_NOERR; } @@ -3061,33 +2566,35 @@ GfErrType LocalRegion::removeAllNoThrow_remote( return GF_NOERR; } -GfErrType LocalRegion::createNoThrow_remote( - const std::shared_ptr&, const std::shared_ptr&, - const std::shared_ptr&, std::shared_ptr&) { +GfErrType LocalRegion::remoteCreate(const std::shared_ptr&, + const std::shared_ptr&, + const std::shared_ptr&, + std::shared_ptr&) noexcept { return GF_NOERR; } -GfErrType LocalRegion::destroyNoThrow_remote( - const std::shared_ptr&, const std::shared_ptr&, - std::shared_ptr&) { +GfErrType LocalRegion::remoteDestroy(const std::shared_ptr&, + const std::shared_ptr&, + std::shared_ptr&) noexcept { return GF_NOERR; } -GfErrType LocalRegion::removeNoThrow_remote( - const std::shared_ptr&, const std::shared_ptr&, - const std::shared_ptr&, std::shared_ptr&) { +GfErrType LocalRegion::remoteRemove(const std::shared_ptr&, + const std::shared_ptr&, + const std::shared_ptr&, + std::shared_ptr&) noexcept { return GF_NOERR; } -GfErrType LocalRegion::removeNoThrowEX_remote( - const std::shared_ptr&, const std::shared_ptr&, - std::shared_ptr&) { +GfErrType LocalRegion::remoteRemoveEx(const std::shared_ptr&, + const std::shared_ptr&, + std::shared_ptr&) noexcept { return GF_NOERR; } -GfErrType LocalRegion::invalidateNoThrow_remote( - const std::shared_ptr&, const std::shared_ptr&, - std::shared_ptr&) { +GfErrType LocalRegion::remoteInvalidate(const std::shared_ptr&, + const std::shared_ptr&, + std::shared_ptr&) noexcept { return GF_NOERR; } @@ -3187,13 +2694,13 @@ void LocalRegion::invokeAfterAllEndPointDisconnected() { } GfErrType LocalRegion::getNoThrow_FullObject(std::shared_ptr, - std::shared_ptr&, + std::shared_ptr&, std::shared_ptr&) { return GF_NOERR; } -std::shared_ptr LocalRegion::handleReplay( - GfErrType& err, std::shared_ptr value) const { +std::shared_ptr LocalRegion::handleReplay( + GfErrType& err, std::shared_ptr value) const { if (err == GF_TRANSACTION_DATA_REBALANCED_EXCEPTION || err == GF_TRANSACTION_DATA_NODE_HAS_DEPARTED_EXCEPTION) { bool isRollBack = (err == GF_TRANSACTION_DATA_REBALANCED_EXCEPTION); diff --git a/cppcache/src/LocalRegion.hpp b/cppcache/src/LocalRegion.hpp index f124efffc1..0e928d662a 100644 --- a/cppcache/src/LocalRegion.hpp +++ b/cppcache/src/LocalRegion.hpp @@ -39,6 +39,7 @@ #include #include "EntriesMap.hpp" +#include "EventOperation.hpp" #include "EventType.hpp" #include "InterestResultPolicy.hpp" #include "RegionInternal.hpp" @@ -75,9 +76,7 @@ namespace client { class CreateActions; class DestroyActions; -class InvalidateActions; -class PutActions; -class PutActionsTx; +class InvalidateAction; class RemoveActions; class VersionedCacheableObjectPartList; @@ -145,20 +144,20 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { } void updateAccessAndModifiedTime(bool modified) override; std::shared_ptr getStatistics() const override; - void clear(const std::shared_ptr& aCallbackArgument = + void clear(const std::shared_ptr& aCallbackArgument = nullptr) override; - void localClear(const std::shared_ptr& aCallbackArgument = + void localClear(const std::shared_ptr& aCallbackArgument = nullptr) override; GfErrType localClearNoThrow( - const std::shared_ptr& aCallbackArgument = nullptr, + const std::shared_ptr& aCallbackArgument = nullptr, const CacheEventFlags eventFlags = CacheEventFlags::NORMAL); - void invalidateRegion(const std::shared_ptr& aCallbackArgument = + void invalidateRegion(const std::shared_ptr& aCallbackArgument = nullptr) override; - void localInvalidateRegion(const std::shared_ptr& + void localInvalidateRegion(const std::shared_ptr& aCallbackArgument = nullptr) override; - void destroyRegion(const std::shared_ptr& aCallbackArgument = + void destroyRegion(const std::shared_ptr& aCallbackArgument = nullptr) override; - void localDestroyRegion(const std::shared_ptr& + void localDestroyRegion(const std::shared_ptr& aCallbackArgument = nullptr) override; std::shared_ptr getSubregion(const std::string& path) override; std::shared_ptr createSubregion( @@ -172,50 +171,56 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { std::shared_ptr& valuePtr); std::shared_ptr get( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument) override; + const std::shared_ptr& aCallbackArgument) override; void put(const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; + std::shared_ptr putIfAbsent( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg = + nullptr) override; + void localPut(const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; void create(const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; void localCreate(const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; void invalidate(const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; void localInvalidate(const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; void destroy(const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; void localDestroy(const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; virtual GfErrType localDestroyNoCallbacks( const std::shared_ptr& key); bool remove(const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; bool removeEx(const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; bool localRemove(const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; bool localRemoveEx(const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; std::vector> keys() override; std::vector> serverKeys() override; @@ -224,20 +229,20 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { HashMapOfCacheable getAll( const std::vector>& keys, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; HashMapOfCacheable getAll_internal( const std::vector>& keys, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, bool addToLocalCache) override; void putAll(const HashMapOfCacheable& map, std::chrono::milliseconds timeout = DEFAULT_RESPONSE_TIMEOUT, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; void removeAll(const std::vector>& keys, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; uint32_t size() override; virtual uint32_t size_remote(); @@ -265,25 +270,35 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { GfErrType getNoThrow( const std::shared_ptr& key, std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument) override; + const std::shared_ptr& aCallbackArgument) override; GfErrType getAllNoThrow( const std::vector>& keys, const std::shared_ptr& values, const std::shared_ptr& exceptions, const bool addToLocalCache, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; GfErrType putNoThrow(const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& cbArg, std::shared_ptr& oldValue, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag, DataInput* delta = nullptr, std::shared_ptr eventId = nullptr) override; + + GfErrType putIfAbsentImpl( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& aCallbackArgument, + std::shared_ptr& retValue, int updateCount, + const CacheEventFlags eventFlags, std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr) noexcept override; + GfErrType putNoThrowTX(const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, std::shared_ptr& oldValue, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag, @@ -292,49 +307,49 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { GfErrType createNoThrow( const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, int updateCount, + const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) override; GfErrType destroyNoThrow( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument, int updateCount, + const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) override; virtual GfErrType destroyNoThrowTX( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument, int updateCount, + const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag); GfErrType removeNoThrow( const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, int updateCount, + const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) override; virtual GfErrType removeNoThrowEx( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument, int updateCount, + const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag); virtual GfErrType putAllNoThrow( const HashMapOfCacheable& map, std::chrono::milliseconds timeout = DEFAULT_RESPONSE_TIMEOUT, - const std::shared_ptr& aCallbackArgument = nullptr); + const std::shared_ptr& aCallbackArgument = nullptr); virtual GfErrType removeAllNoThrow( const std::vector>& keys, - const std::shared_ptr& aCallbackArgument = nullptr); + const std::shared_ptr& aCallbackArgument = nullptr); GfErrType invalidateNoThrow( const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, int updateCount, + const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag) override; virtual GfErrType invalidateNoThrowTX( const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, int updateCount, + const std::shared_ptr& aCallbackArgument, int updateCount, const CacheEventFlags eventFlags, std::shared_ptr versionTag); GfErrType invalidateRegionNoThrow( - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, const CacheEventFlags eventFlags) override; GfErrType destroyRegionNoThrow( - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, bool removeFromParent, const CacheEventFlags eventFlags) override; void tombstoneOperationNoThrow( const std::shared_ptr& tombstoneVersions, @@ -411,50 +426,59 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { std::shared_ptr getTombstoneList() override; + public: + virtual GfErrType remotePut(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag, + std::shared_ptr& retValue, + EventOperation op, + bool checkDelta = true) noexcept; + + virtual GfErrType remoteInvalidate( + const std::shared_ptr& key, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept; + + virtual GfErrType remoteRemove( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept; + + virtual GfErrType remoteRemoveEx( + const std::shared_ptr& key, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept; + + virtual GfErrType remoteDestroy( + const std::shared_ptr& key, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept; + + virtual GfErrType remoteCreate( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept; + protected: /* virtual protected methods */ virtual void release(bool invokeCallbacks = true); virtual GfErrType getNoThrow_remote( const std::shared_ptr& keyPtr, std::shared_ptr& valPtr, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, std::shared_ptr& versionTag); - virtual GfErrType putNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& cvalue, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag, bool checkDelta = true); virtual GfErrType putAllNoThrow_remote( const HashMapOfCacheable& map, std::shared_ptr& versionedObjPartList, std::chrono::milliseconds timeout, - const std::shared_ptr& aCallbackArgument); + const std::shared_ptr& aCallbackArgument); virtual GfErrType removeAllNoThrow_remote( const std::vector>& keys, std::shared_ptr& versionedObjPartList, - const std::shared_ptr& aCallbackArgument); - virtual GfErrType createNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& cvalue, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag); - virtual GfErrType destroyNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag); - virtual GfErrType removeNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& cvalue, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag); - virtual GfErrType removeNoThrowEX_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag); - virtual GfErrType invalidateNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag); + const std::shared_ptr& aCallbackArgument); virtual GfErrType getAllNoThrow_remote( const std::vector>* keys, const std::shared_ptr& values, @@ -462,11 +486,11 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { const std::shared_ptr>>& resultKeys, bool addToLocalCache, - const std::shared_ptr& aCallbackArgument); + const std::shared_ptr& aCallbackArgument); virtual GfErrType invalidateRegionNoThrow_remote( - const std::shared_ptr& aCallbackArgument); + const std::shared_ptr& aCallbackArgument); virtual GfErrType destroyRegionNoThrow_remote( - const std::shared_ptr& aCallbackArgument); + const std::shared_ptr& aCallbackArgument); virtual GfErrType unregisterKeysBeforeDestroyRegion(); const std::shared_ptr& getPool() const override { return m_attachedPool; @@ -486,22 +510,25 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { // template method for put and create template - GfErrType updateNoThrow( - const std::shared_ptr& key, - const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& oldValue, int updateCount, - const CacheEventFlags eventFlags, std::shared_ptr versionTag, - DataInput* delta = nullptr, std::shared_ptr eventId = nullptr); + GfErrType update(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& oldValue, + std::shared_ptr& retValue, int updateCount, + const CacheEventFlags eventFlags, + std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr) noexcept; template - GfErrType updateNoThrowTX( - const std::shared_ptr& key, - const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& oldValue, int updateCount, - const CacheEventFlags eventFlags, std::shared_ptr versionTag, - DataInput* delta = nullptr, std::shared_ptr eventId = nullptr); + GfErrType updateTX(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& aCallbackArgument, + std::shared_ptr& oldValue, int updateCount, + const CacheEventFlags eventFlags, + std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr) noexcept; int64_t startStatOpTime(); void updateStatOpTime(Statistics* m_regionStats, int32_t statId, @@ -538,19 +565,19 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { const std::shared_ptr& key, std::shared_ptr& oldValue, const std::shared_ptr& newValue, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, CacheEventFlags eventFlags, EntryEventType type); bool invokeCacheWriterForRegionEvent( - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, CacheEventFlags eventFlags, RegionEventType type); GfErrType invokeCacheListenerForEntryEvent( const std::shared_ptr& key, std::shared_ptr& oldValue, const std::shared_ptr& newValue, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, CacheEventFlags eventFlags, EntryEventType type, bool isLocal = false); GfErrType invokeCacheListenerForRegionEvent( - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, CacheEventFlags eventFlags, RegionEventType type); // functions related to expirations. void updateAccessAndModifiedTimeForEntry(std::shared_ptr& ptr, @@ -588,17 +615,15 @@ class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal { private: std::shared_ptr findSubRegion(const std::string& name); GfErrType invalidateRegionNoThrowOnSubRegions( - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, const CacheEventFlags eventFlags); // these classes encapsulate actions specific to update operations - // used by the template updateNoThrow class - friend class PutActions; - friend class PutActionsTx; + // used by the template update class friend class CreateActions; friend class DestroyActions; friend class RemoveActions; - friend class InvalidateActions; + friend class InvalidateAction; }; } // namespace client diff --git a/cppcache/src/ProxyRegion.hpp b/cppcache/src/ProxyRegion.hpp index e0a5c1b3fd..113840afae 100644 --- a/cppcache/src/ProxyRegion.hpp +++ b/cppcache/src/ProxyRegion.hpp @@ -75,31 +75,31 @@ class ProxyRegion final : public Region { return m_realRegion->getStatistics(); } - void invalidateRegion(const std::shared_ptr&) final { + void invalidateRegion(const std::shared_ptr&) final { throw UnsupportedOperationException("Region.invalidateRegion()"); } - void localInvalidateRegion(const std::shared_ptr&) final { + void localInvalidateRegion(const std::shared_ptr&) final { throw UnsupportedOperationException("Region.localInvalidateRegion()"); } void destroyRegion( - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); m_realRegion->destroyRegion(aCallbackArgument); } void clear( - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); m_realRegion->clear(aCallbackArgument); } - void localClear(const std::shared_ptr&) final { + void localClear(const std::shared_ptr&) final { throw UnsupportedOperationException("localClear()"); } - void localDestroyRegion(const std::shared_ptr&) final { + void localDestroyRegion(const std::shared_ptr&) final { throw UnsupportedOperationException("Region.localDestroyRegion()"); } @@ -150,7 +150,7 @@ class ProxyRegion final : public Region { std::shared_ptr get( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); return m_realRegion->get(key, aCallbackArgument); } @@ -159,14 +159,14 @@ class ProxyRegion final : public Region { template inline std::shared_ptr get( const KEYTYPE& key, - const std::shared_ptr& callbackArg = nullptr) { + const std::shared_ptr& callbackArg = nullptr) { return get(CacheableKey::create(key), callbackArg); } void put( const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); return m_realRegion->put(key, value, aCallbackArgument); } @@ -174,14 +174,14 @@ class ProxyRegion final : public Region { /** Convenience method allowing both key and value to be a const char* */ template inline void put(const KEYTYPE& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { put(CacheableKey::create(key), Serializable::create(value), arg); } /** Convenience method allowing key to be a const char* */ template inline void put(const KEYTYPE& key, const std::shared_ptr& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { put(CacheableKey::create(key), value, arg); } @@ -189,28 +189,36 @@ class ProxyRegion final : public Region { template inline void put(const std::shared_ptr& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { put(key, Serializable::create(value), arg); } + std::shared_ptr putIfAbsent( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg = nullptr) final { + GuardUserAttributes gua(m_authenticatedView); + return m_realRegion->putIfAbsent(key, value, cbArg); + } + void putAll( const HashMapOfCacheable& map, std::chrono::milliseconds timeout = DEFAULT_RESPONSE_TIMEOUT, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); return m_realRegion->putAll(map, timeout, aCallbackArgument); } void localPut(const std::shared_ptr&, const std::shared_ptr&, - const std::shared_ptr&) final { + const std::shared_ptr&) final { throw UnsupportedOperationException("Region.localPut()"); } /** Convenience method allowing both key and value to be a const char* */ template inline void localPut(const KEYTYPE& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { localPut(CacheableKey::create(key), Serializable::create(value), arg); } @@ -218,7 +226,7 @@ class ProxyRegion final : public Region { template inline void localPut(const KEYTYPE& key, const std::shared_ptr& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { localPut(CacheableKey::create(key), value, arg); } @@ -226,14 +234,14 @@ class ProxyRegion final : public Region { template inline void localPut(const std::shared_ptr& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { localPut(key, Serializable::create(value), arg); } void create( const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); m_realRegion->create(key, value, aCallbackArgument); } @@ -241,7 +249,7 @@ class ProxyRegion final : public Region { /** Convenience method allowing both key and value to be a const char* */ template inline void create(const KEYTYPE& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { create(CacheableKey::create(key), Serializable::create(value), arg); } @@ -249,7 +257,7 @@ class ProxyRegion final : public Region { template inline void create(const KEYTYPE& key, const std::shared_ptr& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { create(CacheableKey::create(key), value, arg); } @@ -257,20 +265,20 @@ class ProxyRegion final : public Region { template inline void create(const std::shared_ptr& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { create(key, Serializable::create(value), arg); } void localCreate(const std::shared_ptr&, const std::shared_ptr&, - const std::shared_ptr&) final { + const std::shared_ptr&) final { throw UnsupportedOperationException("Region.localCreate()"); } /** Convenience method allowing both key and value to be a const char* */ template inline void localCreate(const KEYTYPE& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { localCreate(CacheableKey::create(key), Serializable::create(value), arg); } @@ -278,7 +286,7 @@ class ProxyRegion final : public Region { template inline void localCreate(const KEYTYPE& key, const std::shared_ptr& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { localCreate(CacheableKey::create(key), value, arg); } @@ -286,13 +294,13 @@ class ProxyRegion final : public Region { template inline void localCreate(const std::shared_ptr& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { localCreate(key, Serializable::create(value), arg); } void invalidate( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); m_realRegion->invalidate(key, aCallbackArgument); } @@ -300,25 +308,25 @@ class ProxyRegion final : public Region { /** Convenience method allowing key to be a const char* */ template inline void invalidate(const KEYTYPE& key, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { invalidate(CacheableKey::create(key), arg); } void localInvalidate(const std::shared_ptr&, - const std::shared_ptr&) final { + const std::shared_ptr&) final { throw UnsupportedOperationException("Region.localInvalidate()"); } /** Convenience method allowing key to be a const char* */ template inline void localInvalidate( - const KEYTYPE& key, const std::shared_ptr& arg = nullptr) { + const KEYTYPE& key, const std::shared_ptr& arg = nullptr) { localInvalidate(CacheableKey::create(key), arg); } void destroy( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); m_realRegion->destroy(key, aCallbackArgument); } @@ -326,26 +334,26 @@ class ProxyRegion final : public Region { /** Convenience method allowing key to be a const char* */ template inline void destroy(const KEYTYPE& key, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { destroy(CacheableKey::create(key), arg); } void localDestroy(const std::shared_ptr&, - const std::shared_ptr&) final { + const std::shared_ptr&) final { throw UnsupportedOperationException("Region.localDestroy()"); } /** Convenience method allowing key to be a const char* */ template inline void localDestroy(const KEYTYPE& key, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { localDestroy(CacheableKey::create(key), arg); } bool remove( const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); return m_realRegion->remove(key, value, aCallbackArgument); } @@ -353,7 +361,7 @@ class ProxyRegion final : public Region { /** Convenience method allowing both key and value to be a const char* */ template inline bool remove(const KEYTYPE& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { return remove(CacheableKey::create(key), Serializable::create(value), arg); } @@ -361,7 +369,7 @@ class ProxyRegion final : public Region { template inline bool remove(const KEYTYPE& key, const std::shared_ptr& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { return remove(CacheableKey::create(key), value, arg); } @@ -369,13 +377,13 @@ class ProxyRegion final : public Region { template inline bool remove(const std::shared_ptr& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { return remove(key, Serializable::create(value), arg); } bool removeEx( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); return m_realRegion->removeEx(key, aCallbackArgument); } @@ -383,20 +391,20 @@ class ProxyRegion final : public Region { /** Convenience method allowing key to be a const char* */ template inline bool removeEx(const KEYTYPE& key, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { return removeEx(CacheableKey::create(key), arg); } bool localRemove(const std::shared_ptr&, const std::shared_ptr&, - const std::shared_ptr&) final { + const std::shared_ptr&) final { throw UnsupportedOperationException("Region.localRemove()"); } /** Convenience method allowing both key and value to be a const char* */ template inline bool localRemove(const KEYTYPE& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { return localRemove(CacheableKey::create(key), Serializable::create(value), arg); } @@ -405,7 +413,7 @@ class ProxyRegion final : public Region { template inline bool localRemove(const KEYTYPE& key, const std::shared_ptr& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { return localRemove(CacheableKey::create(key), value, arg); } @@ -413,19 +421,19 @@ class ProxyRegion final : public Region { template inline bool localRemove(const std::shared_ptr& key, const VALUETYPE& value, - const std::shared_ptr& arg = nullptr) { + const std::shared_ptr& arg = nullptr) { return localRemove(key, Serializable::create(value), arg); } bool localRemoveEx(const std::shared_ptr&, - const std::shared_ptr&) final { + const std::shared_ptr&) final { throw UnsupportedOperationException("Region.localRemoveEx()"); } /** Convenience method allowing key to be a const char* */ template inline bool localRemoveEx( - const KEYTYPE& key, const std::shared_ptr& arg = nullptr) { + const KEYTYPE& key, const std::shared_ptr& arg = nullptr) { return localRemoveEx(CacheableKey::create(key), arg); } @@ -526,7 +534,7 @@ class ProxyRegion final : public Region { HashMapOfCacheable getAll( const std::vector>& keys, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); return m_realRegion->getAll_internal(keys, aCallbackArgument, false); } @@ -545,7 +553,7 @@ class ProxyRegion final : public Region { return m_realRegion->existsValue(predicate, timeout); } - std::shared_ptr selectValue( + std::shared_ptr selectValue( const std::string& predicate, std::chrono::milliseconds timeout = DEFAULT_QUERY_RESPONSE_TIMEOUT) final { GuardUserAttributes gua(m_authenticatedView); @@ -554,7 +562,7 @@ class ProxyRegion final : public Region { void removeAll( const std::vector>& keys, - const std::shared_ptr& aCallbackArgument = nullptr) final { + const std::shared_ptr& aCallbackArgument = nullptr) final { GuardUserAttributes gua(m_authenticatedView); m_realRegion->removeAll(keys, aCallbackArgument); } diff --git a/cppcache/src/PutAction.cpp b/cppcache/src/PutAction.cpp new file mode 100644 index 0000000000..cb9492dddf --- /dev/null +++ b/cppcache/src/PutAction.cpp @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PutAction.hpp" + +#include "LocalRegion.hpp" +#include "TSSTXStateWrapper.hpp" +#include "Utils.hpp" +#include "VersionTag.hpp" + +namespace apache { +namespace geode { +namespace client { + +PutAction::PutAction(LocalRegion& region) + : region_{region}, txState_{TSSTXStateWrapper::get().getTXState()} {} + +void PutAction::getCallbackOldValue( + bool cachingEnabled, const std::shared_ptr& key, + std::shared_ptr& entry, + std::shared_ptr& oldValue) const { + if (cachingEnabled) { + region_.getEntryMap()->getEntry(key, entry, oldValue); + } +} + +GfErrType PutAction::remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& retVal, + std::shared_ptr& versionTag) { + return region_.remotePut(key, value, cbArg, versionTag, retVal, + EventOperation::UPDATE); +} + +GfErrType PutAction::localUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, + bool cachingEnabled, const CacheEventFlags, + int updateCount, + std::shared_ptr versionTag, + DataInput* delta, + std::shared_ptr eventId, bool) { + return region_.putLocal(name(), false, key, value, oldValue, cachingEnabled, + updateCount, 0, versionTag, delta, eventId); +} + +void PutAction::logCacheWriterFailure( + const std::shared_ptr& key, + const std::shared_ptr& oldValue) { + bool isUpdate = (oldValue != nullptr); + LOGFINER("Cache writer vetoed %s for key %s", + (isUpdate ? "update" : "create"), + Utils::nullSafeToString(key).c_str()); +} + +GfErrType PutAction::checkArgs(const std::shared_ptr& key, + const std::shared_ptr& value, + DataInput* delta) { + if (key == nullptr || (value == nullptr && delta == nullptr)) { + return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; + } + + return GF_NOERR; +} + +PutActionTx::PutActionTx(LocalRegion& region) : PutAction{region} {} + +GfErrType PutActionTx::checkArgs(const std::shared_ptr& key, + const std::shared_ptr&, + DataInput*) { + if (key == nullptr) { + return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; + } + + return GF_NOERR; +} + +PutIfAbsentAction::PutIfAbsentAction(LocalRegion& region) + : PutAction{region}, absent_{true} {} + +GfErrType PutIfAbsentAction::remoteUpdate( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& retVal, + std::shared_ptr& versionTag) { + auto err = region_.remotePut(key, value, cbArg, versionTag, retVal, + EventOperation::PUT_IF_ABSENT); + if (err == GF_NOERR) { + absent_ = retVal == nullptr; + } + + return err; +} + +GfErrType PutIfAbsentAction::localUpdate( + const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, bool cachingEnabled, + const CacheEventFlags flags, int updateCount, + std::shared_ptr versionTag, DataInput* delta, + std::shared_ptr eventId, bool afterRemote) { + if (!absent_) { + return GF_NOERR; + } + + return PutAction::localUpdate(key, value, oldValue, cachingEnabled, flags, + updateCount, versionTag, delta, eventId, + afterRemote); +} + +} // namespace client +} // namespace geode +} // namespace apache diff --git a/cppcache/src/PutAction.hpp b/cppcache/src/PutAction.hpp new file mode 100644 index 0000000000..6419d67908 --- /dev/null +++ b/cppcache/src/PutAction.hpp @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef GEODE_PUT_ACTION_H_ +#define GEODE_PUT_ACTION_H_ + +#include + +#include "CacheEventFlags.hpp" +#include "ErrType.hpp" +#include "EventType.hpp" + +namespace apache { +namespace geode { +namespace client { + +class CacheableKey; +class DataInput; +class EventId; +class LocalRegion; +class MapEntryImpl; +class Serializable; +class TXState; +class VersionTag; + +// encapsulates actions that need to be taken for a put() operation +class PutAction { + public: + static const EntryEventType s_beforeEventType = BEFORE_UPDATE; + static const EntryEventType s_afterEventType = AFTER_UPDATE; + static const bool s_addIfAbsent = true; + static const bool s_failIfPresent = false; + + public: + explicit PutAction(LocalRegion& region); + + void getCallbackOldValue(bool cachingEnabled, + const std::shared_ptr& key, + std::shared_ptr& entry, + std::shared_ptr& oldValue) const; + + GfErrType remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& retVal, + std::shared_ptr& versionTag); + + GfErrType localUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, + bool cachingEnabled, const CacheEventFlags eventFlags, + int updateCount, std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr, + bool afterRemote = false); + + TXState* getTxState() const { return txState_; } + + public: + static const char* name() { return "Region::put"; } + + static void logCacheWriterFailure( + const std::shared_ptr& key, + const std::shared_ptr& oldValue); + + static GfErrType checkArgs(const std::shared_ptr& key, + const std::shared_ptr& value, + DataInput* delta = nullptr); + + protected: + LocalRegion& region_; + TXState* txState_; +}; + +// encapsulates actions that need to be taken for a put() operation. This +// implementation allows +// null values in Put during transaction. See defect #743 +class PutActionTx : public PutAction { + public: + explicit PutActionTx(LocalRegion& region); + static GfErrType checkArgs(const std::shared_ptr& key, + const std::shared_ptr& value, + DataInput* delta = nullptr); +}; + +class PutIfAbsentAction : public PutAction { + public: + explicit PutIfAbsentAction(LocalRegion& region); + + GfErrType localUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, + bool cachingEnabled, const CacheEventFlags eventFlags, + int updateCount, std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr, + bool afterRemote = false); + + GfErrType remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& retValue, + std::shared_ptr& versionTag); + + static const char* name() { return "Region::putIfAbsent"; } + + protected: + bool absent_; +}; + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_PUT_ACTION_H_ diff --git a/cppcache/src/RegionInternal.cpp b/cppcache/src/RegionInternal.cpp index e3a541ca29..1582d550c6 100644 --- a/cppcache/src/RegionInternal.cpp +++ b/cppcache/src/RegionInternal.cpp @@ -25,23 +25,6 @@ namespace apache { namespace geode { namespace client { -// Static initializers for CacheEventFlags -const CacheEventFlags CacheEventFlags::NORMAL(CacheEventFlags::GF_NORMAL); -const CacheEventFlags CacheEventFlags::LOCAL(CacheEventFlags::GF_LOCAL); -const CacheEventFlags CacheEventFlags::NOTIFICATION( - CacheEventFlags::GF_NOTIFICATION); -const CacheEventFlags CacheEventFlags::NOTIFICATION_UPDATE( - CacheEventFlags::GF_NOTIFICATION_UPDATE); -const CacheEventFlags CacheEventFlags::EVICTION(CacheEventFlags::GF_EVICTION); -const CacheEventFlags CacheEventFlags::EXPIRATION( - CacheEventFlags::GF_EXPIRATION); -const CacheEventFlags CacheEventFlags::CACHE_CLOSE( - CacheEventFlags::GF_CACHE_CLOSE); -const CacheEventFlags CacheEventFlags::NOCACHEWRITER( - CacheEventFlags::GF_NOCACHEWRITER); -const CacheEventFlags CacheEventFlags::NOCALLBACKS( - CacheEventFlags::GF_NOCALLBACKS); - RegionInternal::RegionInternal(CacheImpl* cacheImpl, RegionAttributes attributes) : Region(cacheImpl), m_regionAttributes(attributes) {} diff --git a/cppcache/src/RegionInternal.hpp b/cppcache/src/RegionInternal.hpp index 1e25a6f289..46888714aa 100644 --- a/cppcache/src/RegionInternal.hpp +++ b/cppcache/src/RegionInternal.hpp @@ -26,6 +26,7 @@ #include +#include "CacheEventFlags.hpp" #include "ErrType.hpp" #include "EventId.hpp" #include "HashMapOfException.hpp" @@ -35,90 +36,6 @@ namespace apache { namespace geode { namespace client { -/** - * @class CacheEventFlags RegionInternal.hpp - * - * This class encapsulates the flags (e.g. notification, expiration, local) - * for cache events for various NoThrow methods. - * - * - */ -class CacheEventFlags { - private: - uint16_t m_flags; - static const uint16_t GF_NORMAL = 0x01; - static const uint16_t GF_LOCAL = 0x02; - static const uint16_t GF_NOTIFICATION = 0x04; - static const uint16_t GF_NOTIFICATION_UPDATE = 0x08; - static const uint16_t GF_EVICTION = 0x10; - static const uint16_t GF_EXPIRATION = 0x20; - static const uint16_t GF_CACHE_CLOSE = 0x40; - static const uint16_t GF_NOCACHEWRITER = 0x80; - static const uint16_t GF_NOCALLBACKS = 0x100; - - inline explicit CacheEventFlags(const uint16_t flags) : m_flags(flags) {} - - public: - static const CacheEventFlags NORMAL; - static const CacheEventFlags LOCAL; - static const CacheEventFlags NOTIFICATION; - static const CacheEventFlags NOTIFICATION_UPDATE; - static const CacheEventFlags EVICTION; - static const CacheEventFlags EXPIRATION; - static const CacheEventFlags CACHE_CLOSE; - static const CacheEventFlags NOCACHEWRITER; - static const CacheEventFlags NOCALLBACKS; - - inline CacheEventFlags(const CacheEventFlags& flags) = default; - - CacheEventFlags() = delete; - CacheEventFlags& operator=(const CacheEventFlags&) = delete; - - inline CacheEventFlags operator|(const CacheEventFlags& flags) const { - return CacheEventFlags(m_flags | flags.m_flags); - } - - inline uint32_t operator&(const CacheEventFlags& flags) const { - return (m_flags & flags.m_flags); - } - - inline bool operator==(const CacheEventFlags& flags) const { - return (m_flags == flags.m_flags); - } - - inline bool isNormal() const { return (m_flags & GF_NORMAL) > 0; } - - inline bool isLocal() const { return (m_flags & GF_LOCAL) > 0; } - - inline bool isNotification() const { return (m_flags & GF_NOTIFICATION) > 0; } - - inline bool isNotificationUpdate() const { - return (m_flags & GF_NOTIFICATION_UPDATE) > 0; - } - - inline bool isEviction() const { return (m_flags & GF_EVICTION) > 0; } - - inline bool isExpiration() const { return (m_flags & GF_EXPIRATION) > 0; } - - inline bool isCacheClose() const { return (m_flags & GF_CACHE_CLOSE) > 0; } - - inline bool isNoCacheWriter() const { - return (m_flags & GF_NOCACHEWRITER) > 0; - } - - inline bool isNoCallbacks() const { return (m_flags & GF_NOCALLBACKS) > 0; } - - inline bool isEvictOrExpire() const { - return (m_flags & (GF_EVICTION | GF_EXPIRATION)) > 0; - } - - // special optimized method for CacheWriter invocation condition - inline bool invokeCacheWriter() const { - return ((m_flags & (GF_NOTIFICATION | GF_EVICTION | GF_EXPIRATION | - GF_NOCACHEWRITER | GF_NOCALLBACKS)) == 0x0); - } -}; - class TombstoneList; class VersionTag; class MapEntryImpl; @@ -195,6 +112,14 @@ class RegionInternal : public Region { const CacheEventFlags eventFlags, std::shared_ptr versionTag, DataInput* delta = nullptr, std::shared_ptr eventId = nullptr) = 0; + virtual GfErrType putIfAbsentImpl( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& aCallbackArgument, + std::shared_ptr& oldValue, int updateCount, + const CacheEventFlags eventFlags, std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr) noexcept = 0; virtual GfErrType createNoThrow( const std::shared_ptr& key, const std::shared_ptr& value, diff --git a/cppcache/src/RemoveAction.cpp b/cppcache/src/RemoveAction.cpp new file mode 100644 index 0000000000..7fa37bb51e --- /dev/null +++ b/cppcache/src/RemoveAction.cpp @@ -0,0 +1,222 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "RemoveAction.hpp" + +#include + +#include "CacheImpl.hpp" +#include "LocalRegion.hpp" +#include "SerializableHelper.hpp" +#include "TSSTXStateWrapper.hpp" +#include "Utils.hpp" +#include "VersionTag.hpp" + +namespace apache { +namespace geode { +namespace client { + +using internal::DataSerializablePrimitive; + +RemoveAction::RemoveAction(LocalRegion& region, bool allowNull) + : region_(region), + response_(GF_ENOENT), + txState_{TSSTXStateWrapper::get().getTXState()}, + allowNull_{allowNull} {} + +void RemoveAction::getCallbackOldValue( + bool cachingEnabled, const std::shared_ptr& key, + std::shared_ptr& entry, + std::shared_ptr& oldValue) const { + if (cachingEnabled) { + region_.getEntryMap()->getEntry(key, entry, oldValue); + } +} + +GfErrType RemoveAction::remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr&, + std::shared_ptr& versionTag) { + // propagate the remove to remote server, if any + std::shared_ptr oldValue; + GfErrType err = GF_NOERR; + if (!allowNull_ && region_.getAttributes().getCachingEnabled()) { + region_.getEntry(key, oldValue); + if (oldValue && value) { + if (!serializedEqualTo(oldValue, value)) { + err = GF_ENOENT; + return err; + } + } else if (!oldValue || CacheableToken::isInvalid(oldValue)) { + response_ = region_.remoteRemove(key, value, cbArg, versionTag); + return response_; + } else if (oldValue && !value) { + return GF_ENOENT; + } + } + + if (allowNull_) { + response_ = region_.remoteRemoveEx(key, cbArg, versionTag); + } else { + response_ = region_.remoteRemove(key, value, cbArg, versionTag); + } + + LOGDEBUG("RemoveAction::remoteUpdate server response: %d", response_); + return response_; +} + +GfErrType RemoveAction::localUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, + bool cachingEnabled, + const CacheEventFlags eventFlags, + int updateCount, + std::shared_ptr versionTag, + DataInput*, std::shared_ptr, + bool afterRemote) { + std::shared_ptr fetchedValue; + GfErrType err = GF_NOERR; + if (!allowNull_ && cachingEnabled) { + region_.getEntry(key, fetchedValue); + if (fetchedValue && value) { + if (!serializedEqualTo(fetchedValue, value)) { + return GF_ENOENT; + } + } else if (!value && + (!CacheableToken::isInvalid(fetchedValue) || !fetchedValue)) { + err = (response_ == GF_NOERR && !fetchedValue) ? GF_NOERR : GF_ENOENT; + if (updateCount >= 0 && + !region_.getAttributes().getConcurrencyChecksEnabled()) { + // This means server has deleted an entry & same entry has been + // destroyed locally + // So call removeTrackerForEntry to remove key that + // was added in the map during addTrackerForEntry call. + region_.getEntryMap()->removeTrackerForEntry(key); + } + + return err; + } else if (!fetchedValue && value && response_ != GF_NOERR) { + err = GF_ENOENT; + return err; + } + } + + auto& cachePerfStats = region_.getCacheImpl()->getCachePerfStats(); + if (cachingEnabled) { + // for notification invoke the listener even if the key does + // not exist locally + LOGDEBUG("Region::remove: region [%s] removing key [%s]", + region_.getFullPath().c_str(), + Utils::nullSafeToString(key).c_str()); + + std::shared_ptr entry; + if ((err = region_.getEntryMap()->remove(key, oldValue, entry, updateCount, + versionTag, afterRemote)) != + GF_NOERR) { + if (eventFlags.isNotification()) { + LOGDEBUG( + "Region::remove: region [%s] remove key [%s] for " + "notification having value [%s] failed with %d", + region_.getFullPath().c_str(), Utils::nullSafeToString(key).c_str(), + Utils::nullSafeToString(oldValue).c_str(), err); + err = GF_NOERR; + } + + return err; + } + + if (oldValue) { + LOGDEBUG( + "Region::remove: region [%s] removed key [%s] having " + "value [%s]", + region_.getFullPath().c_str(), Utils::nullSafeToString(key).c_str(), + Utils::nullSafeToString(oldValue).c_str()); + + // any cleanup required for the entry (e.g. removing from LRU list) + if (entry) { + entry->cleanup(eventFlags); + } + + // entry/region expiration + if (!eventFlags.isEvictOrExpire()) { + region_.updateAccessAndModifiedTime(true); + } + + // update the stats + region_.getRegionStats()->setEntries(region_.getEntryMap()->size()); + cachePerfStats.incEntries(-1); + } + } + // update the stats + region_.getRegionStats()->incDestroys(); + cachePerfStats.incDestroys(); + return GF_NOERR; +} + +bool RemoveAction::serializedEqualTo(const std::shared_ptr& lhs, + const std::shared_ptr& rhs) { + auto&& cache = *region_.getCacheImpl(); + + if (const auto primitive = + std::dynamic_pointer_cast(lhs)) { + return SerializableHelper{}.equalTo( + cache, primitive, + std::dynamic_pointer_cast(rhs)); + } else if (const auto dataSerializable = + std::dynamic_pointer_cast(lhs)) { + return SerializableHelper{}.equalTo( + cache, dataSerializable, + std::dynamic_pointer_cast(rhs)); + } else if (const auto pdxSerializable = + std::dynamic_pointer_cast(lhs)) { + return SerializableHelper{}.equalTo( + cache, pdxSerializable, + std::dynamic_pointer_cast(rhs)); + } else if (const auto dataSerializableInternal = + std::dynamic_pointer_cast(lhs)) { + return SerializableHelper{}.equalTo( + cache, dataSerializableInternal, + std::dynamic_pointer_cast(rhs)); + } else { + throw UnsupportedOperationException("Serialization type not implemented."); + } +} + +GfErrType RemoveAction::checkArgs(const std::shared_ptr& key, + const std::shared_ptr&, + DataInput*) { + if (!key) { + return GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION; + } + + return GF_NOERR; +} + +void RemoveAction::logCacheWriterFailure( + const std::shared_ptr& key, + const std::shared_ptr&) { + LOGFINER("Cache writer vetoed remove for key %s", + Utils::nullSafeToString(key).c_str()); +} + +RemoveActionEx::RemoveActionEx(LocalRegion& region) + : RemoveAction(region, true) {} + +} // namespace client +} // namespace geode +} // namespace apache diff --git a/cppcache/src/RemoveAction.hpp b/cppcache/src/RemoveAction.hpp new file mode 100644 index 0000000000..ab453754e9 --- /dev/null +++ b/cppcache/src/RemoveAction.hpp @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef GEODE_REMOVE_ACTION_H_ +#define GEODE_REMOVE_ACTION_H_ + +#include + +#include "CacheEventFlags.hpp" +#include "ErrType.hpp" +#include "EventType.hpp" + +namespace apache { +namespace geode { +namespace client { + +class CacheableKey; +class DataInput; +class EventId; +class LocalRegion; +class MapEntryImpl; +class Serializable; +class TXState; +class VersionTag; + +// encapsulates actions that need to be taken for a remove() operation +class RemoveAction { + public: + static const EntryEventType s_beforeEventType = BEFORE_DESTROY; + static const EntryEventType s_afterEventType = AFTER_DESTROY; + static const bool s_addIfAbsent = true; + static const bool s_failIfPresent = false; + + public: + explicit RemoveAction(LocalRegion& region, bool allowNull = false); + + void getCallbackOldValue(bool cachingEnabled, + const std::shared_ptr& key, + std::shared_ptr& entry, + std::shared_ptr& oldValue) const; + + GfErrType remoteUpdate(const std::shared_ptr& key, + const std::shared_ptr& newValue, + const std::shared_ptr& aCallbackArgument, + std::shared_ptr& retValue, + std::shared_ptr& versionTag); + + GfErrType localUpdate(const std::shared_ptr& key, + const std::shared_ptr& value, + std::shared_ptr& oldValue, + bool cachingEnabled, const CacheEventFlags eventFlags, + int updateCount, std::shared_ptr versionTag, + DataInput* delta = nullptr, + std::shared_ptr eventId = nullptr, + bool afterRemote = false); + + TXState* getTxState() const { return txState_; } + + public: + static const char* name() { return "Region::remove"; } + + static GfErrType checkArgs(const std::shared_ptr& key, + const std::shared_ptr& value, + DataInput* delta); + + static void logCacheWriterFailure( + const std::shared_ptr& key, + const std::shared_ptr& oldValue); + + protected: + bool serializedEqualTo(const std::shared_ptr& lhs, + const std::shared_ptr& rhs); + + protected: + LocalRegion& region_; + GfErrType response_; + TXState* txState_; + bool allowNull_; +}; + +class RemoveActionEx : public RemoveAction { + public: + explicit RemoveActionEx(LocalRegion& region); +}; + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_REMOVE_ACTION_H_ diff --git a/cppcache/src/TcrMessage.cpp b/cppcache/src/TcrMessage.cpp index a6f69d3297..321882d912 100644 --- a/cppcache/src/TcrMessage.cpp +++ b/cppcache/src/TcrMessage.cpp @@ -366,10 +366,12 @@ void TcrMessage::readBooleanPartAsObject(DataInput& input, bool* boolVal) { void TcrMessage::readOldValue(DataInput& input) { // read and ignore length - input.readInt32(); + auto size = input.readInt32(); input.read(); // ignore isObj - std::shared_ptr value; - input.readObject(value); // we are not using this value currently + + if (size > 0) { + input.readObject(m_value); // we are not using this value currently + } } void TcrMessage::readPrMetaData(DataInput& input) { @@ -1932,107 +1934,6 @@ TcrMessageInvalidate::TcrMessageInvalidate( writeMessageLength(); } -TcrMessageDestroy::TcrMessageDestroy( - DataOutput* dataOutput, const Region* region, - const std::shared_ptr& key, - const std::shared_ptr& value, bool isUserNullValue, - const std::shared_ptr& aCallbackArgument, - ThinClientBaseDM* connectionDM) { - m_request.reset(dataOutput); - m_msgType = TcrMessage::DESTROY; - m_tcdm = connectionDM; - m_key = key; - m_regionName = - (region == nullptr ? "INVALID_REGION_NAME" : region->getFullPath()); - m_region = region; - m_timeout = DEFAULT_TIMEOUT; - uint32_t numOfParts = 2; - if (aCallbackArgument != nullptr) { - ++numOfParts; - } - - numOfParts++; - - if (key == nullptr) { - throw IllegalArgumentException( - "key passed to the constructor can't be nullptr"); - } - - if (value != nullptr || isUserNullValue) { - numOfParts += 2; // for GFE Destroy65.java - writeHeader(TcrMessage::DESTROY, numOfParts); - writeRegionPart(m_regionName); - writeObjectPart(key); - writeObjectPart(value); // expectedOldValue part - uint8_t removeByte = 8; // OP_TYPE_DESTROY value from Operation.java - auto removeBytePart = CacheableByte::create(removeByte); - writeObjectPart(removeBytePart); // operation part - writeEventIdPart(); - if (aCallbackArgument != nullptr) { - writeObjectPart(aCallbackArgument); - } - writeMessageLength(); - } else { - numOfParts += 2; // for GFE Destroy65.java - writeHeader(TcrMessage::DESTROY, numOfParts); - writeRegionPart(m_regionName); - writeObjectPart(key); - writeObjectPart(nullptr); // expectedOldValue part - writeObjectPart(nullptr); // operation part - writeEventIdPart(); - if (aCallbackArgument != nullptr) { - writeObjectPart(aCallbackArgument); - } - writeMessageLength(); - } -} - -TcrMessagePut::TcrMessagePut( - DataOutput* dataOutput, const Region* region, - const std::shared_ptr& key, - const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, bool isDelta, - ThinClientBaseDM* connectionDM, bool isMetaRegion, - bool fullValueAfterDeltaFail, const char* regionName) { - m_request.reset(dataOutput); - // m_securityHeaderLength = 0; - m_isMetaRegion = isMetaRegion; - m_msgType = TcrMessage::PUT; - m_tcdm = connectionDM; - m_key = key; - m_regionName = region != nullptr ? region->getFullPath() : regionName; - m_region = region; - m_timeout = DEFAULT_TIMEOUT; - - // TODO check the number of parts in this constructor. doubt because in PUT - // value can be nullptr also. - uint32_t numOfParts = 5; - if (aCallbackArgument != nullptr) { - ++numOfParts; - } - - numOfParts++; - - if (key == nullptr) { - throw IllegalArgumentException( - "key passed to the constructor can't be nullptr"); - } - - numOfParts++; - writeHeader(m_msgType, numOfParts); - writeRegionPart(m_regionName); - writeObjectPart(nullptr); // operation = null - writeIntPart(0); // flags = 0 - writeObjectPart(key); - writeObjectPart(CacheableBoolean::create(isDelta)); - writeObjectPart(value, isDelta); - writeEventIdPart(0, fullValueAfterDeltaFail); - if (aCallbackArgument != nullptr) { - writeObjectPart(aCallbackArgument); - } - writeMessageLength(); -} - TcrMessageReply::TcrMessageReply(bool decodeAll, ThinClientBaseDM* connectionDM) { m_msgType = TcrMessage::INVALID; diff --git a/cppcache/src/TcrMessage.hpp b/cppcache/src/TcrMessage.hpp index 221d6a88c6..4340051724 100644 --- a/cppcache/src/TcrMessage.hpp +++ b/cppcache/src/TcrMessage.hpp @@ -549,18 +549,6 @@ class TcrMessageInvalidate : public TcrMessage { ~TcrMessageInvalidate() override = default; }; -class TcrMessageDestroy : public TcrMessage { - public: - TcrMessageDestroy(DataOutput* dataOutput, const Region* region, - const std::shared_ptr& key, - const std::shared_ptr& value, - bool isUserNullValue, - const std::shared_ptr& aCallbackArgument, - ThinClientBaseDM* connectionDM = nullptr); - - ~TcrMessageDestroy() override = default; -}; - class TcrMessageRegisterInterestList : public TcrMessage { public: TcrMessageRegisterInterestList( @@ -584,19 +572,6 @@ class TcrMessageUnregisterInterestList : public TcrMessage { ~TcrMessageUnregisterInterestList() override = default; }; -class TcrMessagePut : public TcrMessage { - public: - TcrMessagePut(DataOutput* dataOutput, const Region* region, - const std::shared_ptr& key, - const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, - bool isDelta = false, ThinClientBaseDM* connectionDM = nullptr, - bool isMetaRegion = false, bool fullValueAfterDeltaFail = false, - const char* regionName = nullptr); - - ~TcrMessagePut() override = default; -}; - class TcrMessageCreateRegion : public TcrMessage { public: TcrMessageCreateRegion(DataOutput* dataOutput, const std::string& str1, diff --git a/cppcache/src/TcrMessageDestroy.cpp b/cppcache/src/TcrMessageDestroy.cpp new file mode 100644 index 0000000000..909175047e --- /dev/null +++ b/cppcache/src/TcrMessageDestroy.cpp @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "TcrMessageDestroy.hpp" + +#include + +#include "Connector.hpp" +#include "EventOperation.hpp" + +namespace apache { +namespace geode { +namespace client { + +TcrMessageDestroy::TcrMessageDestroy(DataOutput* dataOutput, + const Region* region, + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + EventOperation operation, + ThinClientBaseDM* dm) { + if (!key) { + throw IllegalArgumentException( + "key passed to the constructor can't be nullptr"); + } + + m_request.reset(dataOutput); + m_msgType = TcrMessage::DESTROY; + m_tcdm = dm; + m_key = key; + m_regionName = (!region ? "INVALID_REGION_NAME" : region->getFullPath()); + m_region = region; + m_timeout = DEFAULT_TIMEOUT; + uint32_t numOfParts = 5; + if (cbArg) { + ++numOfParts; + } + + writeHeader(TcrMessage::DESTROY, numOfParts); + writeRegionPart(m_regionName); + writeObjectPart(key); + writeObjectPart(value); // expectedOldValue part + writeBytePart(static_cast(operation)); // operation part + writeEventIdPart(); + + if (cbArg) { + writeObjectPart(cbArg); + } + + writeMessageLength(); +} + +} // namespace client +} // namespace geode +} // namespace apache diff --git a/cppcache/src/TcrMessageDestroy.hpp b/cppcache/src/TcrMessageDestroy.hpp new file mode 100644 index 0000000000..f7613c1400 --- /dev/null +++ b/cppcache/src/TcrMessageDestroy.hpp @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef GEODE_TCR_MESSAGE_DESTROY_H_ +#define GEODE_TCR_MESSAGE_DESTROY_H_ + +#include +#include + +#include "EventOperation.hpp" +#include "TcrMessage.hpp" + +namespace apache { +namespace geode { +namespace client { + +class TcrMessageDestroy : public TcrMessage { + public: + TcrMessageDestroy(DataOutput* dataOutput, const Region* region, + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + EventOperation operation, + ThinClientBaseDM* dm = nullptr); + + ~TcrMessageDestroy() override = default; +}; + + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_TCR_MESSAGE_DESTROY_H_ diff --git a/cppcache/src/TcrMessagePut.cpp b/cppcache/src/TcrMessagePut.cpp new file mode 100644 index 0000000000..fc4f6a20bc --- /dev/null +++ b/cppcache/src/TcrMessagePut.cpp @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "TcrMessagePut.hpp" + +#include + +#include "Connector.hpp" + +namespace apache { +namespace geode { +namespace client { + +TcrMessagePut::TcrMessagePut(DataOutput* dataOutput, const Region* region, + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + EventOperation operation, bool isDelta, + ThinClientBaseDM* connectionDM, bool isMetaRegion, + bool fullValueAfterDeltaFail, + const std::string& regionName) { + m_request.reset(dataOutput); + m_isMetaRegion = isMetaRegion; + m_msgType = TcrMessage::PUT; + m_tcdm = connectionDM; + m_key = key; + m_regionName = region != nullptr ? region->getFullPath() : regionName; + m_region = region; + m_timeout = DEFAULT_TIMEOUT; + + // TODO check the number of parts in this constructor. doubt because in PUT + // value can be nullptr also. + uint32_t numOfParts = 5; + if (cbArg) { + ++numOfParts; + } + + numOfParts++; + + if (key == nullptr) { + throw IllegalArgumentException( + "key passed to the constructor can't be nullptr"); + } + + numOfParts++; + writeHeader(m_msgType, numOfParts); + writeRegionPart(m_regionName); + writeBytePart(static_cast(operation)); + + // Flags are not used for now + writeIntPart(0); + writeObjectPart(key); + writeObjectPart(CacheableBoolean::create(isDelta)); + writeObjectPart(value, isDelta); + writeEventIdPart(0, fullValueAfterDeltaFail); + if (cbArg) { + writeObjectPart(cbArg); + } + + writeMessageLength(); +} + +} // namespace client +} // namespace geode +} // namespace apache diff --git a/cppcache/src/TcrMessagePut.hpp b/cppcache/src/TcrMessagePut.hpp new file mode 100644 index 0000000000..13b4b2c87c --- /dev/null +++ b/cppcache/src/TcrMessagePut.hpp @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef GEODE_TCR_MESSAGE_PUT_H_ +#define GEODE_TCR_MESSAGE_PUT_H_ + +#include +#include + +#include "EventOperation.hpp" +#include "TcrMessage.hpp" + +namespace apache { +namespace geode { +namespace client { + +class TcrMessagePut : public TcrMessage { + public: + TcrMessagePut(DataOutput* dataOutput, const Region* region, + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + EventOperation operation, bool isDelta = false, + ThinClientBaseDM* connectionDM = nullptr, + bool isMetaRegion = false, bool fullValueAfterDeltaFail = false, + const std::string& regionName = std::string{}); + + ~TcrMessagePut() override = default; +}; + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_TCR_MESSAGE_PUT_H_ diff --git a/cppcache/src/ThinClientRegion.cpp b/cppcache/src/ThinClientRegion.cpp index 481887a01e..1e3c9b04c4 100644 --- a/cppcache/src/ThinClientRegion.cpp +++ b/cppcache/src/ThinClientRegion.cpp @@ -39,6 +39,8 @@ #include "TcrConnectionManager.hpp" #include "TcrDistributionManager.hpp" #include "TcrEndpoint.hpp" +#include "TcrMessageDestroy.hpp" +#include "TcrMessagePut.hpp" #include "ThinClientBaseDM.hpp" #include "ThinClientPoolDM.hpp" #include "UserAttributes.hpp" @@ -78,7 +80,7 @@ class PutAllWork : public PooledWork { bool isBGThread, const std::shared_ptr map, const std::shared_ptr>> keys, std::chrono::milliseconds timeout, - const std::shared_ptr& aCallbackArgument) + const std::shared_ptr& aCallbackArgument) : m_poolDM(poolDM), m_serverLocation(serverLocation), m_attemptFailover(attemptFailover), @@ -196,7 +198,7 @@ class RemoveAllWork : public PooledWork { bool m_isBGThread; std::shared_ptr m_userAttribute; const std::shared_ptr m_region; - const std::shared_ptr& m_aCallbackArgument; + const std::shared_ptr& m_aCallbackArgument; std::shared_ptr m_verObjPartListPtr; std::shared_ptr m_papException; ChunkedRemoveAllResponse* m_resultCollector; @@ -210,7 +212,7 @@ class RemoveAllWork : public PooledWork { const std::shared_ptr& region, bool attemptFailover, bool isBGThread, const std::shared_ptr>> keys, - const std::shared_ptr& aCallbackArgument) + const std::shared_ptr& aCallbackArgument) : m_poolDM(poolDM), m_serverLocation(serverLocation), m_attemptFailover(attemptFailover), @@ -617,7 +619,7 @@ GfErrType ThinClientRegion::unregisterKeysBeforeDestroyRegion() { err = opErr != GF_NOERR ? opErr : err; return err; } -std::shared_ptr ThinClientRegion::selectValue( +std::shared_ptr ThinClientRegion::selectValue( const std::string& predicate, std::chrono::milliseconds timeout) { auto results = query(predicate, timeout); @@ -684,7 +686,7 @@ bool ThinClientRegion::containsKeyOnServer( TcrMessageContainsKey request( new DataOutput(m_cacheImpl->createDataOutput()), this, keyPtr, - static_cast>(nullptr), true, m_tcrdm.get()); + static_cast>(nullptr), true, m_tcrdm.get()); TcrMessageReply reply(true, m_tcrdm.get()); reply.setMessageTypeRequest(TcrMessage::CONTAINS_KEY); err = m_tcrdm->sendSyncRequest(request, reply); @@ -729,8 +731,7 @@ bool ThinClientRegion::containsValueForKey_remote( TcrMessageContainsKey request( new DataOutput(m_cacheImpl->createDataOutput()), this, keyPtr, - static_cast>(nullptr), false, - m_tcrdm.get()); + static_cast>(nullptr), false, m_tcrdm.get()); TcrMessageReply reply(true, m_tcrdm.get()); reply.setMessageTypeRequest(TcrMessage::CONTAINS_KEY); err = m_tcrdm->sendSyncRequest(request, reply); @@ -767,7 +768,7 @@ bool ThinClientRegion::containsValueForKey_remote( } void ThinClientRegion::clear( - const std::shared_ptr& aCallbackArgument) { + const std::shared_ptr& aCallbackArgument) { GfErrType err = GF_NOERR; err = localClearNoThrow(aCallbackArgument, CacheEventFlags::NORMAL); if (err != GF_NOERR) throwExceptionIfError("Region::clear", err); @@ -812,7 +813,7 @@ void ThinClientRegion::clear( GfErrType ThinClientRegion::getNoThrow_remote( const std::shared_ptr& keyPtr, std::shared_ptr& valPtr, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, std::shared_ptr& versionTag) { GfErrType err = GF_NOERR; @@ -851,14 +852,14 @@ GfErrType ThinClientRegion::getNoThrow_remote( return err; } -GfErrType ThinClientRegion::invalidateNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { +GfErrType ThinClientRegion::remoteInvalidate( + const std::shared_ptr& key, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept { GfErrType err = GF_NOERR; TcrMessageInvalidate request(new DataOutput(m_cacheImpl->createDataOutput()), - this, keyPtr, aCallbackArgument, m_tcrdm.get()); + this, key, cbArg, m_tcrdm.get()); TcrMessageReply reply(true, m_tcrdm.get()); err = m_tcrdm->sendSyncRequest(request, reply); if (err != GF_NOERR) return err; @@ -870,7 +871,7 @@ GfErrType ThinClientRegion::invalidateNoThrow_remote( break; } case TcrMessage::EXCEPTION: { - err = handleServerException("Region::get", reply.getException()); + err = handleServerException("Region::invalidate", reply.getException()); break; } case TcrMessage::INVALIDATE_ERROR: { @@ -887,49 +888,63 @@ GfErrType ThinClientRegion::invalidateNoThrow_remote( return err; } -GfErrType ThinClientRegion::putNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& valuePtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag, bool checkDelta) { +GfErrType ThinClientRegion::remotePut(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag, + std::shared_ptr& retValue, + EventOperation op, + bool checkDelta) noexcept { GfErrType err = GF_NOERR; - // do TCR put - // bool delta = valuePtr->hasDelta(); + bool delta = false; - auto&& conFlationValue = getCacheImpl() + auto&& conflationValue = getCacheImpl() ->getDistributedSystem() .getSystemProperties() .conflateEvents(); - if (checkDelta && valuePtr && conFlationValue != "true" && + if (checkDelta && value && conflationValue != "true" && ThinClientBaseDM::isDeltaEnabledOnServer()) { - auto&& temp = std::dynamic_pointer_cast(valuePtr); + auto&& temp = std::dynamic_pointer_cast(value); delta = temp && temp->hasDelta(); } - TcrMessagePut request(new DataOutput(m_cacheImpl->createDataOutput()), this, - keyPtr, valuePtr, aCallbackArgument, delta, - m_tcrdm.get()); - auto reply = std::unique_ptr( - new TcrMessageReply(true, m_tcrdm.get())); - err = m_tcrdm->sendSyncRequest(request, *reply); + + std::unique_ptr reply; + { + TcrMessagePut request(new DataOutput(m_cacheImpl->createDataOutput()), this, + key, value, cbArg, op, delta, m_tcrdm.get()); + reply.reset(new TcrMessageReply(true, m_tcrdm.get())); + err = m_tcrdm->sendSyncRequest(request, *reply); + } + if (delta) { // Does not check whether success of failure.. m_cacheImpl->getCachePerfStats().incDeltaPut(); if (reply->getMessageType() == TcrMessage::PUT_DELTA_ERROR) { // Try without delta - TcrMessagePut putRequest(new DataOutput(m_cacheImpl->createDataOutput()), - this, keyPtr, valuePtr, aCallbackArgument, false, - m_tcrdm.get(), false, true); - reply = std::unique_ptr( - new TcrMessageReply(true, m_tcrdm.get())); - err = m_tcrdm->sendSyncRequest(putRequest, *reply); + TcrMessagePut request{new DataOutput(m_cacheImpl->createDataOutput()), + this, + key, + value, + cbArg, + op, + false, + m_tcrdm.get(), + false, + true}; + reply.reset(new TcrMessageReply(true, m_tcrdm.get())); + err = m_tcrdm->sendSyncRequest(request, *reply); } } - if (err != GF_NOERR) return err; + + if (err != GF_NOERR) { + return err; + } // put the object into local region switch (reply->getMessageType()) { case TcrMessage::REPLY: { versionTag = reply->getVersionTag(); + retValue = reply->getValue(); break; } case TcrMessage::EXCEPTION: { @@ -949,24 +964,25 @@ GfErrType ThinClientRegion::putNoThrow_remote( return err; } -GfErrType ThinClientRegion::createNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& valuePtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { - return putNoThrow_remote(keyPtr, valuePtr, aCallbackArgument, versionTag, - false); +GfErrType ThinClientRegion::remoteCreate( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept { + std::shared_ptr discarded; + return remotePut(key, value, cbArg, versionTag, discarded, + EventOperation::CREATE, false); } -GfErrType ThinClientRegion::destroyNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { +GfErrType ThinClientRegion::remoteDestroy( + const std::shared_ptr& key, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept { GfErrType err = GF_NOERR; // do TCR destroy TcrMessageDestroy request(new DataOutput(m_cacheImpl->createDataOutput()), - this, keyPtr, nullptr, false, aCallbackArgument, + this, key, nullptr, cbArg, EventOperation::DESTROY, m_tcrdm.get()); TcrMessageReply reply(true, m_tcrdm.get()); err = m_tcrdm->sendSyncRequest(request, reply); @@ -978,7 +994,7 @@ GfErrType ThinClientRegion::destroyNoThrow_remote( err = GF_CACHE_ENTRY_NOT_FOUND; } else { LOGDEBUG("Remote key [%s] is destroyed successfully in region %s", - Utils::nullSafeToString(keyPtr).c_str(), m_fullPath.c_str()); + Utils::nullSafeToString(key).c_str(), m_fullPath.c_str()); } versionTag = reply.getVersionTag(); break; @@ -1001,17 +1017,17 @@ GfErrType ThinClientRegion::destroyNoThrow_remote( return err; } // destroyNoThrow_remote() -GfErrType ThinClientRegion::removeNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& cvalue, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { +GfErrType ThinClientRegion::remoteRemove( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept { GfErrType err = GF_NOERR; // do TCR remove TcrMessageDestroy request(new DataOutput(m_cacheImpl->createDataOutput()), - this, keyPtr, cvalue, cvalue == nullptr, - aCallbackArgument, m_tcrdm.get()); + this, key, value, cbArg, EventOperation::REMOVE, + m_tcrdm.get()); TcrMessageReply reply(true, m_tcrdm.get()); err = m_tcrdm->sendSyncRequest(request, reply); if (err != GF_NOERR) { @@ -1023,7 +1039,7 @@ GfErrType ThinClientRegion::removeNoThrow_remote( err = GF_ENOENT; } else { LOGDEBUG("Remote key [%s] is removed successfully in region %s", - Utils::nullSafeToString(keyPtr).c_str(), m_fullPath.c_str()); + Utils::nullSafeToString(key).c_str(), m_fullPath.c_str()); } versionTag = reply.getVersionTag(); break; @@ -1045,21 +1061,22 @@ GfErrType ThinClientRegion::removeNoThrow_remote( return err; } -GfErrType ThinClientRegion::removeNoThrowEX_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) { +GfErrType ThinClientRegion::remoteRemoveEx( + const std::shared_ptr& key, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept { GfErrType err = GF_NOERR; // do TCR remove TcrMessageDestroy request(new DataOutput(m_cacheImpl->createDataOutput()), - this, keyPtr, nullptr, false, aCallbackArgument, + this, key, nullptr, cbArg, EventOperation::DESTROY, m_tcrdm.get()); TcrMessageReply reply(true, m_tcrdm.get()); err = m_tcrdm->sendSyncRequest(request, reply); if (err != GF_NOERR) { return err; } + switch (reply.getMessageType()) { case TcrMessage::REPLY: { versionTag = reply.getVersionTag(); @@ -1067,7 +1084,7 @@ GfErrType ThinClientRegion::removeNoThrowEX_remote( err = GF_ENOENT; } else { LOGDEBUG("Remote key [%s] is removed successfully in region %s", - Utils::nullSafeToString(keyPtr).c_str(), m_fullPath.c_str()); + Utils::nullSafeToString(key).c_str(), m_fullPath.c_str()); } break; } @@ -1094,8 +1111,7 @@ GfErrType ThinClientRegion::getAllNoThrow_remote( const std::shared_ptr& exceptions, const std::shared_ptr>>& resultKeys, - bool addToLocalCache, - const std::shared_ptr& aCallbackArgument) { + bool addToLocalCache, const std::shared_ptr& aCallbackArgument) { GfErrType err = GF_NOERR; MapOfUpdateCounters updateCountMap; int32_t destroyTracker = 0; @@ -1177,7 +1193,7 @@ GfErrType ThinClientRegion::singleHopPutAllNoThrow_remote( ThinClientPoolDM* tcrdm, const HashMapOfCacheable& map, std::shared_ptr& versionedObjPartList, std::chrono::milliseconds timeout, - const std::shared_ptr& aCallbackArgument) { + const std::shared_ptr& aCallbackArgument) { LOGDEBUG(" ThinClientRegion::singleHopPutAllNoThrow_remote map size = %zu", map.size()); auto region = shared_from_this(); @@ -1263,7 +1279,7 @@ GfErrType ThinClientRegion::singleHopPutAllNoThrow_remote( * a. Iterate over all vector of putAllWorkers and populate worker specific * information into the HashMap * resultMap, - * std::shared_ptr>, 2nd part, Value can be a + * std::shared_ptr>, 2nd part, Value can be a * std::shared_ptr or * std::shared_ptr. * failedServers, @@ -1479,7 +1495,7 @@ GfErrType ThinClientRegion::multiHopPutAllNoThrow_remote( const HashMapOfCacheable& map, std::shared_ptr& versionedObjPartList, std::chrono::milliseconds timeout, - const std::shared_ptr& aCallbackArgument) { + const std::shared_ptr& aCallbackArgument) { // Multiple hop implementation LOGDEBUG("ThinClientRegion::multiHopPutAllNoThrow_remote "); auto err = GF_NOERR; @@ -1545,7 +1561,7 @@ GfErrType ThinClientRegion::putAllNoThrow_remote( const HashMapOfCacheable& map, std::shared_ptr& versionedObjPartList, std::chrono::milliseconds timeout, - const std::shared_ptr& aCallbackArgument) { + const std::shared_ptr& aCallbackArgument) { LOGDEBUG("ThinClientRegion::putAllNoThrow_remote"); if (auto poolDM = std::dynamic_pointer_cast(m_tcrdm)) { @@ -1567,7 +1583,7 @@ GfErrType ThinClientRegion::singleHopRemoveAllNoThrow_remote( ThinClientPoolDM* tcrdm, const std::vector>& keys, std::shared_ptr& versionedObjPartList, - const std::shared_ptr& aCallbackArgument) { + const std::shared_ptr& aCallbackArgument) { LOGDEBUG( " ThinClientRegion::singleHopRemoveAllNoThrow_remote keys size = %zu", keys.size()); @@ -1626,7 +1642,7 @@ GfErrType ThinClientRegion::singleHopRemoveAllNoThrow_remote( * a. Iterate over all vector of putAllWorkers and populate worker specific * information into the HashMap * resultMap, - * std::shared_ptr>, 2nd part, Value can be a + * std::shared_ptr>, 2nd part, Value can be a * std::shared_ptr or * std::shared_ptr. * failedServers, @@ -1812,7 +1828,7 @@ GfErrType ThinClientRegion::singleHopRemoveAllNoThrow_remote( GfErrType ThinClientRegion::multiHopRemoveAllNoThrow_remote( const std::vector>& keys, std::shared_ptr& versionedObjPartList, - const std::shared_ptr& aCallbackArgument) { + const std::shared_ptr& aCallbackArgument) { // Multiple hop implementation LOGDEBUG("ThinClientRegion::multiHopRemoveAllNoThrow_remote "); GfErrType err = GF_NOERR; @@ -1867,7 +1883,7 @@ GfErrType ThinClientRegion::multiHopRemoveAllNoThrow_remote( GfErrType ThinClientRegion::removeAllNoThrow_remote( const std::vector>& keys, std::shared_ptr& versionedObjPartList, - const std::shared_ptr& aCallbackArgument) { + const std::shared_ptr& aCallbackArgument) { LOGDEBUG("ThinClientRegion::removeAllNoThrow_remote"); if (auto poolDM = std::dynamic_pointer_cast(m_tcrdm)) { @@ -2108,7 +2124,7 @@ GfErrType ThinClientRegion::unregisterKeys() { } GfErrType ThinClientRegion::destroyRegionNoThrow_remote( - const std::shared_ptr& aCallbackArgument) { + const std::shared_ptr& aCallbackArgument) { GfErrType err = GF_NOERR; // do TCR destroyRegion @@ -3226,7 +3242,7 @@ GfErrType ThinClientRegion::getNoThrow_FullObject( void ThinClientRegion::txDestroy( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, std::shared_ptr versionTag) { GfErrType err = destroyNoThrowTX(key, aCallbackArgument, -1, CacheEventFlags::NORMAL, versionTag); @@ -3235,7 +3251,7 @@ void ThinClientRegion::txDestroy( void ThinClientRegion::txInvalidate( const std::shared_ptr& key, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, std::shared_ptr versionTag) { GfErrType err = invalidateNoThrowTX(key, aCallbackArgument, -1, CacheEventFlags::NORMAL, versionTag); @@ -3245,7 +3261,7 @@ void ThinClientRegion::txInvalidate( void ThinClientRegion::txPut( const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, std::shared_ptr versionTag) { std::shared_ptr oldValue; int64_t sampleStartNanos = startStatOpTime(); @@ -3459,7 +3475,7 @@ void ChunkedQueryResponse::handleChunk(const uint8_t* chunk, int32_t chunkLen, int32_t arraySize = input.readArrayLength(); skipClass(input); for (int32_t arrayItem = 0; arrayItem < arraySize; ++arrayItem) { - std::shared_ptr value; + std::shared_ptr value; if (isResultSet) { input.readObject(value); m_queryResults->push_back(value); diff --git a/cppcache/src/ThinClientRegion.hpp b/cppcache/src/ThinClientRegion.hpp index 9ed4e83611..2c111bf9d0 100644 --- a/cppcache/src/ThinClientRegion.hpp +++ b/cppcache/src/ThinClientRegion.hpp @@ -28,6 +28,7 @@ #include "CacheableObjectPartList.hpp" #include "ClientMetadataService.hpp" +#include "EventOperation.hpp" #include "FunctionAttributes.hpp" #include "LocalRegion.hpp" #include "Queue.hpp" @@ -83,7 +84,7 @@ class ThinClientRegion : public LocalRegion { bool receiveValues = true) override; void unregisterRegex(const std::string& regex) override; std::vector> serverKeys() override; - void clear(const std::shared_ptr& aCallbackArgument = + void clear(const std::shared_ptr& aCallbackArgument = nullptr) override; std::shared_ptr query( @@ -95,7 +96,7 @@ class ThinClientRegion : public LocalRegion { std::chrono::milliseconds timeout = DEFAULT_QUERY_RESPONSE_TIMEOUT) override; - std::shared_ptr selectValue( + std::shared_ptr selectValue( const std::string& predicate, std::chrono::milliseconds timeout = DEFAULT_QUERY_RESPONSE_TIMEOUT) override; @@ -107,12 +108,12 @@ class ThinClientRegion : public LocalRegion { const HashMapOfCacheable& map, std::shared_ptr& versionedObjPartList, std::chrono::milliseconds timeout = DEFAULT_RESPONSE_TIMEOUT, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; GfErrType removeAllNoThrow_remote( const std::vector>& keys, std::shared_ptr& versionedObjPartList, - const std::shared_ptr& aCallbackArgument = + const std::shared_ptr& aCallbackArgument = nullptr) override; GfErrType registerKeys(TcrEndpoint* endpoint = nullptr, const TcrMessage* request = nullptr, @@ -185,14 +186,14 @@ class ThinClientRegion : public LocalRegion { uint32_t size_remote() override; void txDestroy(const std::shared_ptr& key, - const std::shared_ptr& callBack, + const std::shared_ptr& callBack, std::shared_ptr versionTag) override; void txInvalidate(const std::shared_ptr& key, - const std::shared_ptr& callBack, + const std::shared_ptr& callBack, std::shared_ptr versionTag) override; void txPut(const std::shared_ptr& key, const std::shared_ptr& value, - const std::shared_ptr& callBack, + const std::shared_ptr& callBack, std::shared_ptr versionTag) override; void clearKeysOfInterest(); @@ -201,35 +202,36 @@ class ThinClientRegion : public LocalRegion { GfErrType getNoThrow_remote( const std::shared_ptr& keyPtr, std::shared_ptr& valPtr, - const std::shared_ptr& aCallbackArgument, + const std::shared_ptr& aCallbackArgument, std::shared_ptr& versionTag) override; - GfErrType putNoThrow_remote( + GfErrType remotePut(const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag, + std::shared_ptr& retValue, EventOperation op, + bool checkDelta = true) noexcept override; + GfErrType remoteCreate( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept override; + GfErrType remoteDestroy( + const std::shared_ptr& key, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept override; + GfErrType remoteRemove( + const std::shared_ptr& key, + const std::shared_ptr& value, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept override; + GfErrType remoteRemoveEx( + const std::shared_ptr& key, + const std::shared_ptr& cbArg, + std::shared_ptr& versionTag) noexcept override; + GfErrType remoteInvalidate( const std::shared_ptr& keyPtr, - const std::shared_ptr& cvalue, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag, bool checkDelta = true) override; - GfErrType createNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& cvalue, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) override; - GfErrType destroyNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) override; - GfErrType removeNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& cvalue, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) override; - GfErrType removeNoThrowEX_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) override; - GfErrType invalidateNoThrow_remote( - const std::shared_ptr& keyPtr, - const std::shared_ptr& aCallbackArgument, - std::shared_ptr& versionTag) override; + const std::shared_ptr& aCallbackArgument, + std::shared_ptr& versionTag) noexcept override; GfErrType getAllNoThrow_remote( const std::vector>* keys, const std::shared_ptr& values, @@ -237,9 +239,9 @@ class ThinClientRegion : public LocalRegion { const std::shared_ptr>>& resultKeys, bool addToLocalCache, - const std::shared_ptr& aCallbackArgument) override; + const std::shared_ptr& aCallbackArgument) override; GfErrType destroyRegionNoThrow_remote( - const std::shared_ptr& aCallbackArgument) override; + const std::shared_ptr& aCallbackArgument) override; GfErrType registerKeysNoThrow( const std::vector>& keys, bool attemptFailover = true, TcrEndpoint* endpoint = nullptr, @@ -326,7 +328,7 @@ class ThinClientRegion : public LocalRegion { GfErrType createOnServer( const std::shared_ptr& keyPtr, const std::shared_ptr& cvalue, - const std::shared_ptr& aCallbackArgument); + const std::shared_ptr& aCallbackArgument); GfErrType getNoThrow_FullObject( std::shared_ptr eventId, std::shared_ptr& fullObject, std::shared_ptr& versionTag) override; @@ -335,28 +337,28 @@ class ThinClientRegion : public LocalRegion { ThinClientPoolDM* tcrdm, const HashMapOfCacheable& map, std::shared_ptr& versionedObjPartList, std::chrono::milliseconds timeout = DEFAULT_RESPONSE_TIMEOUT, - const std::shared_ptr& aCallbackArgument = nullptr); + const std::shared_ptr& aCallbackArgument = nullptr); GfErrType multiHopPutAllNoThrow_remote( const HashMapOfCacheable& map, std::shared_ptr& versionedObjPartList, std::chrono::milliseconds timeout = DEFAULT_RESPONSE_TIMEOUT, - const std::shared_ptr& aCallbackArgument = nullptr); + const std::shared_ptr& aCallbackArgument = nullptr); GfErrType singleHopRemoveAllNoThrow_remote( ThinClientPoolDM* tcrdm, const std::vector>& keys, std::shared_ptr& versionedObjPartList, - const std::shared_ptr& aCallbackArgument = nullptr); + const std::shared_ptr& aCallbackArgument = nullptr); GfErrType multiHopRemoveAllNoThrow_remote( const std::vector>& keys, std::shared_ptr& versionedObjPartList, - const std::shared_ptr& aCallbackArgument = nullptr); + const std::shared_ptr& aCallbackArgument = nullptr); boost::shared_mutex region_mutex_; bool m_isMetaDataRefreshed; typedef std::unordered_map< - std::shared_ptr, std::shared_ptr, + std::shared_ptr, std::shared_ptr, dereference_hash>, dereference_equal_to>> ResultMap; diff --git a/cppcache/test/TcrMessageTest.cpp b/cppcache/test/TcrMessageTest.cpp index 34d8b1b1d4..af1d6afe99 100644 --- a/cppcache/test/TcrMessageTest.cpp +++ b/cppcache/test/TcrMessageTest.cpp @@ -15,7 +15,6 @@ * limitations under the License. */ -#include #include #include @@ -26,6 +25,9 @@ #include "ByteArrayFixture.hpp" #include "FunctionAttributes.hpp" #include "SerializationRegistry.hpp" +#include "TcrMessage.hpp" +#include "TcrMessageDestroy.hpp" +#include "TcrMessagePut.hpp" namespace { @@ -36,6 +38,7 @@ using apache::geode::client::CacheableString; using apache::geode::client::CacheableVector; using apache::geode::client::CqState; using apache::geode::client::DataOutput; +using apache::geode::client::EventOperation; using apache::geode::client::FunctionAttributes; using apache::geode::client::InterestResultPolicy; using apache::geode::client::Region; @@ -260,22 +263,35 @@ TEST_F(TcrMessageTest, testConstructor2WithREQUEST) { message); } -TEST_F(TcrMessageTest, testConstructor2WithDestroy) { +TEST_F(TcrMessageTest, testDestroy) { using apache::geode::client::TcrMessageDestroy; - TcrMessageDestroy message( - new DataOutputUnderTest(), static_cast(nullptr), - CacheableString::create("mykey"), - static_cast>(nullptr), true, - static_cast>(nullptr), - static_cast(nullptr)); + TcrMessageDestroy message(new DataOutputUnderTest(), nullptr, + CacheableString::create("mykey"), nullptr, nullptr, + EventOperation::DESTROY, nullptr); EXPECT_EQ(TcrMessage::DESTROY, message.getMessageType()); EXPECT_MESSAGE_EQ( - "000000090000004900000005FFFFFFFF000000001300494E56414C49445F524547494F4E" - "5F4E414D4500000008015700056D796B6579000000010129000000020137080000001200" - "03000000000000000103\\h{16}", + "000000090000004800000005FFFFFFFF000000001300494E56414C49445F524547494F4E" + "5F4E414D4500000008015700056D796B6579000000010129000000010013000000120003" + "000000000000000103\\h{16}", + message); +} + +TEST_F(TcrMessageTest, testRemove) { + using apache::geode::client::TcrMessageDestroy; + + TcrMessageDestroy message(new DataOutputUnderTest(), nullptr, + CacheableString::create("mykey"), nullptr, nullptr, + EventOperation::REMOVE, nullptr); + + EXPECT_EQ(TcrMessage::DESTROY, message.getMessageType()); + + EXPECT_MESSAGE_EQ( + "000000090000004800000005FFFFFFFF000000001300494E56414C49445F524547494F4E" + "5F4E414D4500000008015700056D796B657900000001012900000001002E000000120003" + "000000000000000103\\h{16}", message); } @@ -299,24 +315,74 @@ TEST_F(TcrMessageTest, testConstructor2WithInvalidate) { message); } -TEST_F(TcrMessageTest, testConstructor3WithPut) { +TEST_F(TcrMessageTest, testPut) { using apache::geode::client::TcrMessagePut; TcrMessagePut message( - new DataOutputUnderTest(), static_cast(nullptr), - CacheableString::create("mykey"), CacheableString::create("myvalue"), - static_cast>(nullptr), - false, // isDelta - static_cast(nullptr), - false, // isMetaRegion - false, // fullValueAfterDeltaFail - "myRegionName"); + new DataOutputUnderTest(), nullptr, CacheableString::create("mykey"), + CacheableString::create("myvalue"), nullptr, EventOperation::UPDATE, + false, nullptr, false, false, "myRegionName"); + + EXPECT_EQ(TcrMessage::PUT, message.getMessageType()); + + EXPECT_MESSAGE_EQ( + "000000070000005A00000007FFFFFFFF000000000C006D79526567696F6E4E616D650000" + "0001000C00000004000000000000000008015700056D796B657900000002013500000000" + "0A015700076D7976616C7565000000120003000000000000000103\\h" + "{16}", + message); +} + +TEST_F(TcrMessageTest, testPutIfAbsent) { + using apache::geode::client::TcrMessagePut; + + TcrMessagePut message(new DataOutputUnderTest(), nullptr, + CacheableString::create("mykey"), + CacheableString::create("myvalue"), nullptr, + EventOperation::PUT_IF_ABSENT, false, nullptr, false, + false, "myRegionName"); + + EXPECT_EQ(TcrMessage::PUT, message.getMessageType()); + + EXPECT_MESSAGE_EQ( + "000000070000005A00000007FFFFFFFF000000000C006D79526567696F6E4E616D650000" + "0001002C00000004000000000000000008015700056D796B657900000002013500000000" + "0A015700076D7976616C7565000000120003000000000000000103\\h" + "{16}", + message); +} + +TEST_F(TcrMessageTest, testCreate) { + using apache::geode::client::TcrMessagePut; + + TcrMessagePut message( + new DataOutputUnderTest(), nullptr, CacheableString::create("mykey"), + CacheableString::create("myvalue"), nullptr, EventOperation::CREATE, + false, nullptr, false, false, "myRegionName"); + + EXPECT_EQ(TcrMessage::PUT, message.getMessageType()); + + EXPECT_MESSAGE_EQ( + "000000070000005A00000007FFFFFFFF000000000C006D79526567696F6E4E616D650000" + "0001000100000004000000000000000008015700056D796B657900000002013500000000" + "0A015700076D7976616C7565000000120003000000000000000103\\h" + "{16}", + message); +} + +TEST_F(TcrMessageTest, testReplace) { + using apache::geode::client::TcrMessagePut; + + TcrMessagePut message( + new DataOutputUnderTest(), nullptr, CacheableString::create("mykey"), + CacheableString::create("myvalue"), nullptr, EventOperation::REPLACE, + false, nullptr, false, false, "myRegionName"); EXPECT_EQ(TcrMessage::PUT, message.getMessageType()); EXPECT_MESSAGE_EQ( "000000070000005A00000007FFFFFFFF000000000C006D79526567696F6E4E616D650000" - "0001012900000004000000000000000008015700056D796B657900000002013500000000" + "0001002D00000004000000000000000008015700056D796B657900000002013500000000" "0A015700076D7976616C7565000000120003000000000000000103\\h" "{16}", message);