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