| /* |
| * 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 <cstdlib> |
| #include <string> |
| |
| #include <ace/DLL.h> |
| |
| #include <geode/Cache.hpp> |
| #include <geode/DataInput.hpp> |
| #include <geode/DataOutput.hpp> |
| #include <geode/PersistenceManager.hpp> |
| #include <geode/Properties.hpp> |
| |
| #include "CacheXmlParser.hpp" |
| #include "Utils.hpp" |
| |
| namespace apache { |
| namespace geode { |
| namespace client { |
| |
| RegionAttributes::RegionAttributes() |
| : Serializable(), |
| m_regionTimeToLiveExpirationAction(ExpirationAction::INVALIDATE), |
| m_regionIdleTimeoutExpirationAction(ExpirationAction::INVALIDATE), |
| m_entryTimeToLiveExpirationAction(ExpirationAction::INVALIDATE), |
| m_entryIdleTimeoutExpirationAction(ExpirationAction::INVALIDATE), |
| m_lruEvictionAction(ExpirationAction::LOCAL_DESTROY), |
| m_lruEntriesLimit(0), |
| m_caching(true), |
| m_maxValueDistLimit(100 * 1024), |
| m_entryIdleTimeout(0), |
| m_entryTimeToLive(0), |
| m_regionIdleTimeout(0), |
| m_regionTimeToLive(0), |
| m_initialCapacity(10000), |
| m_loadFactor(0.75), |
| m_concurrencyLevel(16), |
| m_diskPolicy(DiskPolicyType::NONE), |
| m_clientNotificationEnabled(false), |
| m_persistenceProperties(nullptr), |
| m_persistenceManager(nullptr), |
| m_isClonable(false), |
| m_isConcurrencyChecksEnabled(true) {} |
| |
| RegionAttributes::~RegionAttributes() noexcept = default; |
| |
| namespace impl { |
| |
| /** |
| * lib should be in the form required by ACE_DLL, typically just like specifying |
| * a |
| * lib in java System.loadLibrary( "x" ); Where x is a component of the name |
| * lib<x>.so on unix, or <x>.dll on windows. |
| */ |
| void* getFactoryFunc(const std::string& lib, const std::string& funcName) { |
| ACE_DLL dll; |
| if (dll.open(lib.c_str(), ACE_DEFAULT_SHLIB_MODE, 0) == -1) { |
| throw IllegalArgumentException("cannot open library: " + lib); |
| } |
| void* func = dll.symbol(funcName.c_str()); |
| if (func == nullptr) { |
| throw IllegalArgumentException("cannot find factory function " + funcName + |
| " in library " + lib); |
| } |
| return func; |
| } |
| |
| } // namespace impl |
| |
| std::shared_ptr<CacheLoader> RegionAttributes::getCacheLoader() const { |
| if (!m_cacheLoader && !m_cacheLoaderLibrary.empty()) { |
| if (CacheXmlParser::managedCacheLoaderFn && |
| m_cacheLoaderFactory.find('.') != std::string::npos) { |
| // this is a managed library |
| m_cacheLoader.reset((*CacheXmlParser::managedCacheLoaderFn)( |
| m_cacheLoaderLibrary.c_str(), m_cacheLoaderFactory.c_str())); |
| } else { |
| CacheLoader* (*funcptr)(); |
| funcptr = reinterpret_cast<CacheLoader* (*)()>( |
| apache::geode::client::impl::getFactoryFunc(m_cacheLoaderLibrary, |
| m_cacheLoaderFactory)); |
| m_cacheLoader.reset(funcptr()); |
| } |
| } |
| return m_cacheLoader; |
| } |
| |
| std::shared_ptr<CacheWriter> RegionAttributes::getCacheWriter() const { |
| if (!m_cacheWriter && !m_cacheWriterLibrary.empty()) { |
| if (CacheXmlParser::managedCacheWriterFn && |
| m_cacheWriterFactory.find('.') != std::string::npos) { |
| // this is a managed library |
| m_cacheWriter.reset((*CacheXmlParser::managedCacheWriterFn)( |
| m_cacheWriterLibrary.c_str(), m_cacheWriterFactory.c_str())); |
| } else { |
| CacheWriter* (*funcptr)(); |
| funcptr = reinterpret_cast<CacheWriter* (*)()>( |
| apache::geode::client::impl::getFactoryFunc(m_cacheWriterLibrary, |
| m_cacheWriterFactory)); |
| m_cacheWriter.reset(funcptr()); |
| } |
| } |
| return m_cacheWriter; |
| } |
| |
| std::shared_ptr<CacheListener> RegionAttributes::getCacheListener() const { |
| if (!m_cacheListener && !m_cacheListenerLibrary.empty()) { |
| if (CacheXmlParser::managedCacheListenerFn && |
| m_cacheListenerFactory.find('.') != std::string::npos) { |
| // this is a managed library |
| m_cacheListener.reset((*CacheXmlParser::managedCacheListenerFn)( |
| m_cacheListenerLibrary.c_str(), m_cacheListenerFactory.c_str())); |
| } else { |
| CacheListener* (*funcptr)(); |
| funcptr = reinterpret_cast<CacheListener* (*)()>( |
| apache::geode::client::impl::getFactoryFunc(m_cacheListenerLibrary, |
| m_cacheListenerFactory)); |
| m_cacheListener.reset(funcptr()); |
| } |
| } |
| return m_cacheListener; |
| } |
| |
| std::shared_ptr<PartitionResolver> RegionAttributes::getPartitionResolver() |
| const { |
| if (!m_partitionResolver && !m_partitionResolverLibrary.empty()) { |
| if (CacheXmlParser::managedPartitionResolverFn && |
| m_partitionResolverFactory.find('.') != std::string::npos) { |
| // this is a managed library |
| m_partitionResolver.reset((*CacheXmlParser::managedPartitionResolverFn)( |
| m_partitionResolverLibrary.c_str(), |
| m_partitionResolverFactory.c_str())); |
| } else { |
| PartitionResolver* (*funcptr)(); |
| funcptr = reinterpret_cast<PartitionResolver* (*)()>( |
| apache::geode::client::impl::getFactoryFunc( |
| m_partitionResolverLibrary, m_partitionResolverFactory)); |
| m_partitionResolver.reset(funcptr()); |
| } |
| } |
| return m_partitionResolver; |
| } |
| |
| std::shared_ptr<PersistenceManager> RegionAttributes::getPersistenceManager() |
| const { |
| if (!m_persistenceManager && !m_persistenceLibrary.empty()) { |
| if (CacheXmlParser::managedPartitionResolverFn && |
| m_persistenceFactory.find('.') != std::string::npos) { |
| // this is a managed library |
| m_persistenceManager.reset((*CacheXmlParser::managedPersistenceManagerFn)( |
| m_persistenceLibrary.c_str(), m_persistenceFactory.c_str())); |
| } else { |
| PersistenceManager* (*funcptr)(); |
| funcptr = reinterpret_cast<PersistenceManager* (*)()>( |
| apache::geode::client::impl::getFactoryFunc(m_persistenceLibrary, |
| m_persistenceFactory)); |
| m_persistenceManager.reset(funcptr()); |
| } |
| } |
| return m_persistenceManager; |
| } |
| |
| const std::string& RegionAttributes::getCacheLoaderFactory() const { |
| return m_cacheLoaderFactory; |
| } |
| |
| const std::string& RegionAttributes::getCacheWriterFactory() const { |
| return m_cacheWriterFactory; |
| } |
| |
| const std::string& RegionAttributes::getCacheListenerFactory() const { |
| return m_cacheListenerFactory; |
| } |
| |
| const std::string& RegionAttributes::getPartitionResolverFactory() const { |
| return m_partitionResolverFactory; |
| } |
| |
| const std::string& RegionAttributes::getPersistenceFactory() const { |
| return m_persistenceFactory; |
| } |
| const std::string& RegionAttributes::getCacheLoaderLibrary() const { |
| return m_cacheLoaderLibrary; |
| } |
| |
| const std::string& RegionAttributes::getCacheWriterLibrary() const { |
| return m_cacheWriterLibrary; |
| } |
| |
| const std::string& RegionAttributes::getCacheListenerLibrary() const { |
| return m_cacheListenerLibrary; |
| } |
| |
| const std::string& RegionAttributes::getPartitionResolverLibrary() const { |
| return m_partitionResolverLibrary; |
| } |
| |
| const std::string& RegionAttributes::getEndpoints() const { |
| return m_endpoints; |
| } |
| |
| bool RegionAttributes::getClientNotificationEnabled() const { |
| return m_clientNotificationEnabled; |
| } |
| |
| const std::string& RegionAttributes::getPersistenceLibrary() const { |
| return m_persistenceLibrary; |
| } |
| |
| std::shared_ptr<Properties> RegionAttributes::getPersistenceProperties() const { |
| return m_persistenceProperties; |
| } |
| |
| std::chrono::seconds RegionAttributes::getRegionTimeToLive() const { |
| return m_regionTimeToLive; |
| } |
| |
| ExpirationAction RegionAttributes::getRegionTimeToLiveAction() const { |
| return m_regionTimeToLiveExpirationAction; |
| } |
| |
| std::chrono::seconds RegionAttributes::getRegionIdleTimeout() const { |
| return m_regionIdleTimeout; |
| } |
| |
| ExpirationAction RegionAttributes::getRegionIdleTimeoutAction() const { |
| return m_regionIdleTimeoutExpirationAction; |
| } |
| |
| std::chrono::seconds RegionAttributes::getEntryTimeToLive() const { |
| return m_entryTimeToLive; |
| } |
| |
| ExpirationAction RegionAttributes::getEntryTimeToLiveAction() const { |
| return m_entryTimeToLiveExpirationAction; |
| } |
| |
| std::chrono::seconds RegionAttributes::getEntryIdleTimeout() const { |
| return m_entryIdleTimeout; |
| } |
| |
| ExpirationAction RegionAttributes::getEntryIdleTimeoutAction() const { |
| return m_entryIdleTimeoutExpirationAction; |
| } |
| |
| int RegionAttributes::getInitialCapacity() const { return m_initialCapacity; } |
| |
| float RegionAttributes::getLoadFactor() const { return m_loadFactor; } |
| |
| uint8_t RegionAttributes::getConcurrencyLevel() const { |
| return m_concurrencyLevel; |
| } |
| |
| ExpirationAction RegionAttributes::getLruEvictionAction() const { |
| return m_lruEvictionAction; |
| } |
| |
| uint32_t RegionAttributes::getLruEntriesLimit() const { |
| return m_lruEntriesLimit; |
| } |
| |
| DiskPolicyType RegionAttributes::getDiskPolicy() const { return m_diskPolicy; } |
| |
| std::shared_ptr<Serializable> RegionAttributes::createDeserializable() { |
| return std::make_shared<RegionAttributes>(); |
| } |
| |
| namespace impl { |
| |
| void writeBool(DataOutput& out, bool field) { |
| out.write(static_cast<int8_t>(field ? 1 : 0)); |
| } |
| |
| void readBool(DataInput& in, bool* field) { *field = in.read() ? true : false; } |
| |
| void writeString(DataOutput& out, const std::string& field) { |
| out.writeBytes(reinterpret_cast<int8_t*>(const_cast<char*>(field.c_str())), |
| static_cast<uint32_t>(field.length()) + 1); |
| } |
| |
| void readString(DataInput& in, std::string& field) { |
| // length including null terminator |
| auto len = in.readArrayLength(); |
| // currentBufferPosition is read-only and we are only reading, cast away const |
| field = std::string(const_cast<char*>(reinterpret_cast<const char*>( |
| in.currentBufferPosition())), |
| len - 1); |
| in.advanceCursor(len); |
| } |
| |
| } // namespace impl |
| |
| void RegionAttributes::toData(DataOutput& out) const { |
| out.writeInt(static_cast<int32_t>(m_regionTimeToLive.count())); |
| out.writeInt(static_cast<int32_t>(m_regionTimeToLiveExpirationAction)); |
| out.writeInt(static_cast<int32_t>(m_regionIdleTimeout.count())); |
| out.writeInt(static_cast<int32_t>(m_regionIdleTimeoutExpirationAction)); |
| out.writeInt(static_cast<int32_t>(m_entryTimeToLive.count())); |
| out.writeInt(static_cast<int32_t>(m_entryTimeToLiveExpirationAction)); |
| out.writeInt(static_cast<int32_t>(m_entryIdleTimeout.count())); |
| out.writeInt(static_cast<int32_t>(m_entryIdleTimeoutExpirationAction)); |
| out.writeInt(static_cast<int32_t>(m_initialCapacity)); |
| out.writeFloat(m_loadFactor); |
| out.writeInt(static_cast<int32_t>(m_maxValueDistLimit)); |
| out.writeInt(static_cast<int32_t>(m_concurrencyLevel)); |
| out.writeInt(static_cast<int32_t>(m_lruEntriesLimit)); |
| out.writeInt(static_cast<int32_t>(m_lruEvictionAction)); |
| |
| apache::geode::client::impl::writeBool(out, m_caching); |
| apache::geode::client::impl::writeBool(out, m_clientNotificationEnabled); |
| |
| apache::geode::client::impl::writeString(out, m_cacheLoaderLibrary); |
| apache::geode::client::impl::writeString(out, m_cacheLoaderFactory); |
| apache::geode::client::impl::writeString(out, m_cacheWriterLibrary); |
| apache::geode::client::impl::writeString(out, m_cacheWriterFactory); |
| apache::geode::client::impl::writeString(out, m_cacheListenerLibrary); |
| apache::geode::client::impl::writeString(out, m_cacheListenerFactory); |
| apache::geode::client::impl::writeString(out, m_partitionResolverLibrary); |
| apache::geode::client::impl::writeString(out, m_partitionResolverFactory); |
| out.writeInt(static_cast<int32_t>(m_diskPolicy)); |
| apache::geode::client::impl::writeString(out, m_endpoints); |
| apache::geode::client::impl::writeString(out, m_persistenceLibrary); |
| apache::geode::client::impl::writeString(out, m_persistenceFactory); |
| out.writeObject(m_persistenceProperties); |
| apache::geode::client::impl::writeString(out, m_poolName); |
| apache::geode::client::impl::writeBool(out, m_isConcurrencyChecksEnabled); |
| } |
| |
| void RegionAttributes::fromData(DataInput& in) { |
| m_regionTimeToLive = std::chrono::seconds(in.readInt32()); |
| m_regionTimeToLiveExpirationAction = |
| static_cast<ExpirationAction>(in.readInt32()); |
| m_regionIdleTimeout = std::chrono::seconds(in.readInt32()); |
| m_regionIdleTimeoutExpirationAction = |
| static_cast<ExpirationAction>(in.readInt32()); |
| m_entryTimeToLive = std::chrono::seconds(in.readInt32()); |
| m_entryTimeToLiveExpirationAction = |
| static_cast<ExpirationAction>(in.readInt32()); |
| m_entryIdleTimeout = std::chrono::seconds(in.readInt32()); |
| m_entryIdleTimeoutExpirationAction = |
| static_cast<ExpirationAction>(in.readInt32()); |
| m_initialCapacity = in.readInt32(); |
| m_loadFactor = in.readFloat(); |
| m_maxValueDistLimit = in.readInt32(); |
| m_concurrencyLevel = in.readInt32(); |
| m_lruEntriesLimit = in.readInt32(); |
| m_lruEvictionAction = static_cast<ExpirationAction>(in.readInt32()); |
| |
| apache::geode::client::impl::readBool(in, &m_caching); |
| apache::geode::client::impl::readBool(in, &m_clientNotificationEnabled); |
| |
| apache::geode::client::impl::readString(in, m_cacheLoaderLibrary); |
| apache::geode::client::impl::readString(in, m_cacheLoaderFactory); |
| apache::geode::client::impl::readString(in, m_cacheWriterLibrary); |
| apache::geode::client::impl::readString(in, m_cacheWriterFactory); |
| apache::geode::client::impl::readString(in, m_cacheListenerLibrary); |
| apache::geode::client::impl::readString(in, m_cacheListenerFactory); |
| apache::geode::client::impl::readString(in, m_partitionResolverLibrary); |
| apache::geode::client::impl::readString(in, m_partitionResolverFactory); |
| m_diskPolicy = static_cast<DiskPolicyType>(in.readInt32()); |
| apache::geode::client::impl::readString(in, m_endpoints); |
| apache::geode::client::impl::readString(in, m_persistenceLibrary); |
| apache::geode::client::impl::readString(in, m_persistenceFactory); |
| m_persistenceProperties = |
| std::dynamic_pointer_cast<Properties>(in.readObject()); |
| apache::geode::client::impl::readString(in, m_poolName); |
| apache::geode::client::impl::readBool(in, &m_isConcurrencyChecksEnabled); |
| } |
| |
| /** Return true if all the attributes are equal to those of other. */ |
| bool RegionAttributes::operator==(const RegionAttributes& other) const { |
| if (m_regionTimeToLive != other.m_regionTimeToLive) return false; |
| if (m_regionTimeToLiveExpirationAction != |
| other.m_regionTimeToLiveExpirationAction) { |
| return false; |
| } |
| if (m_regionIdleTimeout != other.m_regionIdleTimeout) return false; |
| if (m_regionIdleTimeoutExpirationAction != |
| other.m_regionIdleTimeoutExpirationAction) { |
| return false; |
| } |
| if (m_entryTimeToLive != other.m_entryTimeToLive) return false; |
| if (m_entryTimeToLiveExpirationAction != |
| other.m_entryTimeToLiveExpirationAction) { |
| return false; |
| } |
| if (m_entryIdleTimeout != other.m_entryIdleTimeout) return false; |
| if (m_entryIdleTimeoutExpirationAction != |
| other.m_entryIdleTimeoutExpirationAction) { |
| return false; |
| } |
| if (m_initialCapacity != other.m_initialCapacity) return false; |
| if (m_loadFactor != other.m_loadFactor) return false; |
| if (m_maxValueDistLimit != other.m_maxValueDistLimit) return false; |
| if (m_concurrencyLevel != other.m_concurrencyLevel) return false; |
| if (m_lruEntriesLimit != other.m_lruEntriesLimit) return false; |
| if (m_lruEvictionAction != other.m_lruEvictionAction) return false; |
| if (m_caching != other.m_caching) return false; |
| if (m_clientNotificationEnabled != other.m_clientNotificationEnabled) { |
| return false; |
| } |
| |
| if (m_cacheLoaderLibrary != other.m_cacheLoaderLibrary) { |
| return false; |
| } |
| if (m_cacheLoaderFactory != other.m_cacheLoaderFactory) { |
| return false; |
| } |
| if (m_cacheWriterLibrary != other.m_cacheWriterLibrary) { |
| return false; |
| } |
| if (m_cacheWriterFactory != other.m_cacheWriterFactory) { |
| return false; |
| } |
| if (m_cacheListenerLibrary != other.m_cacheListenerLibrary) { |
| return false; |
| } |
| if (m_cacheListenerFactory != other.m_cacheListenerFactory) { |
| return false; |
| } |
| if (m_partitionResolverLibrary != other.m_partitionResolverLibrary) { |
| return false; |
| } |
| if (m_partitionResolverFactory != other.m_partitionResolverFactory) { |
| return false; |
| } |
| if (m_diskPolicy != other.m_diskPolicy) { |
| return false; |
| } |
| if (m_endpoints != other.m_endpoints) { |
| return false; |
| } |
| if (m_persistenceLibrary != other.m_persistenceLibrary) { |
| return false; |
| } |
| if (m_persistenceFactory != other.m_persistenceFactory) { |
| return false; |
| } |
| if (m_isConcurrencyChecksEnabled != other.m_isConcurrencyChecksEnabled) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** Return true if any of the attributes are not equal to those of other. */ |
| bool RegionAttributes::operator!=(const RegionAttributes& other) const { |
| return !(*this == other); |
| } |
| |
| /* Throws IllegalStateException when attributes targetted for use on a server do |
| * not meet requirements. */ |
| void RegionAttributes::validateSerializableAttributes() { |
| if (m_cacheLoader != nullptr) { |
| throw IllegalStateException( |
| "CacheLoader must be set with setCacheLoader(library, factory) in " |
| "members of type SERVER"); |
| } |
| if (m_cacheWriter != nullptr) { |
| throw IllegalStateException( |
| "CacheWriter must be set with setCacheWriter(library, factory) in " |
| "members of type SERVER"); |
| } |
| if (m_cacheListener != nullptr) { |
| throw IllegalStateException( |
| "CacheListener must be set with setCacheListener(library, factory) in " |
| "members of type SERVER"); |
| } |
| if (m_partitionResolver != nullptr) { |
| throw IllegalStateException( |
| "PartitionResolver must be set with setPartitionResolver(library, " |
| "factory) in members of type SERVER"); |
| } |
| if (m_persistenceManager != nullptr) { |
| throw IllegalStateException( |
| "persistenceManager must be set with setPersistenceManager(library, " |
| "factory,config) in members of type SERVER"); |
| } |
| } |
| |
| void RegionAttributes::setCacheListener(const std::string& lib, |
| const std::string& func) { |
| m_cacheListenerLibrary = lib; |
| m_cacheListenerFactory = func; |
| } |
| |
| void RegionAttributes::setPartitionResolver(const std::string& lib, |
| const std::string& func) { |
| m_partitionResolverLibrary = lib; |
| m_partitionResolverFactory = func; |
| } |
| |
| void RegionAttributes::setCacheLoader(const std::string& lib, |
| const std::string& func) { |
| m_cacheLoaderLibrary = lib; |
| m_cacheLoaderFactory = func; |
| } |
| |
| void RegionAttributes::setCacheWriter(const std::string& lib, |
| const std::string& func) { |
| m_cacheWriterLibrary = lib; |
| m_cacheWriterFactory = func; |
| } |
| |
| void RegionAttributes::setPersistenceManager( |
| const std::string& lib, const std::string& func, |
| const std::shared_ptr<Properties>& config) { |
| m_persistenceLibrary = lib; |
| m_persistenceFactory = func; |
| m_persistenceProperties = config; |
| } |
| |
| void RegionAttributes::setEndpoints(const std::string& endpoints) { |
| m_endpoints = endpoints; |
| } |
| |
| void RegionAttributes::setPoolName(const std::string& poolName) { |
| m_poolName = poolName; |
| } |
| |
| void RegionAttributes::setCachingEnabled(bool enable) { m_caching = enable; } |
| |
| void RegionAttributes::setLruEntriesLimit(int limit) { |
| m_lruEntriesLimit = limit; |
| } |
| void RegionAttributes::setDiskPolicy(DiskPolicyType diskPolicy) { |
| m_diskPolicy = diskPolicy; |
| } |
| |
| void RegionAttributes::setCloningEnabled(bool isClonable) { |
| m_isClonable = isClonable; |
| } |
| |
| void RegionAttributes::setConcurrencyChecksEnabled(bool enable) { |
| m_isConcurrencyChecksEnabled = enable; |
| } |
| |
| } // namespace client |
| } // namespace geode |
| } // namespace apache |