Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id EA1AF200C22 for ; Tue, 21 Feb 2017 18:40:23 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id E8B61160B4F; Tue, 21 Feb 2017 17:40:23 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 6F413160B82 for ; Tue, 21 Feb 2017 18:40:20 +0100 (CET) Received: (qmail 14683 invoked by uid 500); 21 Feb 2017 17:40:18 -0000 Mailing-List: contact commits-help@geode.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.apache.org Delivered-To: mailing list commits@geode.apache.org Received: (qmail 12705 invoked by uid 99); 21 Feb 2017 17:40:15 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Feb 2017 17:40:15 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 1FCDEE004D; Tue, 21 Feb 2017 17:40:15 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jbarrett@apache.org To: commits@geode.apache.org Date: Tue, 21 Feb 2017 17:40:42 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [29/31] geode-native git commit: GEODE-2476: Replace gfcpp with geode. archived-at: Tue, 21 Feb 2017 17:40:24 -0000 http://git-wip-us.apache.org/repos/asf/geode-native/blob/fd58b100/src/cppcache/include/geode/CacheFactory.hpp ---------------------------------------------------------------------- diff --git a/src/cppcache/include/geode/CacheFactory.hpp b/src/cppcache/include/geode/CacheFactory.hpp new file mode 100644 index 0000000..d935a33 --- /dev/null +++ b/src/cppcache/include/geode/CacheFactory.hpp @@ -0,0 +1,505 @@ +#pragma once + +#ifndef GEODE_CACHEFACTORY_H_ +#define GEODE_CACHEFACTORY_H_ + +/* + * 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 "geode_globals.hpp" +#include "gf_types.hpp" +#include "DistributedSystem.hpp" +#include "Cache.hpp" +#include "CacheAttributes.hpp" +#include "PoolFactory.hpp" +/** + * @file + */ + +#define DEFAULT_POOL_NAME "default_geodeClientPool" + +namespace apache { +namespace geode { +namespace client { + +class CppCacheLibrary; +/** + * @class CacheFactory CacheFactory.hpp + * Top level class for configuring and using Geode on a client.This should be + *called once to create {@link Cache}. + *

+ * For the default values for the pool attributes see {@link PoolFactory}. + * To create additional {@link Pool}s see {@link PoolManager} + */ +class CPPCACHE_EXPORT CacheFactory : public SharedBase { + public: + /** + * To create the instance of {@link CacheFactory} + * @param dsProps + * Properties which are applicable at client level. + */ + static CacheFactoryPtr createCacheFactory( + const PropertiesPtr& dsProps = NULLPTR); + + /** + * To create the instance of {@link Cache}. + */ + CachePtr create(); + + /** + * Gets the instance of {@link Cache} produced by an + * earlier call to {@link CacheFactory::create}. + * @param system the DistributedSystem the cache was created + * with. + * @return the {@link Cache} associated with the specified system. + * @throws CacheClosedException if a cache has not been created + * or the created one is {@link Cache::isClosed closed} + * @throws EntryNotFoundException if a cache with specified system not found + */ + static CachePtr getInstance(const DistributedSystemPtr& system); + + /** + * Gets the instance of {@link Cache} produced by an + * earlier call to {@link CacheFactory::create}, even if it has been closed. + * @param system the DistributedSystem the cache was created + * with. + * @return the {@link Cache} associated with the specified system. + * @throws CacheClosedException if a cache has not been created + * @throws EntryNotFoundException if a cache with specified system is not + * found + */ + static CachePtr getInstanceCloseOk(const DistributedSystemPtr& system); + + /** + * Gets an arbitrary open instance of {@link Cache} produced by an + * earlier call to {@link CacheFactory::create}. + * @throws CacheClosedException if a cache has not been created + * or the only created one is {@link Cache::isClosed closed} + */ + static CachePtr getAnyInstance(); + + /** Returns the version of the cache implementation. + * For the 1.0 release of Geode, the string returned is 1.0. + * @return the version of the cache implementation as a String + */ + static const char* getVersion(); + + /** Returns the product description string including product name and version. + */ + static const char* getProductDescription(); + + /** + * Sets the free connection timeout for this pool. + * If the pool has a max connections setting, operations will block + * if all of the connections are in use. The free connection timeout + * specifies how long those operations will block waiting for + * a free connection before receiving + * an {@link AllConnectionsInUseException}. If max connections + * is not set this setting has no effect. + * @see #setMaxConnections(int) + * @param connectionTimeout is the connection timeout in milliseconds + * @return a reference to this + * @throws IllegalArgumentException if connectionTimeout + * is less than or equal to 0. + */ + CacheFactoryPtr setFreeConnectionTimeout(int connectionTimeout); + /** + * Sets the load conditioning interval for this pool. + * This interval controls how frequently the pool will check to see if + * a connection to a given server should be moved to a different + * server to improve the load balance. + *

A value of -1 disables load conditioning + * @param loadConditioningInterval is the connection lifetime in milliseconds + * @return a reference to this + * @throws IllegalArgumentException if connectionLifetime + * is less than -1. + */ + CacheFactoryPtr setLoadConditioningInterval(int loadConditioningInterval); + /** + * Sets the socket buffer size for each connection made in this pool. + * Large messages can be received and sent faster when this buffer is larger. + * Larger buffers also optimize the rate at which servers can send events + * for client subscriptions. + * @param bufferSize is the size of the socket buffers used for reading and + * writing on each connection in this pool. + * @return a reference to this + * @throws IllegalArgumentException if bufferSize + * is less than or equal to 0. + */ + CacheFactoryPtr setSocketBufferSize(int bufferSize); + + /** + * Sets the thread local connections policy for this pool. + * If true then any time a thread goes to use a connection + * from this pool it will check a thread local cache and see if it already + * has a connection in it. If so it will use it. If not it will get one from + * this pool and cache it in the thread local. This gets rid of thread + * contention + * for the connections but increases the number of connections the servers + * see. + *

If false then connections are returned to the pool as soon + * as the operation being done with the connection completes. This allows + * connections to be shared amonst multiple threads keeping the number of + * connections down. + * @param threadLocalConnections if true then enable thread local + * connections. + * @return a reference to this + */ + CacheFactoryPtr setThreadLocalConnections(bool threadLocalConnections); + + /** + * Sets the number of milliseconds to wait for a response from a server before + * timing out the operation and trying another server (if any are available). + * @param timeout is the number of milliseconds to wait for a response from a + * server + * @return a reference to this + * @throws IllegalArgumentException if timeout + * is less than or equal to 0. + */ + CacheFactoryPtr setReadTimeout(int timeout); + + /** + * Sets the minimum number of connections to keep available at all times. + * When the pool is created, it will create this many connections. + * If 0 then connections will not be made until an actual + * operation + * is done that requires client-to-server communication. + * @param minConnections is the initial number of connections + * this pool will create. + * @return a reference to this + * @throws IllegalArgumentException if minConnections + * is less than 0. + */ + CacheFactoryPtr setMinConnections(int minConnections); + + /** + * Sets the max number of client to server connections that the pool will + * create. If all of + * the connections are in use, an operation requiring a client to server + * connection + * will block until a connection is available. + * @see #setFreeConnectionTimeout(int) + * @param maxConnections is the maximum number of connections in the pool. + * -1 indicates that there is no maximum number of connections + * @return a reference to this + * @throws IllegalArgumentException if maxConnections + * is less than minConnections. + */ + CacheFactoryPtr setMaxConnections(int maxConnections); + + /** + * Sets the amount of time a connection can be idle before expiring the + * connection. + * If the pool size is greater than the minimum specified by + * {@link PoolFactory#setMinConnections(int)}, connections which have been + * idle + * for longer than the idleTimeout will be closed. + * @param idleTimeout is the amount of time in milliseconds that an idle + * connection + * should live before expiring. -1 indicates that connections should never + * expire. + * @return a reference to this + * @throws IllegalArgumentException if idleTimout + * is less than 0. + */ + CacheFactoryPtr setIdleTimeout(long idleTimeout); + + /** + * Set the number of times to retry a request after timeout/exception. + * @param retryAttempts is the number of times to retry a request + * after timeout/exception. -1 indicates that a request should be + * tried against every available server before failing + * @return a reference to this + * @throws IllegalArgumentException if idleTimout + * is less than 0. + */ + CacheFactoryPtr setRetryAttempts(int retryAttempts); + + /** + * The frequency with which servers must be pinged to verify that they are + * still alive. + * Each server will be sent a ping every pingInterval if there + * has not + * been any other communication with the server. + * + * These pings are used by the server to monitor the health of + * the client. Make sure that the pingInterval is less than the + * maximum time between pings allowed by the bridge server. + * @param pingInterval is the amount of time in milliseconds between + * pings. + * @return a reference to this + * @throws IllegalArgumentException if pingInterval + * is less than 0. + */ + CacheFactoryPtr setPingInterval(long pingInterval); + + /** + * The frequency with which client updates the locator list. To disable this + * set its + * value to 0. + * @param updateLocatorListInterval is the amount of time in milliseconds + * between + * checking locator list at locator. + */ + CacheFactoryPtr setUpdateLocatorListInterval(long updateLocatorListInterval); + + /** + * The frequency with which the client statistics must be sent to the server. + * Doing this allows GFMon to monitor clients. + *

A value of -1 disables the sending of client statistics + * to the server. + * + * @param statisticInterval is the amount of time in milliseconds between + * sends of client statistics to the server. + * @return a reference to this + * @throws IllegalArgumentException if statisticInterval + * is less than -1. + */ + CacheFactoryPtr setStatisticInterval(int statisticInterval); + + /** + * Configures the group which contains all the servers that this pool connects + * to. + * @param group is the server group that this pool will connect to. + * If the value is null or "" then the pool connects + * to all servers. + * @return a reference to this + */ + CacheFactoryPtr setServerGroup(const char* group); + + /** + * Adds a locator, given its host and port, to this factory. + * The locator must be a server locator and will be used to discover other + * running + * bridge servers and locators. + * @param host is the host name or ip address that the locator is listening + * on. + * @param port is the port that the locator is listening on. + * @return a reference to this + * @throws IllegalArgumentException if the host is an unknown + * host + * according to {@link java.net.InetAddress#getByName} or if the port is + * outside + * the valid range of [1..65535] inclusive. + * @throws IllegalStateException if the locator has already been {@link + * #addServer added} to this factory. + */ + CacheFactoryPtr addLocator(const char* host, int port); + + /** + * Adds a server, given its host and port, to this factory. + * The server must be a bridge server and this client will + * directly connect to the server without consulting a server locator. + * @param host is the host name or ip address that the server is listening on. + * @param port is the port that the server is listening on. + * @return a reference to this + * @throws IllegalArgumentException if the host is an unknown + * host + * according to {@link java.net.InetAddress#getByName} or if the port is + * outside + * the valid range of [1..65535] inclusive. + * @throws IllegalStateException if the server has already been {@link + * #addLocator added} to this factory. + */ + CacheFactoryPtr addServer(const char* host, int port); + + /** + * If set to true then the created pool will have + * server-to-client + * subscriptions enabled. + * If set to false then all Subscription* attributes + * are ignored at the time of creation. + * @return a reference to this + */ + CacheFactoryPtr setSubscriptionEnabled(bool enabled); + /** + * Sets the redundancy level for this pools server-to-client subscriptions. + * If 0 then no redundant copies are kept on the servers. + * Otherwise an effort is made to maintain the requested number of + * copies of the server-to-client subscriptions. At most, one copy per server + * is + * made up to the requested level. + * @param redundancy is the number of redundant servers for this client's + * subscriptions. + * @return a reference to this + * @throws IllegalArgumentException if redundancyLevel + * is less than -1. + */ + CacheFactoryPtr setSubscriptionRedundancy(int redundancy); + /** + * Sets the messageTrackingTimeout attribute which is the time-to-live period, + * in + * milliseconds, for subscription events the client has received from the + * server. It is used + * to minimize duplicate events. + * Entries that have not been modified for this amount of time + * are expired from the list. + * @param messageTrackingTimeout is the number of milliseconds to set the + * timeout to. + * @return a reference to this + * @throws IllegalArgumentException if messageTrackingTimeout + * is less than or equal to 0. + */ + CacheFactoryPtr setSubscriptionMessageTrackingTimeout( + int messageTrackingTimeout); + + /** + * Sets the is the interval in milliseconds + * to wait before sending acknowledgements to the bridge server for + * events received from the server subscriptions. + * + * @param ackInterval is the number of milliseconds to wait before sending + * event + * acknowledgements. + * @return a reference to this + * @throws IllegalArgumentException if ackInterval + * is less than or equal to 0. + */ + CacheFactoryPtr setSubscriptionAckInterval(int ackInterval); + + /** + * Sets whether Pool is in multi user secure mode. + * If its in multiuser mode then app needs to get RegionService instance of + * Cache, to do the operations on cache. + * Deafult value is false. + * @param multiuserAuthentication + * to set the pool in multiuser mode. + * @return a reference to this + */ + CacheFactoryPtr setMultiuserAuthentication(bool multiuserAuthentication); + + /** + * By default setPRSingleHopEnabled is true
+ * The client is aware of location of partitions on servers hosting + * {@link Region}s. + * Using this information, the client routes the client cache operations + * directly to the server which is hosting the required partition for the + * cache operation. + * If setPRSingleHopEnabled is false the client can do an extra hop on servers + * to go to the required partition for that cache operation. + * The setPRSingleHopEnabled avoids extra hops only for following cache + * operations:
+ * 1. {@link Region#put(Object, Object)}
+ * 2. {@link Region#get(Object)}
+ * 3. {@link Region#destroy(Object)}
+ * 4. {@link Region#getAll(Object, object)}
+ * If true, works best when {@link PoolFactory#setMaxConnections(int)} is set + * to -1. + * @param name is boolean whether PR Single Hop optimization is enabled or + * not. + * @return a reference to this + */ + CacheFactoryPtr setPRSingleHopEnabled(bool enabled); + + /** + * Control whether pdx ignores fields that were unread during deserialization. + * The default is to preserve unread fields be including their data during + * serialization. + * But if you configure the cache to ignore unread fields then their data will + * be lost + * during serialization. + *

You should only set this attribute to true if you know this + * member + * will only be reading cache data. In this use case you do not need to pay the + * cost + * of preserving the unread fields since you will never be reserializing pdx + * data. + * + * @param ignore true if fields not read during pdx + * deserialization should be ignored; + * false, the default, if they should be preserved. + * + * + * @return this CacheFactory + * @since 3.6 + */ + CacheFactoryPtr setPdxIgnoreUnreadFields(bool ignore); + + /** Sets the object preference to PdxInstance type. + * When a cached object that was serialized as a PDX is read + * from the cache a {@link PdxInstance} will be returned instead of the actual + * domain class. + * The PdxInstance is an interface that provides run time access to + * the fields of a PDX without deserializing the entire PDX. + * The PdxInstance implementation is a light weight wrapper + * that simply refers to the raw bytes of the PDX that are kept + * in the cache. Using this method applications can choose to + * access PdxInstance instead of C++ object. + *

Note that a PdxInstance is only returned if a serialized PDX is found in + * the cache. + * If the cache contains a deserialized PDX, then a domain class instance is + * returned instead of a PdxInstance. + * + * @param pdxReadSerialized true to prefer PdxInstance + * @return this ClientCacheFactory + */ + CacheFactoryPtr setPdxReadSerialized(bool pdxReadSerialized); + + /** + * Sets a geode property that will be used when creating the {link @Cache}. + * @param name the name of the geode property + * @param value the value of the geode property + * @return a reference to this + * @since 3.5 + */ + CacheFactoryPtr set(const char* name, const char* value); + + private: + PoolFactoryPtr pf; + PropertiesPtr dsProp; + bool ignorePdxUnreadFields; + bool pdxReadSerialized; + + PoolFactoryPtr getPoolFactory(); + + CachePtr create(const char* name, DistributedSystemPtr system = NULLPTR, + const char* cacheXml = 0, + const CacheAttributesPtr& attrs = NULLPTR); + + static void create_(const char* name, DistributedSystemPtr& system, + const char* id_data, CachePtr& cptr, + bool ignorePdxUnreadFields, bool readPdxSerialized); + + // no instances allowed + CacheFactory(); + CacheFactory(const PropertiesPtr dsProps); + ~CacheFactory(); + + PoolPtr determineDefaultPool(CachePtr cachePtr); + + static CachePtr getAnyInstance(bool throwException); + static GfErrType basicGetInstance(const DistributedSystemPtr& system, + bool closeOk, CachePtr& cptr); + + // Set very first time some creates cache + static CacheFactoryPtr default_CacheFactory; + static PoolPtr createOrGetDefaultPool(); + static void* m_cacheMap; + static void init(); + static void cleanup(); + static void handleXML(CachePtr& cachePtr, const char* cachexml, + DistributedSystemPtr& system); + friend class CppCacheLibrary; + friend class RegionFactory; + friend class RegionXmlCreation; + friend class CacheXmlCreation; +}; +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHEFACTORY_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/fd58b100/src/cppcache/include/geode/CacheListener.hpp ---------------------------------------------------------------------- diff --git a/src/cppcache/include/geode/CacheListener.hpp b/src/cppcache/include/geode/CacheListener.hpp new file mode 100644 index 0000000..321df5d --- /dev/null +++ b/src/cppcache/include/geode/CacheListener.hpp @@ -0,0 +1,213 @@ +#pragma once + +#ifndef GEODE_CACHELISTENER_H_ +#define GEODE_CACHELISTENER_H_ + +/* + * 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 "geode_globals.hpp" +#include "gf_types.hpp" +#include "SharedPtr.hpp" + +/** + * @file + */ + +namespace apache { +namespace geode { +namespace client { + +class EntryEvent; +class RegionEvent; + +/** + * @class CacheListener CacheListener.hpp + * An application plug-in that can be installed on a region. + * Listeners are change notifications that are invoked + * AFTER the change has occured for region update operations on a client. + * Listeners also receive notifications when entries in a region are modified. + * Multiple events can cause concurrent invocation + * of CacheListener methods. If event A occurs before event B, + * there is no guarantee that their corresponding CacheListener + * method invocations will occur in the same order. Any exceptions thrown by + * the listener are caught by Geode and logged. If the exception is due to + * listener invocation on the same thread where a region operation has been + * performed, then a CacheListenerException is thrown back to + * the application. If the exception is for a notification received from + * server then that is logged and the notification thread moves on to + * receiving other notifications. + * + * There are two cases in which listeners are invoked. The first is when a + * region modification operation (e.g. put, create, destroy, invalidate) + * is performed. For this case it is important to ensure that minimal work is + * done in the listener before returning control back to Geode since the + * operation will block till the listener has not completed. For example, + * a listener implementation may choose to hand off the event to a thread pool + * that then processes the event on its thread rather than the listener thread. + * The second is when notifications are received from java server as a result + * of region register interest calls (Region::registerKeys etc), + * or invalidate notifications when notify-by-subscription is false on the + * server. In this case the methods of CacheListener are invoked + * asynchronously (i.e. does not block the thread that receives notification + * messages). Additionally for the latter case of notifications from server, + * listener is always invoked whether or not local operation is successful + * e.g. if a destroy notification is received and key does not exist in the + * region, the listener will still be invoked. This is different from the + * first case where listeners are invoked only when the region update + * operation succeeds. + * + * @see AttributesFactory::setCacheListener + * @see RegionAttributes::getCacheListener + * @see CacheListenerException + */ +class CPPCACHE_EXPORT CacheListener : public SharedBase { + /** + * @brief public methods + */ + public: + /** + * @brief destructor + */ + virtual ~CacheListener(); + + /** Handles the event of a new key being added to a region. The entry + * did not previously exist in this region in the local cache (even with a + * NULLPTR value). + * + * @param event denotes the event object associated with the entry creation + * This function does not throw any exception. + * @see Region::create + * @see Region::put + * @see Region::get + */ + virtual void afterCreate(const EntryEvent& event); + + /** Handles the event of an entry's value being modified in a region. This + * entry + * previously existed in this region in the local cache, but its previous + * value + * may have been NULLPTR. + * + * @param event EntryEvent denotes the event object associated with updating + * the entry + * @see Region::put + */ + virtual void afterUpdate(const EntryEvent& event); + + /** + * Handles the event of an entry's value being invalidated. + * + * @param event EntryEvent denotes the event object associated with the entry + * invalidation + */ + virtual void afterInvalidate(const EntryEvent& event); + + /** + * Handles the event of an entry being destroyed. + * + * @param event EntryEvent denotes the event object associated with the entry + * destruction + * @see Region::destroy + */ + virtual void afterDestroy(const EntryEvent& event); + + /** Handles the event of a region being invalidated. Events are not + * invoked for each individual value that is invalidated as a result of + * the region being invalidated. Each subregion, however, gets its own + * regionInvalidated event invoked on its listener. + * @param event RegionEvent denotes the event object associated with the + * region + * invalidation + * @see Region::invalidateRegion + */ + virtual void afterRegionInvalidate(const RegionEvent& event); + + /** Handles the event of a region being destroyed. Events are not invoked for + * each individual entry that is destroyed as a result of the region being + * destroyed. Each subregion, however, gets its own + * afterRegionDestroyed event + * invoked on its listener. + * @param event RegionEvent denotes the event object associated with the + * region + * destruction + * @see Region::destroyRegion + */ + virtual void afterRegionDestroy(const RegionEvent& event); + + /** Handles the event of a region being cleared. Events are not invoked for + * each individual entry that is removed as a result of the region being + * cleared. Each subregion, however, gets its own + * afterRegionClear event + * invoked on its listener. + * @param event RegionEvent denotes the event object associated with the + * region + * removal + * @see Region::clear + */ + virtual void afterRegionClear(const RegionEvent& event); + + /** Handles the event of a region being live. This event will be invoked + * after processing all the past messages. + * Each subregion, however, gets its own afterRegionLive event + * invoked on its listener. + * @param event RegionEvent denotes the associated event object + */ + virtual void afterRegionLive(const RegionEvent& event); + + /** Called when the region containing this callback is destroyed, when + * the cache is closed. + * + *

Implementations should clean up any external + * resources, such as database connections. Any runtime exceptions this + * method + * throws will be logged. + * + *

It is possible for this method to be called multiple times on a single + * callback instance, so implementations must be tolerant of this. + * + * @see Cache::close + * @see Region::destroyRegion + */ + + virtual void close(const RegionPtr& region); + /** + * Called when all the endpoints assosiated with region are down. + * This will be called when all the endpoints are down for the first time. + * If endpoints come up and again go down it will be called again. + * This will also be called when all endpoints are down and region is attached + * to the pool. + * @param region RegionPtr denotes the assosiated region. + */ + virtual void afterRegionDisconnected(const RegionPtr& region); + + protected: + /** + * @brief constructors + */ + CacheListener(); + + private: + // never implemented. + CacheListener(const CacheListener& other); + void operator=(const CacheListener& other); +}; +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHELISTENER_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/fd58b100/src/cppcache/include/geode/CacheLoader.hpp ---------------------------------------------------------------------- diff --git a/src/cppcache/include/geode/CacheLoader.hpp b/src/cppcache/include/geode/CacheLoader.hpp new file mode 100644 index 0000000..5d579b6 --- /dev/null +++ b/src/cppcache/include/geode/CacheLoader.hpp @@ -0,0 +1,105 @@ +#pragma once + +#ifndef GEODE_CACHELOADER_H_ +#define GEODE_CACHELOADER_H_ + +/* + * 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. + */ + +/** + * @file + */ + +#include "geode_globals.hpp" +#include "gf_types.hpp" +#include "CacheableKey.hpp" +#include "Cacheable.hpp" +#include "UserData.hpp" + +namespace apache { +namespace geode { +namespace client { + +/** + * @class CacheLoader CacheLoader.hpp + * An application plug-in that can be installed on a region. Loaders + * facilitate loading of data into the cache. When an application does a + * lookup for a key in a region and it does not exist, the system checks to + * see if any loaders are available for the region in the system and + * invokes them to get the value for the key into the cache. + * Allows data to be loaded from a 3rd party data source and placed + * into the region + * When {@link Region::get} is called for a region + * entry that has a NULLPTR value, the + * {@link CacheLoader::load} method of the + * region's cache loader is invoked. The load method + * creates the value for the desired key by performing an operation such + * as a database query. + * + * @see AttributesFactory::setCacheLoader + * @see RegionAttributes::getCacheLoader + */ +class CPPCACHE_EXPORT CacheLoader : public SharedBase { + public: + /**Loads a value. Application writers should implement this + * method to customize the loading of a value. This method is called + * by the caching service when the requested value is not in the cache. + * Any exception thrown by this method is propagated back to and thrown + * by the invocation of {@link Region::get} that triggered this load. + * @param rp a Region Pointer for which this is called. + * @param key the key for the cacheable + * @param helper any related user data, or NULLPTR + * @return the value supplied for this key, or NULLPTR if no value can be + * supplied. + * + *@see Region::get . + */ + virtual CacheablePtr load(const RegionPtr& rp, const CacheableKeyPtr& key, + const UserDataPtr& aCallbackArgument) = 0; + + /** Called when the region containing this callback is destroyed, when + * the cache is closed. + * + *

Implementations should clean up any external + * resources, such as database connections. Any runtime exceptions this method + * throws will be logged. + * + *

It is possible for this method to be called multiple times on a single + * callback instance, so implementations must be tolerant of this. + * + * @param rp the region pointer + * + * @see Cache::close + * @see Region::destroyRegion + */ + virtual void close(const RegionPtr& rp); + + virtual ~CacheLoader(); + + protected: + CacheLoader(); + + protected: + // never implemented. + CacheLoader(const CacheLoader& other); + void operator=(const CacheLoader& other); +}; +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHELOADER_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/fd58b100/src/cppcache/include/geode/CacheStatistics.hpp ---------------------------------------------------------------------- diff --git a/src/cppcache/include/geode/CacheStatistics.hpp b/src/cppcache/include/geode/CacheStatistics.hpp new file mode 100644 index 0000000..4e5e0d2 --- /dev/null +++ b/src/cppcache/include/geode/CacheStatistics.hpp @@ -0,0 +1,114 @@ +#pragma once + +#ifndef GEODE_CACHESTATISTICS_H_ +#define GEODE_CACHESTATISTICS_H_ + +/* + * 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 "geode_globals.hpp" +#include "gf_types.hpp" +/** + * @file + */ + +namespace apache { +namespace geode { +namespace client { + +class LocalRegion; + +/** +*@class CacheStatistics CacheStatistics.hpp +* +*Defines common statistical information +*for both the region and its entries. All of these methods may throw a +*CacheClosedException, RegionDestroyedException, or EntryDestroyedException. +* +*@see Region::getStatistics +*@see RegionEntry::getStatistics +*/ +class CPPCACHE_EXPORT CacheStatistics : public SharedBase { + public: + CacheStatistics(); + + virtual ~CacheStatistics(); + + /** For an entry, returns the time that the entry's value was last modified. + * For a region, returns the last time any of the region's entries' values or + * the values in subregions' entries were modified. The + * modification may have been initiated locally, or it may have been an update + * distributed from another cache. It may also have been a new value provided + * by a loader. The modification time on a region is propagated upward to + * parent + * regions, transitively, to the root region. + *

+ * The number is expressed as the number of milliseconds since January 1, + * 1970. + * The granularity may be as coarse as 100ms, so the accuracy may be off by + * up to 50ms. + *

+ * Entry and subregion creation will update the modification time on a + * region, but destroy, destroyRegion, + * invalidate, and invalidateRegion + * do not update the modification time. + * @return the last modification time of the region or the entry; + * returns 0 if the entry is invalid or the modification time is + * uninitialized. + * @see Region::put + * @see Region::get + * @see Region::create + * @see Region::createSubregion + */ + virtual uint32_t getLastModifiedTime() const; + + /** + * For an entry, returns the last time it was accessed via + * Region.get. + * For a region, returns the last time any of its entries or the entries of + * its subregions were accessed with Region.get. + * Any modifications will also update the lastAccessedTime, so + * lastAccessedTime is always >= lastModifiedTime. + * The lastAccessedTime on a region is propagated upward to + * parent regions, transitively, to the the root region. + *

+ * The number is expressed as the number of milliseconds + * since January 1, 1970. + * The granularity may be as coarse as 100ms, so the accuracy may be off by + * up to 50ms. + * + * @return the last access time of the region or the entry's value; + * returns 0 if entry is invalid or access time is uninitialized. + * @see Region::get + * @see getLastModifiedTime + */ + virtual uint32_t getLastAccessedTime() const; + + private: + virtual void setLastAccessedTime(uint32_t lat); + virtual void setLastModifiedTime(uint32_t lmt); + + volatile uint32_t m_lastAccessTime; + volatile uint32_t m_lastModifiedTime; + + friend class LocalRegion; +}; +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHESTATISTICS_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/fd58b100/src/cppcache/include/geode/CacheTransactionManager.hpp ---------------------------------------------------------------------- diff --git a/src/cppcache/include/geode/CacheTransactionManager.hpp b/src/cppcache/include/geode/CacheTransactionManager.hpp new file mode 100644 index 0000000..d2186e1 --- /dev/null +++ b/src/cppcache/include/geode/CacheTransactionManager.hpp @@ -0,0 +1,205 @@ +#pragma once + +#ifndef GEODE_CACHETRANSACTIONMANAGER_H_ +#define GEODE_CACHETRANSACTIONMANAGER_H_ + +/* + * 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. + */ + +/* The specification of function behaviors is found in the corresponding .cpp + * file. + */ + +//#### Warning: DO NOT directly include Region.hpp, include Cache.hpp instead. + +#include "geode_globals.hpp" +#include "gf_types.hpp" + +namespace apache { +namespace geode { +namespace client { + +class CPPCACHE_EXPORT CacheTransactionManager + : public apache::geode::client::SharedBase { + public: + /** Creates a new transaction and associates it with the current thread. + * + * @throws IllegalStateException if the thread is already associated with a + * transaction + * + * @since 3.6 + */ + virtual void begin() = 0; + + /** Commit the transaction associated with the current thread. If + * the commit operation fails due to a conflict it will destroy + * the transaction state and throw a {@link + * CommitConflictException}. If the commit operation succeeds, + * it returns after the transaction state has been merged with + * committed state. When this method completes, the thread is no + * longer associated with a transaction. + * + * @throws IllegalStateException if the thread is not associated with a + * transaction + * + * @throws CommitConflictException if the commit operation fails due to + * a write conflict. + * + * @throws TransactionDataNodeHasDepartedException if the node hosting the + * transaction data has departed. This is only relevant for transaction that + * involve PartitionedRegions. + * + * @throws TransactionDataNotColocatedException if at commit time, the data + * involved in the transaction has moved away from the transaction hosting + * node. This can only happen if rebalancing/recovery happens during a + * transaction that involves a PartitionedRegion. + * + * @throws TransactionInDoubtException when Geode cannot tell which nodes + * have applied the transaction and which have not. This only occurs if nodes + * fail mid-commit, and only then in very rare circumstances. + */ + virtual void commit() = 0; + + /** Roll back the transaction associated with the current thread. When + * this method completes, the thread is no longer associated with a + * transaction and the transaction context is destroyed. + * + * @since 3.6 + * + * @throws IllegalStateException if the thread is not associated with a + * transaction + */ + virtual void rollback() = 0; + + /** + * Suspends the transaction on the current thread. All subsequent operations + * performed by this thread will be non-transactional. The suspended + * transaction can be resumed by calling {@link #resume(TransactionId)} + * + * @return the transaction identifier of the suspended transaction or null if + * the thread was not associated with a transaction + * @since 3.6.2 + */ + virtual TransactionIdPtr suspend() = 0; + + /** + * On the current thread, resumes a transaction that was previously suspended + * using {@link #suspend()} + * + * @param transactionId + * the transaction to resume + * @throws IllegalStateException + * if the thread is associated with a transaction or if + * {@link #isSuspended(TransactionId)} would return false for the + * given transactionId + * @since 3.6.2 + */ + virtual void resume(TransactionIdPtr transactionId) = 0; + + /** + * This method can be used to determine if a transaction with the given + * transaction identifier is currently suspended locally. This method does not + * check other members for transaction status. + * + * @param transactionId + * @return true if the transaction is in suspended state, false otherwise + * @since 3.6.2 + * @see #exists(TransactionId) + */ + virtual bool isSuspended(TransactionIdPtr transactionId) = 0; + + /** + * On the current thread, resumes a transaction that was previously suspended + * using {@link #suspend()}. + * + * This method is equivalent to + *

+   * if (isSuspended(txId)) {
+   *   resume(txId);
+   * }
+   * 
+ * except that this action is performed atomically + * + * @param transactionId + * the transaction to resume + * @return true if the transaction was resumed, false otherwise + * @since 3.6.2 + */ + virtual bool tryResume(TransactionIdPtr transactionId) = 0; + + /** + * On the current thread, resumes a transaction that was previously suspended + * using {@link #suspend()}, or waits for the specified timeout interval if + * the transaction has not been suspended. This method will return if: + *
    + *
  • Another thread suspends the transaction
  • + *
  • Another thread calls commit/rollback on the transaction
  • + *
  • This thread has waited for the specified timeout
  • + *
+ * + * This method returns immediately if {@link #exists(TransactionId)} returns + * false. + * + * @param transactionId + * the transaction to resume + * @param waitTimeInMilliSec + * the maximum milliseconds to wait + * @return true if the transaction was resumed, false otherwise + * @since 3.6.2 + * @see #tryResume(TransactionId) + */ + virtual bool tryResume(TransactionIdPtr transactionId, + int32_t waitTimeInMilliSec) = 0; + + /** + * Reports the existence of a transaction for the given transactionId. This + * method can be used to determine if a transaction with the given transaction + * identifier is currently in progress locally. + * + * @param transactionId + * the given transaction identifier + * @return true if the transaction is in progress, false otherwise. + * @since 3.6.2 + * @see #isSuspended(TransactionId) + */ + virtual bool exists(TransactionIdPtr transactionId) = 0; + + /** Returns the transaction identifier for the current thread + * + * @return the transaction identifier or null if no transaction exists + * + * @since 3.6.2 + */ + virtual TransactionIdPtr getTransactionId() = 0; + + /** Reports the existence of a Transaction for this thread + * + * @return true if a transaction exists, false otherwise + * + * @since 3.6 + */ + virtual bool exists() = 0; + + protected: + CacheTransactionManager(); + virtual ~CacheTransactionManager(); +}; +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHETRANSACTIONMANAGER_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/fd58b100/src/cppcache/include/geode/CacheWriter.hpp ---------------------------------------------------------------------- diff --git a/src/cppcache/include/geode/CacheWriter.hpp b/src/cppcache/include/geode/CacheWriter.hpp new file mode 100644 index 0000000..2dc2e6d --- /dev/null +++ b/src/cppcache/include/geode/CacheWriter.hpp @@ -0,0 +1,188 @@ +#pragma once + +#ifndef GEODE_CACHEWRITER_H_ +#define GEODE_CACHEWRITER_H_ + +/* + * 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 "geode_globals.hpp" +#include "gf_types.hpp" + +/** + * @file + * + */ + +namespace apache { +namespace geode { +namespace client { + +class EntryEvent; +class RegionEvent; +/** + * @class CacheWriter CacheWriter.hpp + * An application plug-in that can be installed on the region. + * Defines methods that are called BEFORE entry modification. + * A distributed region will typically have a single cache writer. + * If the application is designed such that all or most updates to + * a region occurs on a node, it is desirable to have the cache writer + * for the region to be installed at that node. + * + * Cache writer invocations are initiated by the node where the entry or + * region modification occurs. If there is a local cache writer on the node + * where the change occurs, that is invoked. If there is no local cache writer + * , the system knows which of the nodes that have the region defined have a + * cache writer defined. + * + * Note that cache writer callbacks are synchronous callbacks and have the + * ability + * to veto the cache update. Since cache writer invocations require + * communications + * over the network, (especially if they are not colocated on the nodes where + * the + * change occurs) the use of cache writers presents a performance penalty. + * + * A user-defined object defined in the {@link RegionAttributes} that is + * called synchronously before a region or entry in the cache is modified. + * + * The typical use for a CacheWriter is to update a database. + * Application writers should implement these methods to execute + * application-specific behavior before the cache is modified. + * + *

Before the region is updated via a put, create, or destroy operation, + * Geode will call a CacheWriter that is installed anywhere in + * any + * participating cache for that region, preferring a local + * CacheWriter + * if there is one. Usually there will be only one CacheWriter in + * the distributed system. If there are multiple CacheWriters + * available in the distributed system, the Geode + * implementation always prefers one that is stored locally, or else picks one + * arbitrarily. In any case, only one CacheWriter will be invoked. + * + *

The CacheWriter is capable of aborting the update to the + * cache by throwing + * a CacheWriterException. This exception or any runtime exception + * thrown by the CacheWriter will abort the operation, and the + * exception will be propagated to the initiator of the operation, regardless + * of whether the initiator is in the same process as the + * CacheWriter. + * + * @see AttributesFactory::setCacheWriter + * @see RegionAttributes::getCacheWriter + * @see AttributesMutator::setCacheWriter + */ +class CPPCACHE_EXPORT CacheWriter : public SharedBase { + public: + /** + * Called before an entry is updated. The entry update is initiated by a + * put + * or a get that causes the loader to update an existing entry. + * The entry previously existed in the cache where the operation was + * initiated, although the old value may have been NULLPTR. The entry being + * updated may or may not exist in the local cache where the CacheWriter is + * installed. + * + * @param event EntryEvent denotes the event object associated with updating + * the entry + * + * + * @see Region::put + * @see Region::get + */ + virtual bool beforeUpdate(const EntryEvent& event); + + /** Called before an entry is created. Entry creation is initiated by a + * create, a put, or a get. + * The CacheWriter can determine whether this value comes from a + * get or not from {@link EntryEvent::isLoad}. The entry being + * created may already exist in the local cache where this + * CacheWriter + * is installed, but it does not yet exist in the cache where the operation + * was initiated. + * @param event EntryEvent denotes the event object associated with creating + * the entry + * + * + * @see Region::create + * @see Region::put + * @see Region::get + */ + virtual bool beforeCreate(const EntryEvent& event); + + /** + * Called before an entry is destroyed. The entry being destroyed may or may + * not exist in the local cache where the CacheWriter is installed. This + * method + * is not called as a result of expiration or {@link + * Region::localDestroyRegion}. + * + * @param event EntryEvent denotes the event object associated with destroying + * the entry + * + * @see Region::destroy + */ + virtual bool beforeDestroy(const EntryEvent& event); + + /*@brief called before this region is cleared + * @param event EntryEvent denotes the event object associated with clearing + * the region + * + * @see Region::clear + */ + virtual bool beforeRegionClear(const RegionEvent& event); + + /*@brief called before this region is destroyed + * @param event EntryEvent denotes the event object associated with destroying + * the region + * + * @see Region::destroyRegion + */ + virtual bool beforeRegionDestroy(const RegionEvent& event); + + /** Called when the region containing this callback is destroyed, when + * the cache is closed. + * + *

Implementations should clean up any external + * resources, such as database connections. Any runtime exceptions this + * method + * throws will be logged. + * + *

It is possible for this method to be called multiple times on a single + * callback instance, so implementations must be tolerant of this. + * + * @see Cache::close + * @see Region::destroyRegion + */ + virtual void close(const RegionPtr& rp); + + virtual ~CacheWriter(); + + protected: + CacheWriter(); + + private: + // never implemented. + CacheWriter(const CacheWriter& other); + void operator=(const CacheWriter& other); +}; +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHEWRITER_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/fd58b100/src/cppcache/include/geode/Cacheable.hpp ---------------------------------------------------------------------- diff --git a/src/cppcache/include/geode/Cacheable.hpp b/src/cppcache/include/geode/Cacheable.hpp new file mode 100644 index 0000000..daf398e --- /dev/null +++ b/src/cppcache/include/geode/Cacheable.hpp @@ -0,0 +1,46 @@ +#pragma once + +#ifndef GEODE_CACHEABLE_H_ +#define GEODE_CACHEABLE_H_ + +/* + * 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. + */ + +/** + * @file + */ + +#include "geode_globals.hpp" +#include "Serializable.hpp" + +namespace apache { +namespace geode { +namespace client { + +typedef SerializablePtr CacheablePtr; +typedef Serializable Cacheable; + +template +inline CacheablePtr createValue(const SharedPtr& value); + +template +inline CacheablePtr createValue(const TVALUE* value); +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHEABLE_H_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/fd58b100/src/cppcache/include/geode/Cacheable.inl ---------------------------------------------------------------------- diff --git a/src/cppcache/include/geode/Cacheable.inl b/src/cppcache/include/geode/Cacheable.inl new file mode 100644 index 0000000..4f7d61f --- /dev/null +++ b/src/cppcache/include/geode/Cacheable.inl @@ -0,0 +1,55 @@ +#pragma once + +#ifndef GEODE_CACHEABLE_INL_ +#define GEODE_CACHEABLE_INL_ + +/* + * 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. + */ + +/** + * @file + */ + +#include "Cacheable.hpp" + +namespace apache { +namespace geode { +namespace client { + +template< class PRIM > +inline CacheablePtr Cacheable::create( const PRIM value ) +{ + return createValue( value ); +} + +template +inline CacheablePtr createValue( const SharedPtr< TVALUE >& value ) +{ + return CacheablePtr( value ); +} + +template +inline CacheablePtr createValue( const TVALUE* value ) +{ + return createValueArr( value ); +} + +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHEABLE_INL_ http://git-wip-us.apache.org/repos/asf/geode-native/blob/fd58b100/src/cppcache/include/geode/CacheableBuiltins.hpp ---------------------------------------------------------------------- diff --git a/src/cppcache/include/geode/CacheableBuiltins.hpp b/src/cppcache/include/geode/CacheableBuiltins.hpp new file mode 100644 index 0000000..7168c92 --- /dev/null +++ b/src/cppcache/include/geode/CacheableBuiltins.hpp @@ -0,0 +1,700 @@ +#pragma once + +#ifndef GEODE_CACHEABLEBUILTINS_H_ +#define GEODE_CACHEABLEBUILTINS_H_ + +/* + * 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. + */ + +/** @file CacheableBuiltins.hpp + * @brief Contains generic template definitions for Cacheable types + * and instantiations for built-in types. + */ + +#include "Cacheable.hpp" +#include "CacheableKey.hpp" +#include "Serializer.hpp" +#include "CacheableKeys.hpp" +#include "CacheableString.hpp" + +namespace apache { +namespace geode { +namespace client { + +/** sprintf implementation. */ +extern int gf_sprintf(char* buffer, const char* fmt, ...); + +/** snprintf implementation. */ +extern int gf_snprintf(char* buffer, int32_t maxLength, const char* fmt, ...); + +/** Template CacheableKey class for primitive types. */ +template +class CacheableKeyType : public CacheableKey { + protected: + TObj m_value; + + inline CacheableKeyType() + : m_value(apache::geode::client::serializer::zeroObject()) {} + + inline CacheableKeyType(const TObj value) : m_value(value) {} + + public: + /** Gets the contained value. */ + inline TObj value() const { return m_value; } + + // Cacheable methods + + /** Serialize this object to given DataOutput. */ + virtual void toData(DataOutput& output) const { + apache::geode::client::serializer::writeObject(output, m_value); + } + + /** Deserialize this object from given DataInput. */ + virtual Serializable* fromData(DataInput& input) { + apache::geode::client::serializer::readObject(input, m_value); + return this; + } + + /** + * Return the classId of the instance being serialized. + * + * This is used by deserialization to determine what instance + * type to create and deserialize into. + */ + virtual int32_t classId() const { return 0; } + + /** + * Return the typeId byte of the instance being serialized. + * + * This is used by deserialization to determine what instance + * type to create and deserialize into. + */ + virtual int8_t typeId() const { return TYPEID; } + + /** Return a string representation of the object. */ + virtual CacheableStringPtr toString() const { + char buffer[STRSIZE + 1]; + gf_sprintf(buffer, SPRINTFSYM, m_value); + return CacheableString::create(buffer); + } + + // CacheableKey methods + + /** Return the hashcode for this key. */ + virtual uint32_t hashcode() const { + return apache::geode::client::serializer::hashcode(m_value); + } + + /** Return true if this key matches other. */ + virtual bool operator==(const CacheableKey& other) const { + if (other.typeId() != TYPEID) { + return false; + } + const CacheableKeyType& otherValue = + static_cast(other); + return apache::geode::client::serializer::equals(m_value, + otherValue.m_value); + } + + /** Return true if this key matches other key value. */ + inline bool operator==(const TObj other) const { + return apache::geode::client::serializer::equals(m_value, other); + } + + /** + * Copy the string form of the object into a char* buffer for + * logging purposes. + */ + virtual int32_t logString(char* buffer, int32_t maxLength) const { + char fmt[64]; + gf_sprintf(fmt, "%s( %s )", TYPENAME, SPRINTFSYM); + return gf_snprintf(buffer, maxLength, fmt, m_value); + } + + /** + * Return the size in bytes of the instance being serialized. + * + * This is used to determine whether the cache is using up more + * physical memory than it has been configured to use. The method can + * return zero if the user does not require the ability to control + * cache memory utilization. + */ + virtual uint32_t objectSize() const { return sizeof(CacheableKeyType); } +}; + +// Forward declaration for SharedArrayPtr +template +class SharedArrayPtr; + +/** Function to copy an array from source to destination. */ +template +inline void copyArray(TObj* dest, const TObj* src, int32_t length) { + memcpy(dest, src, length * sizeof(TObj)); +} + +/** + * Function to copy an array of SharedPtrs from + * source to destination. + */ +template +inline void copyArray(SharedPtr* dest, const SharedPtr* src, + int32_t length) { + for (int32_t index = 0; index < length; index++) { + dest[index] = src[index]; + } +} + +/** + * Function to copy an array of SharedArrayPtrs from + * source to destination. + */ +template +inline void copyArray(SharedArrayPtr* dest, + const SharedArrayPtr* src, int32_t length) { + for (int32_t index = 0; index < length; index++) { + dest[index] = src[index]; + } +} + +/** Template class for array of primitive types. */ +template +class CacheableArrayType : public Cacheable { + protected: + TObj* m_value; + int32_t m_length; + + inline CacheableArrayType() : m_value(NULL), m_length(0) {} + + inline CacheableArrayType(int32_t length) : m_length(length) { + if (length > 0) { + GF_NEW(m_value, TObj[length]); + } + } + + inline CacheableArrayType(TObj* value, int32_t length) + : m_value(value), m_length(length) {} + + inline CacheableArrayType(const TObj* value, int32_t length, bool copy) + : m_value(NULL), m_length(length) { + if (length > 0) { + GF_NEW(m_value, TObj[length]); + copyArray(m_value, value, length); + } + } + + virtual ~CacheableArrayType() { GF_SAFE_DELETE_ARRAY(m_value); } + + private: + // Private to disable copy constructor and assignment operator. + CacheableArrayType(const CacheableArrayType& other) + : m_value(other.m_value), m_length(other.m_length) {} + + CacheableArrayType& operator=(const CacheableArrayType& other) { + return *this; + } + + public: + /** Get the underlying array. */ + inline const TObj* value() const { return m_value; } + + /** Get the length of the array. */ + inline int32_t length() const { return m_length; } + + /** Get the element at given index. */ + inline TObj operator[](uint32_t index) const { + if (static_cast(index) >= m_length) { + throw OutOfRangeException( + "CacheableArray::operator[]: Index out of range."); + } + return m_value[index]; + } + + // Cacheable methods + + /** Serialize this object to the given DataOutput. */ + virtual void toData(DataOutput& output) const { + apache::geode::client::serializer::writeObject(output, m_value, m_length); + } + + /** Deserialize this object from the given DataInput. */ + virtual Serializable* fromData(DataInput& input) { + GF_SAFE_DELETE_ARRAY(m_value); + apache::geode::client::serializer::readObject(input, m_value, m_length); + return this; + } + + /** + * Return the classId of the instance being serialized. + * + * This is used by deserialization to determine what instance + * type to create and deserialize into. + */ + virtual int32_t classId() const { return 0; } + + /** + * Return the typeId byte of the instance being serialized. + * + * This is used by deserialization to determine what instance + * type to create and deserialize into. + */ + virtual int8_t typeId() const { return TYPEID; } + + /** + * Return the size in bytes of the instance being serialized. + * + * This is used to determine whether the cache is using up more + * physical memory than it has been configured to use. The method can + * return zero if the user does not require the ability to control + * cache memory utilization. + */ + virtual uint32_t objectSize() const { + return static_cast( + sizeof(CacheableArrayType) + + apache::geode::client::serializer::objectSize(m_value, m_length)); + } +}; + +/** + * Template class for CacheableArrayType SharedPtr's that adds [] operator + */ +template +class SharedArrayPtr : public SharedPtr > { + private: + typedef CacheableArrayType TArray; + + public: + /** Default constructor. */ + inline SharedArrayPtr() : SharedPtr >() {} + + /** Constructor, given a pointer to array. */ + inline SharedArrayPtr(const TArray* ptr) + : SharedPtr >(ptr) {} + + /** Constructor, given a null SharedBase. */ + inline SharedArrayPtr(const NullSharedBase* ptr) + : SharedPtr >(ptr) {} + + /** Constructor, given another SharedArrayPtr. */ + inline SharedArrayPtr(const SharedArrayPtr& other) + : SharedPtr >(other) {} + + /** Constructor, given another kind of SharedArrayPtr. */ + template + inline SharedArrayPtr(const SharedArrayPtr& other) + : SharedPtr >(other) {} + + /** Constructor, given another SharedPtr. */ + template + inline SharedArrayPtr(const SharedPtr& other) + : SharedPtr >(other) {} + + /** Get the element at given index. */ + inline TObj operator[](uint32_t index) const { + return SharedPtr >::ptr()->operator[]( + index); + } + + /** Deserialize self */ + inline Serializable* fromData(DataInput& input) { + return SharedPtr >::ptr()->fromData(input); + } +}; + +/** Template class for container Cacheable types. */ +template +class CacheableContainerType : public Cacheable, public TBase { + protected: + inline CacheableContainerType() : TBase() {} + + inline CacheableContainerType(const int32_t n) : TBase(n) {} + + public: + // Cacheable methods + + /** Serialize this object to the given DataOutput. */ + virtual void toData(DataOutput& output) const { + apache::geode::client::serializer::writeObject(output, *this); + } + + /** Deserialize this object from the given DataInput. */ + virtual Serializable* fromData(DataInput& input) { + apache::geode::client::serializer::readObject(input, *this); + return this; + } + + /** + * Return the classId of the instance being serialized. + * + * This is used by deserialization to determine what instance + * type to create and deserialize into. + */ + virtual int32_t classId() const { return 0; } + + /** + * Return the typeId byte of the instance being serialized. + * + * This is used by deserialization to determine what instance + * type to create and deserialize into. + */ + virtual int8_t typeId() const { return TYPEID; } + + /** + * Return the size in bytes of the instance being serialized. + * + * This is used to determine whether the cache is using up more + * physical memory than it has been configured to use. The method can + * return zero if the user does not require the ability to control + * cache memory utilization. + */ + virtual uint32_t objectSize() const { + return static_cast( + sizeof(CacheableContainerType) + + apache::geode::client::serializer::objectSize(*this)); + } +}; + +#ifdef _SOLARIS +#define TEMPLATE_EXPORT template class +#else +#ifdef BUILD_CPPCACHE +#define TEMPLATE_EXPORT template class CPPCACHE_EXPORT +#else +#define TEMPLATE_EXPORT extern template class CPPCACHE_EXPORT +#endif +#endif + +// Disable extern template warning on MSVC compiler +#ifdef _MSC_VER +#pragma warning(disable : 4231) +#endif + +#define _GF_CACHEABLE_KEY_TYPE_DEF_(p, k, sz) \ + extern const char tName_##k[]; \ + extern const char tStr_##k[]; \ + TEMPLATE_EXPORT \ + CacheableKeyType; \ + typedef CacheableKeyType _##k; \ + class CPPCACHE_EXPORT k; \ + typedef SharedPtr k##Ptr; + +// use a class instead of typedef for bug #283 +#define _GF_CACHEABLE_KEY_TYPE_(p, k, sz) \ + class CPPCACHE_EXPORT k : public _##k { \ + protected: \ + inline k() : _##k() {} \ + inline k(const p value) : _##k(value) {} \ + \ + public: \ + /** Factory function registered with serialization registry. */ \ + static Serializable* createDeserializable() { return new k(); } \ + /** Factory function to create a new default instance. */ \ + inline static k##Ptr create() { return k##Ptr(new k()); } \ + /** Factory function to create an instance with the given value. */ \ + inline static k##Ptr create(const p value) { \ + return k##Ptr(new k(value)); \ + } \ + }; \ + inline CacheableKeyPtr createKey(const p value) { return k::create(value); } \ + inline CacheablePtr createValue(const p value) { return k::create(value); } + +#define _GF_CACHEABLE_ARRAY_TYPE_DEF_(p, c) \ + TEMPLATE_EXPORT CacheableArrayType; \ + typedef CacheableArrayType _##c; \ + class CPPCACHE_EXPORT c; \ + typedef SharedArrayPtr c##Ptr; + +// use a class instead of typedef for bug #283 +#define _GF_CACHEABLE_ARRAY_TYPE_(p, c) \ + class CPPCACHE_EXPORT c : public _##c { \ + protected: \ + inline c() : _##c() {} \ + inline c(int32_t length) : _##c(length) {} \ + inline c(p* value, int32_t length) : _##c(value, length) {} \ + inline c(const p* value, int32_t length, bool copy) \ + : _##c(value, length, true) {} \ + \ + private: \ + /* Private to disable copy constructor and assignment operator. */ \ + c(const c& other); \ + c& operator=(const c& other); \ + \ + public: \ + /** Factory function registered with serialization registry. */ \ + static Serializable* createDeserializable() { return new c(); } \ + /** Factory function to create a new default instance. */ \ + inline static c##Ptr create() { return c##Ptr(new c()); } \ + /** Factory function to create a cacheable array of given size. */ \ + inline static c##Ptr create(int32_t length) { \ + return c##Ptr(new c(length)); \ + } \ + /** Create a cacheable array copying from the given array. */ \ + inline static c##Ptr create(const p* value, int32_t length) { \ + return (value != NULL ? c##Ptr(new c(value, length, true)) : NULLPTR); \ + } \ + /** \ \ + * \ \ + * \ \ \ + * Create a cacheable array taking ownership of the given array \ \ + * \ \ + * \ \ \ + * without creating a copy. \ \ + * \ \ + * \ \ \ + * \ \ + * \ \ + * \ \ \ + * Note that the application has to ensure that the given array is \ \ + * \ \ + * \ \ \ + * not deleted (apart from this class) and is allocated on the heap \ \ + * \ \ + * \ \ \ + * using the "new" operator. \ \ + * \ \ + * \ \ \ + */ \ + inline static c##Ptr createNoCopy(p* value, int32_t length) { \ + return (value != NULL ? c##Ptr(new c(value, length)) : NULLPTR); \ + } \ + }; + +#define _GF_CACHEABLE_CONTAINER_TYPE_DEF_(p, c) \ + TEMPLATE_EXPORT CacheableContainerType; \ + typedef CacheableContainerType _##c; \ + class CPPCACHE_EXPORT c; \ + typedef SharedPtr c##Ptr; + +// use a class instead of typedef for bug #283 +#define _GF_CACHEABLE_CONTAINER_TYPE_(p, c) \ + class CPPCACHE_EXPORT c : public _##c { \ + protected: \ + inline c() : _##c() {} \ + inline c(const int32_t n) : _##c(n) {} \ + \ + public: \ + /** Iterator for this type. */ \ + typedef p::Iterator Iterator; \ + /** Factory function registered with serialization registry. */ \ + static Serializable* createDeserializable() { return new c(); } \ + /** Factory function to create a default instance. */ \ + inline static c##Ptr create() { return c##Ptr(new c()); } \ + /** Factory function to create an instance with the given size. */ \ + inline static c##Ptr create(const int32_t n) { return c##Ptr(new c(n)); } \ + }; + +// Instantiations for the built-in CacheableKeys + +_GF_CACHEABLE_KEY_TYPE_DEF_(bool, CacheableBoolean, 3); +/** + * An immutable wrapper for booleans that can serve as + * a distributable key object for caching. + */ +_GF_CACHEABLE_KEY_TYPE_(bool, CacheableBoolean, 3); + +_GF_CACHEABLE_ARRAY_TYPE_DEF_(bool, BooleanArray); +/** + * An immutable wrapper for array of booleans that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_ARRAY_TYPE_(bool, BooleanArray); + +_GF_CACHEABLE_KEY_TYPE_DEF_(uint8_t, CacheableByte, 15); +/** + * An immutable wrapper for bytes that can serve as + * a distributable key object for caching. + */ +_GF_CACHEABLE_KEY_TYPE_(uint8_t, CacheableByte, 15); + +_GF_CACHEABLE_KEY_TYPE_DEF_(double, CacheableDouble, 63); +/** + * An immutable wrapper for doubles that can serve as + * a distributable key object for caching. + */ +_GF_CACHEABLE_KEY_TYPE_(double, CacheableDouble, 63); + +_GF_CACHEABLE_KEY_TYPE_DEF_(float, CacheableFloat, 63); +/** + * An immutable wrapper for floats that can serve as + * a distributable key object for caching. + */ +_GF_CACHEABLE_KEY_TYPE_(float, CacheableFloat, 63); + +_GF_CACHEABLE_KEY_TYPE_DEF_(int16_t, CacheableInt16, 15); +/** + * An immutable wrapper for 16-bit integers that can serve as + * a distributable key object for caching. + */ +_GF_CACHEABLE_KEY_TYPE_(int16_t, CacheableInt16, 15); + +_GF_CACHEABLE_KEY_TYPE_DEF_(int32_t, CacheableInt32, 15); +/** + * An immutable wrapper for 32-bit integers that can serve as + * a distributable key object for caching. + */ +_GF_CACHEABLE_KEY_TYPE_(int32_t, CacheableInt32, 15); + +_GF_CACHEABLE_KEY_TYPE_DEF_(int64_t, CacheableInt64, 31); +/** + * An immutable wrapper for 64-bit integers that can serve as + * a distributable key object for caching. + */ +_GF_CACHEABLE_KEY_TYPE_(int64_t, CacheableInt64, 31); + +_GF_CACHEABLE_KEY_TYPE_DEF_(wchar_t, CacheableWideChar, 3); +/** + * An immutable wrapper for wide-characters that can serve as + * a distributable key object for caching. + */ +_GF_CACHEABLE_KEY_TYPE_(wchar_t, CacheableWideChar, 3); + +_GF_CACHEABLE_ARRAY_TYPE_DEF_(wchar_t, CharArray); +/** + * An immutable wrapper for array of wide-characters that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_ARRAY_TYPE_(wchar_t, CharArray); + +// Instantiations for array built-in Cacheables + +_GF_CACHEABLE_ARRAY_TYPE_DEF_(uint8_t, CacheableBytes); +/** + * An immutable wrapper for byte arrays that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_ARRAY_TYPE_(uint8_t, CacheableBytes); + +_GF_CACHEABLE_ARRAY_TYPE_DEF_(double, CacheableDoubleArray); +/** + * An immutable wrapper for array of doubles that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_ARRAY_TYPE_(double, CacheableDoubleArray); + +_GF_CACHEABLE_ARRAY_TYPE_DEF_(float, CacheableFloatArray); +/** + * An immutable wrapper for array of floats that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_ARRAY_TYPE_(float, CacheableFloatArray); + +_GF_CACHEABLE_ARRAY_TYPE_DEF_(int16_t, CacheableInt16Array); +/** + * An immutable wrapper for array of 16-bit integers that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_ARRAY_TYPE_(int16_t, CacheableInt16Array); + +_GF_CACHEABLE_ARRAY_TYPE_DEF_(int32_t, CacheableInt32Array); +/** + * An immutable wrapper for array of 32-bit integers that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_ARRAY_TYPE_(int32_t, CacheableInt32Array); + +_GF_CACHEABLE_ARRAY_TYPE_DEF_(int64_t, CacheableInt64Array); +/** + * An immutable wrapper for array of 64-bit integers that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_ARRAY_TYPE_(int64_t, CacheableInt64Array); + +_GF_CACHEABLE_ARRAY_TYPE_DEF_(CacheableStringPtr, CacheableStringArray); +/** + * An immutable wrapper for array of strings that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_ARRAY_TYPE_(CacheableStringPtr, CacheableStringArray); + +// Instantiations for container types (Vector/HashMap/HashSet) Cacheables + +_GF_CACHEABLE_CONTAINER_TYPE_DEF_(_VectorOfCacheable, CacheableVector); +/** + * A mutable Cacheable vector wrapper that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_CONTAINER_TYPE_(_VectorOfCacheable, CacheableVector); + +_GF_CACHEABLE_CONTAINER_TYPE_DEF_(_HashMapOfCacheable, CacheableHashMap); +/** + * A mutable CacheableKey to Serializable + * hash map that can serve as a distributable object for caching. + */ +_GF_CACHEABLE_CONTAINER_TYPE_(_HashMapOfCacheable, CacheableHashMap); + +_GF_CACHEABLE_CONTAINER_TYPE_DEF_(_HashSetOfCacheableKey, CacheableHashSet); +/** + * A mutable CacheableKey hash set wrapper that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_CONTAINER_TYPE_(_HashSetOfCacheableKey, CacheableHashSet); + +_GF_CACHEABLE_CONTAINER_TYPE_DEF_(_VectorOfCacheable, CacheableArrayList); +/** + * A mutable Cacheable array list wrapper that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_CONTAINER_TYPE_(_VectorOfCacheable, CacheableArrayList); + +// linketlist for JSON formattor issue +_GF_CACHEABLE_CONTAINER_TYPE_DEF_(_VectorOfCacheable, CacheableLinkedList); +/** + * A mutable Cacheable array list wrapper that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_CONTAINER_TYPE_(_VectorOfCacheable, CacheableLinkedList); + +_GF_CACHEABLE_CONTAINER_TYPE_DEF_(_VectorOfCacheable, CacheableStack); +/** + * A mutable Cacheable stack wrapper that can serve as + * a distributable object for caching. + */ +_GF_CACHEABLE_CONTAINER_TYPE_(_VectorOfCacheable, CacheableStack); + +_GF_CACHEABLE_CONTAINER_TYPE_DEF_(_HashMapOfCacheable, CacheableHashTable); +/** + * A mutable CacheableKey to Serializable + * hash map that can serve as a distributable object for caching. + */ +_GF_CACHEABLE_CONTAINER_TYPE_(_HashMapOfCacheable, CacheableHashTable); + +_GF_CACHEABLE_CONTAINER_TYPE_DEF_(_HashMapOfCacheable, + CacheableIdentityHashMap); +/** + * A mutable CacheableKey to Serializable + * hash map that can serve as a distributable object for caching. This is + * provided for compability with java side, though is functionally identical + * to CacheableHashMap i.e. does not provide the semantics of + * java IdentityHashMap. + */ +_GF_CACHEABLE_CONTAINER_TYPE_(_HashMapOfCacheable, CacheableIdentityHashMap); + +_GF_CACHEABLE_CONTAINER_TYPE_DEF_(_HashSetOfCacheableKey, + CacheableLinkedHashSet); +/** + * A mutable CacheableKey hash set wrapper that can serve as + * a distributable object for caching. This is provided for compability + * with java side, though is functionally identical to + * CacheableHashSet i.e. does not provide the predictable + * iteration semantics of java LinkedHashSet. + */ +_GF_CACHEABLE_CONTAINER_TYPE_(_HashSetOfCacheableKey, CacheableLinkedHashSet); +} // namespace client +} // namespace geode +} // namespace apache + +#endif // GEODE_CACHEABLEBUILTINS_H_