00001 /* 00002 * Copyright (c) 2000, 2020, Oracle and/or its affiliates. 00003 * 00004 * Licensed under the Universal Permissive License v 1.0 as shown at 00005 * http://oss.oracle.com/licenses/upl. 00006 */ 00007 #ifndef COH_KEY_ASSOCIATED_FILTER_HPP 00008 #define COH_KEY_ASSOCIATED_FILTER_HPP 00009 00010 #include "coherence/lang.ns" 00011 00012 #include "coherence/io/pof/PofReader.hpp" 00013 #include "coherence/io/pof/PofWriter.hpp" 00014 #include "coherence/io/pof/PortableObject.hpp" 00015 #include "coherence/util/Filter.hpp" 00016 00017 COH_OPEN_NAMESPACE3(coherence,util,filter) 00018 00019 using coherence::io::pof::PofReader; 00020 using coherence::io::pof::PofWriter; 00021 using coherence::io::pof::PortableObject; 00022 00023 00024 /** 00025 * Filter which limits the scope of another filter according to the key 00026 * association information. 00027 * <p/> 00028 * This filter is intended to be used to optimize queries for partitioned 00029 * caches that utilize any of the key association algorithms (by implementing 00030 * either coherence::net::partition::KeyAssociator or 00031 * coherence::net::cache::KeyAssociation) to ensure placement of 00032 * all associated entries in the same distributed cache partition (and 00033 * therefore in the same storage-enabled cluster node). Using the 00034 * KeyAssociatedFilter will instruct the distributed cache to apply the 00035 * wrapped filter only to the entries stored at the cache service node that 00036 * owns the specified host key. 00037 * 00038 * <b>Note 1:</b> This filter must be the outermost filter and cannot be used 00039 * as a part of any composite filter (AndFilter, OrFilter, etc.) 00040 * 00041 * For example, consider two classes called <i>Parent</i> and <i>Child</i> 00042 * that are stored in separate caches using <i>ParentKey</i> and 00043 * <i>ChildKey</i> objects respectively. The Parent and Child classes have a 00044 * <i>getId</i> method that returns a Long value that uniquely identifies the 00045 * object. Similarly, the ParentKey and ChildKey classes have a <i>getId</i> 00046 * method that uniquely identifies the corresponding cached object. 00047 * Futhermore, the Child and ChildKey classes include a <i>getParentId</i> 00048 * method that returns the Long identifier of the Parent object. 00049 * 00050 * There are two ways to ensure that Child objects are collected with their 00051 * Parent objects (in the same storage-enabled cluster node). 00052 * <ol> 00053 * <li>Make the ChildKey class implement 00054 * coherence::net::cache::KeyAssociation as follows: 00055 * <pre> 00056 * virtual Object::View getAssociatedKey() const 00057 * { 00058 * return getParentId(); 00059 * }</pre> 00060 * and the ParentKey class implement 00061 * coherence::net::cache::KeyAssociation as follows: 00062 * <pre> 00063 * public: virtual Object::View getAssociatedKey() 00064 * { 00065 * return getId(); 00066 * }</pre> 00067 * Note: a Java version of these classes must also exist and contain the same 00068 * logic</li> 00069 * <li>Implement a custom com.tangosol.coherence.net.partition.KeyAssociator 00070 * in Java which will be processed on the cache servers. 00071 * </li> 00072 * </ol> 00073 * The first approach requires a trivial change to the ChildKey and ParentKey 00074 * classes, whereas the second requires a new class and a configuration 00075 * change, but no changes to existing classes. 00076 * <p/> 00077 * Now, to retrieve all the Child objects of a given Parent using an optimized 00078 * query you would do the following: 00079 * <pre> 00080 * ParentKey::Handle parentKey = ParentKey::create(...); 00081 * Integer64::View parentId = parentKey->getId(); 00082 * 00083 * // this Filter will be applied to all Child objects in order to fetch those 00084 * // for which getParentId() returns the specified Parent identifier 00085 * Filter::View filterEq = EqualsFilter::create(ReflectionExtractor::create( 00086 * "getParentId"), parentId); 00087 * 00088 * // this Filter will direct the query to the cluster node that currently 00089 * // owns the Parent object with the given identifier 00090 * Filter::View filterAsc = KeyAssociatedFilter::create(filterEq, parentId); 00091 * 00092 * // run the optimized query to get the ChildKey objects 00093 * Set::View setChildKeys = cacheChildren->keySet(filterAsc); 00094 * 00095 * // get all the Child objects at once 00096 * Set::Handle setChildren = cacheChildren->getAll(setChildKeys); 00097 * </pre> 00098 * To remove the Child objects you would then do the following: 00099 * <pre> 00100 * cacheChildren->keySet()->removeAll(setChildKeys);</pre> 00101 * 00102 * @author djl 2008.05.19 00103 */ 00104 class COH_EXPORT KeyAssociatedFilter 00105 : public class_spec<KeyAssociatedFilter, 00106 extends<Object>, 00107 implements<PortableObject, Filter> > 00108 { 00109 friend class factory<KeyAssociatedFilter>; 00110 00111 // ----- constructors --------------------------------------------------- 00112 00113 protected: 00114 /** 00115 * Default constructor (necessary for the PortableObject interface). 00116 */ 00117 KeyAssociatedFilter(); 00118 00119 /** 00120 * Construct a key associated filter. 00121 * 00122 * @param vFilter the underlying (wrapped) filter 00123 * @param vHostKey the host key that serves as an associated key for 00124 * all keys that the wrapped filter will be applied 00125 * to 00126 */ 00127 KeyAssociatedFilter(Filter::View vFilter, Object::View vHostKey); 00128 00129 00130 // ----- Filter interface ----------------------------------------------- 00131 00132 public: 00133 /** 00134 * {@inheritDoc} 00135 */ 00136 virtual bool evaluate(Object::View v) const; 00137 00138 00139 // ----- PortableObject interface --------------------------------------- 00140 00141 public: 00142 /** 00143 * {@inheritDoc} 00144 */ 00145 virtual void readExternal(PofReader::Handle hIn); 00146 00147 /** 00148 * {@inheritDoc} 00149 */ 00150 virtual void writeExternal(PofWriter::Handle hOut) const; 00151 00152 00153 // ----- Object interface ----------------------------------------------- 00154 00155 public: 00156 /** 00157 * {@inheritDoc} 00158 */ 00159 virtual bool equals(Object::View v) const; 00160 00161 /** 00162 * {@inheritDoc} 00163 */ 00164 virtual size32_t hashCode() const; 00165 00166 /** 00167 * {@inheritDoc} 00168 */ 00169 virtual TypedHandle<const String> toString() const; 00170 00171 00172 // ----- data member accessors ------------------------------------------ 00173 00174 public: 00175 /** 00176 * Obtain the wrapped Filter. 00177 * 00178 * @return the wrapped filter object 00179 */ 00180 virtual Filter::View getFilter() const; 00181 00182 /** 00183 * Obtain the host key that serves as an associated key for all keys 00184 * that the wrapped filter will be applied to. 00185 * 00186 * @return the host key 00187 */ 00188 virtual Object::View getHostKey() const; 00189 00190 00191 // ----- data members --------------------------------------------------- 00192 00193 protected: 00194 /** 00195 * The underlying filter. 00196 */ 00197 FinalView<Filter> f_vFilter; 00198 00199 /** 00200 * The association host key. 00201 */ 00202 FinalView<Object> f_vHostKey; 00203 }; 00204 00205 COH_CLOSE_NAMESPACE3 00206 00207 #endif // COH_KEY_ASSOCIATED_FILTER_HPP