You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by km...@apache.org on 2017/11/28 22:04:25 UTC

[geode] branch develop updated: Revert "GEODE-3063 partition resolver doc revisions (#1077)" (#1096)

This is an automated email from the ASF dual-hosted git repository.

kmiller pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new dd8cb9c  Revert "GEODE-3063 partition resolver doc revisions (#1077)" (#1096)
dd8cb9c is described below

commit dd8cb9c986ee465b5e7a13d7dd503e7728b355b2
Author: Karen Miller <ka...@users.noreply.github.com>
AuthorDate: Tue Nov 28 14:04:22 2017 -0800

    Revert "GEODE-3063 partition resolver doc revisions (#1077)" (#1096)
    
    This reverts commit c18cf175ab4ace9b6eebd1866bbeed9e3e5a9414.
---
 .../colocating_partitioned_region_data.html.md.erb |  41 +--
 ...om_partitioning_and_data_colocation.html.md.erb |  20 +-
 ...om_partitioning_and_data_colocation.html.md.erb |   6 +-
 .../using_custom_partition_resolvers.html.md.erb   | 358 ++++++++-------------
 4 files changed, 161 insertions(+), 264 deletions(-)

diff --git a/geode-docs/developing/partitioned_regions/colocating_partitioned_region_data.html.md.erb b/geode-docs/developing/partitioned_regions/colocating_partitioned_region_data.html.md.erb
index db405d3..962c21e 100644
--- a/geode-docs/developing/partitioned_regions/colocating_partitioned_region_data.html.md.erb
+++ b/geode-docs/developing/partitioned_regions/colocating_partitioned_region_data.html.md.erb
@@ -19,19 +19,27 @@ See the License for the specific language governing permissions and
 limitations under the License.
 -->
 
-By default, <%=vars.product_name%> allocates the data locations for a partitioned region independent of the data locations for any other partitioned region. You can change this policy for any group of partitioned regions, so that cross-region, related data is all hosted by the same member.
-Colocation is required for some operations,
-and it increases performance for others by reducing the number of data
-accesses to entries that are hosted on other cluster members.
+By default, <%=vars.product_name%> allocates the data locations for a partitioned region independent of the data locations for any other partitioned region. You can change this policy for any group of partitioned regions, so that cross-region, related data is all hosted by the same member. This colocation speeds queries and other operations that access data from the regions.
 
 <a id="colocating_partitioned_region_data__section_131EC040055E48A6B35E981B5C845A65"></a>
+**Note:**
+If you are colocating data between regions and custom partitioning the data in the regions, all colocated regions must use partitioning mechanisms that return the same routing object. The most common approach, though not the only one, is for all colocated regions to use the same custom PartitionResolver. See [Custom-Partition Your Region Data](using_custom_partition_resolvers.html).
 
 Data colocation between partitioned regions generally improves the performance of data-intensive operations. You can reduce network hops for iterative operations on related data sets. Compute-heavy applications that are data-intensive can significantly increase overall throughput. For example, a query run on a patient's health records, insurance, and billing information is more efficient if all data is grouped in a single member. Similarly, a financial risk analytical application runs fa [...]
 
+**Prerequisites**
+
+<a id="colocating_partitioned_region_data__section_5A8D752F02834146A37D9430F1CA32DA"></a>
+
+-   Understand how to configure and create your partitioned regions. See [Understanding Partitioning](how_partitioning_works.html) and [Configuring Partitioned Regions](managing_partitioned_regions.html#configure_partitioned_regions).
+-   (Optional) Understand how to custom-partition your data. See [Custom-Partition Your Region Data](using_custom_partition_resolvers.html).
+-   (Optional) If you want your colocated regions to be highly available, understand how high availability for partitioned regions works. See [Understanding High Availability for Partitioned Regions](how_pr_ha_works.html#how_pr_ha_works).
+-   (Optional) Understand how to persist your region data. See [Configure Region Persistence and Overflow](../storing_data_on_disk/storing_data_on_disk.html).
+
 **Procedure**
 
 1.  Identify one region as the central region, with which data in the other regions is explicitly colocated. If you use persistence for any of the regions, you must persist the central region.
-    1.  Create the central region before you create the others, either in the `cache.xml` or your code. Regions in the XML are created before regions in the code, so if you create any of your colocated regions in the XML, you must create the central region in the XML before the others. <%=vars.product_name%> will verify its existence when the others are created and return `IllegalStateException` if the central region is not there. Do not add any colocation specifications to this central region.
+    1.  Create the central region before you create the others, either in the cache.xml or your code. Regions in the XML are created before regions in the code, so if you create any of your colocated regions in the XML, you must create the central region in the XML before the others. <%=vars.product_name%> will verify its existence when the others are created and return `IllegalStateException` if the central region is not there. Do not add any colocation specifications to this central region.
     2.  For all other regions, in the region partition attributes, provide the central region's name in the `colocated-with` attribute. Use one of these methods:
         -   XML:
 
@@ -57,13 +65,10 @@ Data colocation between partitioned regions generally improves the performance o
 
             ``` pre
             PartitionAttributes attrs = ...
-            Region trades = new RegionFactory().setPartitionAttributes(attrs)
-                .create("trades");
+            Region trades = new RegionFactory().setPartitionAttributes(attrs).create("trades");
             ...
-            attrs = new PartitionAttributesFactory().setColocatedWith(trades.getFullPath())
-                .create();
-            Region trade_history = new RegionFactory().setPartitionAttributes(attrs)
-                .create("trade_history");
+            attrs = new PartitionAttributesFactory().setColocatedWith(trades.getFullPath()).create();
+            Region trade_history = new RegionFactory().setPartitionAttributes(attrs).create("trade_history");
             ```
         -   gfsh:
 
@@ -78,7 +83,7 @@ Data colocation between partitioned regions generally improves the performance o
     -   `startup-recovery-delay`
     -   `total-num-buckets`
 
-3.  If you custom partition your region data, specify the custom resolver for all colocated regions. This example uses the same partition resolver for both regions:
+3.  If you custom partition your region data, provide the same custom resolver to all colocated regions:
     -   XML:
 
         ``` pre
@@ -110,18 +115,14 @@ Data colocation between partitioned regions generally improves the performance o
         PartitionAttributes attrs = 
             new PartitionAttributesFactory()
             .setPartitionResolver(resolver).create();
-        Region trades = new RegionFactory().setPartitionAttributes(attrs)
-            .create("trades");
+        Region trades = new RegionFactory().setPartitionAttributes(attrs).create("trades");
         attrs = new PartitionAttributesFactory()
-            .setColocatedWith(trades.getFullPath()).setPartitionResolver(resolver)
-            .create();
-        Region trade_history = new RegionFactory().setPartitionAttributes(attrs)
-            .create("trade_history");
+            .setColocatedWith(trades.getFullPath()).setPartitionResolver(resolver).create();
+        Region trade_history = new RegionFactory().setPartitionAttributes(attrs).create("trade_history");
         ```
     -   gfsh:
 
-        Specify a partition resolver as described in the configuration
-        section of [Custom-Partition Your Region Data](using_custom_partition_resolvers.html).
+        You cannot specify a partition resolver using gfsh.
 
 4.  If you want to persist data in the colocated regions, persist the central region and then persist the other regions as needed. Use the same disk store for all of the colocated regions that you persist.
 
diff --git a/geode-docs/developing/partitioned_regions/custom_partitioning_and_data_colocation.html.md.erb b/geode-docs/developing/partitioned_regions/custom_partitioning_and_data_colocation.html.md.erb
index fd2ca65..62e5cab 100644
--- a/geode-docs/developing/partitioned_regions/custom_partitioning_and_data_colocation.html.md.erb
+++ b/geode-docs/developing/partitioned_regions/custom_partitioning_and_data_colocation.html.md.erb
@@ -31,28 +31,24 @@ This figure shows a region with customer data that is grouped into buckets by cu
 
 <img src="../../images_svg/custom_partitioned.svg" id="custom_partitioning_and_data_colocation__image_1D37D547D3244171BB9CADAEC88E7649" class="image" />
 
-With custom partitioning, you have two choices:
+With custom partitioning, you have three choices:
 
--   **Standard custom partitioning**. With standard partitioning, you group entries into buckets, but you do not specify where the buckets reside. <%=vars.product_name%> always keeps the entries in the buckets you have specified, but may move the buckets around for load balancing.
-The partition resolver provided with <%=vars.product_name%>
-at `org.apache.geode.cache.util.StringPrefixPartitionResolver`
+-   **Default string-based partition resolver**. A default partition
+resolver at `org.apache.geode.cache.util.StringPrefixPartitionResolver`
 groups entries into buckets based on a string portion of the key.
 All keys must be strings, specified with a syntax that includes
 a '|' character that delimits the string.
 The substring that precedes the '|' delimiter within the key
-will be returned by `getRoutingObject`.
--   **Fixed custom partitioning**. With fixed partitioning,
-you specify the exact member where each region entry resides.
-You assign an entry to a partition and then to a bucket within
-that partition.
-You name specific members as primary and secondary hosts of each partition.
+partitions the entry.  
+-   **Standard custom partitioning**. With standard partitioning, you group entries into buckets, but you do not specify where the buckets reside. <%=vars.product_name%> always keeps the entries in the buckets you have specified, but may move the buckets around for load balancing.
+-   **Fixed custom partitioning**. With fixed partitioning, you provide standard partitioning plus you specify the exact member where each data entry resides. You do this by assigning the data entry to a bucket and to a partition and by naming specific members as primary and secondary hosts of each partition.
 
     This gives you complete control over the locations of your primary and any secondary buckets for the region. This can be useful when you want to store specific data on specific physical machines or when you need to keep data close to certain hardware elements.
 
     Fixed partitioning has these requirements and caveats:
 
-    -   <%=vars.product_name%> cannot rebalance fixed partition region data, because it cannot move the buckets around among the host members. You must carefully consider your expected data loads for the partitions you create.
-    -   With fixed partitioning, the region configuration is different between host members. Each member identifies the named partitions it hosts, and whether it is hosting the primary copy or a secondary copy. You then program a fixed-partition resolver to return the partition id, so the entry is placed on the right members. Only one member can be primary for a particular partition name, and that member cannot be the partition's secondary.
+    -   <%=vars.product_name%> cannot rebalance fixed partition region data because it cannot move the buckets around among the host members. You must carefully consider your expected data loads for the partitions you create.
+    -   With fixed partitioning, the region configuration is different between host members. Each member identifies the named partitions it hosts, and whether it is hosting the primary copy or a secondary copy. You then program fixed partition resolver to return the partition id, so the entry is placed on the right members. Only one member can be primary for a particular partition name and that member cannot be the partition's secondary.
 
 ## <a id="custom_partitioning_and_data_colocation__section_D2C66951FE38426F9C05050D2B9028D8" class="no-quick-link"></a>Data Colocation Between Regions
 
diff --git a/geode-docs/developing/partitioned_regions/overview_custom_partitioning_and_data_colocation.html.md.erb b/geode-docs/developing/partitioned_regions/overview_custom_partitioning_and_data_colocation.html.md.erb
index 1dd3d05..b2ebc08 100644
--- a/geode-docs/developing/partitioned_regions/overview_custom_partitioning_and_data_colocation.html.md.erb
+++ b/geode-docs/developing/partitioned_regions/overview_custom_partitioning_and_data_colocation.html.md.erb
@@ -31,8 +31,6 @@ You can customize how <%=vars.product_name_long%> groups your partitioned region
 
 -   **[Colocate Data from Different Partitioned Regions](colocating_partitioned_region_data.html)**
 
-    By default, <%=vars.product_name%> allocates the data locations for a partitioned region independent of the data locations for any other partitioned region. You can change this policy for any group of partitioned regions, so that cross-region, related data is all hosted by the same member.
-Colocation is required for some operations,
-and it increases performance for others by reducing the number of data
-accesses to entries that are hosted on other cluster members.
+    By default, <%=vars.product_name%> allocates the data locations for a partitioned region independent of the data locations for any other partitioned region. You can change this policy for any group of partitioned regions, so that cross-region, related data is all hosted by the same member. This colocation speeds queries and other operations that access data from the regions.
+
 
diff --git a/geode-docs/developing/partitioned_regions/using_custom_partition_resolvers.html.md.erb b/geode-docs/developing/partitioned_regions/using_custom_partition_resolvers.html.md.erb
index 1255f48..44b45d8 100644
--- a/geode-docs/developing/partitioned_regions/using_custom_partition_resolvers.html.md.erb
+++ b/geode-docs/developing/partitioned_regions/using_custom_partition_resolvers.html.md.erb
@@ -19,67 +19,47 @@ See the License for the specific language governing permissions and
 limitations under the License.
 -->
 
-By default, <%=vars.product_name%> partitions each data entry into a bucket using a hashing policy on the key. 
-Additionally, the physical location of the key-value pair 
-is abstracted away from the application.
-You can change these policies for a partitioned region by providing
-your own partition resolver.
-The partitioning can go further with a fixed-partition resolver
-that specifies which members host which data buckets.
+By default, <%=vars.product_name%> partitions each data entry into a bucket using a hashing policy on the key. Additionally, the physical location of the key-value pair is abstracted away from the application. You can change these policies for a partitioned region. You can provide your own data partitioning resolver and you can additionally specify which members host which data buckets.
 
 <a id="custom_partition_region_data__section_CF05CE974C9C4AF78430DA55601D2158"></a>
 **Note:**
-If you are both colocating region data and custom partitioning,
-all colocated regions must use the same custom partitioning mechanism.
-See [Colocate Data from Different Partitioned Regions](colocating_partitioned_region_data.html#colocating_partitioned_region_data).
+If you are colocating data between regions and custom partitioning the data in the regions, all colocated regions must use the same custom partitioning mechanism. See [Colocate Data from Different Partitioned Regions](colocating_partitioned_region_data.html#colocating_partitioned_region_data).
 
-To custom-partition your region data, follow two steps:
+<a id="custom_partition_region_data__section_1D7043815DF24308ABE4C78BFDFEE686"></a>
 
-- implement the interface
-- configure the regions
+For the default implementation of string-based partitioning, use `org.apache.geode.cache.util.StringPrefixPartitionResolver`.
+For standard partitioning, use `org.apache.geode.cache.PartitionResolver`. To implement fixed partitioning, use `org.apache.geode.cache.FixedPartitionResolver`.
 
-These steps differ based on which partition resolver is used.
+<a id="custom_partition_region_data__section_5A8D752F02834146A37D9430F1CA32DA"></a>
 
-**Implementing Standard Partitioning**
+**Prerequisites**
 
--   Implement the `org.apache.geode.cache.PartitionResolver` interface
-within one of the following locations,
-listed here in the search order used by <%=vars.product_name%>:
-    -   **Within a custom class**. Specify this class as the partition
-resolver during region creation.
-    -   **Within the key's class**. For keys implemented as objects,
-define the interface within the key's class.
-    -   **Within the cache callback class**. Implement the interface
-within a cache callback's class. When using this implementation,
-any and all `Region` operations must be those that specify the callback
-as a parameter.
+-   Create partitioned regions. See [Understanding Partitioning](how_partitioning_works.html) and [Configuring Partitioned Regions](managing_partitioned_regions.html#configure_partitioned_regions).
+-   Decide whether to use the default implementation of the string-based partitioning, standard custom partitioning, or fixed custom partitioning. See [Understanding Custom Partitioning and Data Colocation](custom_partitioning_and_data_colocation.html#custom_partitioning_and_data_colocation).
+-   If you also want to colocate data from multiple regions, understand how to colocate. See [Colocate Data from Different Partitioned Regions](colocating_partitioned_region_data.html#colocating_partitioned_region_data).
 
--   Implement the resolver's `getName`, `init`, and `close` methods.
+**Procedure**
 
-    A simple implementation of `getName` is
+1.  If using `org.apache.geode.cache.PartitionResolver` (standard partitioning) or `org.apache.geode.cache.FixedPartitionResolver` (fixed partitioning), implement the standard partitioning resolver or the fixed partitioning resolver in one of the following locations, listed here in the search order used by <%=vars.product_name%>:
+    -   **Custom class**. You provide this class as the partition resolver to the region creation.
+    -   **Entry key**. You use the implementing key object for every operation on the region entries.
+    -   **Cache callback argument**. This implementation restricts you to using methods that accept a cache callback argument to manage the region entries. For a full list of the methods that take a callback argument, see the `Region` Javadocs.
 
-    ``` pre
-    return getClass().getName();
-    ```
-
-    The `init` method does any initialization steps upon cache
-    start that relate to the partition resolver's task. 
-
-    The `close` method accomplishes any clean up that must be accomplished
-    before a cache close completes. For example, `close` might close
-    files or connections that the partition resolver opened. 
-
--   Implement the resolver's `getRoutingObject` method to return 
-the routing object for each entry.
-A hash of that returned routing object determines the bucket.
-Therefore, `getRoutingObject` should return an object that,
-when run through its `hashCode`, directs grouped objects to the
-desired bucket.
+    If using the default implementation of the string-based
+partition resolver, `org.apache.geode.cache.util.StringPrefixPartitionResolver`,
+specify all keys with the required syntax.
+Keys are strings, and contain the '|' character as a delimiter.
+The substring that precedes the '|' delimiter will used in the hash
+function that partitions the entry.
+2.  If you need the resolver's `getName` method, program that.
+3.  If *not* using the default implementation of the string-based
+partition resolver,
+program the resolver's `getRoutingObject` method to return the routing object for each entry, based on how you want to group the entries. Give the same routing object to entries you want to group together. <%=vars.product_name%> will place the entries in the same bucket.
 
     **Note:**
     Only fields on the key should be used when creating the routing object. Do not use the value or additional metadata for this purpose.
 
-    For example, here is an implementation on a region key object that groups using the sum of a month and year:
+    For example, here is an implementation on a region key object that groups the entries by month and year:
 
     ``` pre
     Public class TradeKey implements PartitionResolver 
@@ -100,120 +80,116 @@ desired bucket.
     }
     ```
 
-**Implementing the String-Based Partition Resolver**
+4.  For fixed partitioning only, program and configure additional fixed partitioning pieces:
+    1.  Set the fixed partition attributes for each member.
 
-The implementation of a string-based partition resolver is in
-`org.apache.geode.cache.util.StringPrefixPartitionResolver`.
-It does not require any further implementation.
+        These attributes define the data stored for the region by the member and must be different for different members. See `org.apache.geode.cache.FixedPartitionAttributes` for definitions of the attributes. Define each `partition-name` in your data host members for the region. For each partition name, in the member you want to host the primary copy, define it with `is-primary` set to `true`. In every member you want to host the secondary copy, define it with `is-primary` set to `fals [...]
 
+        **Note:**
+        Buckets for a partition are hosted only by the members that have defined the partition name in their `FixedPartitionAttributes`.
 
-**Implementing Fixed Partitioning**
+        These examples set the partition attributes for a member to be the primary host for the "Q1" partition data and a secondary host for "Q3" partition data.
+        -   XML:
 
--   Implement the `org.apache.geode.cache.FixedPartitionResolver`
-interface within one of the following locations,
-listed here in the search order used by <%=vars.product_name%>:
-    -   **Custom class**. Specify this class as the partition resolver during region creation.
-    -   **Entry key**. For keys implemented as objects, define the interface for the key's class.
-    -   **Within the cache callback class**. Implement the interface
-within a cache callback's class. When using this implementation,
-any and all `Region` operations must be those that specify the callback
-as a parameter.
+            ``` pre
+            <cache>
+               <region name="Trades">
+                  <region-attributes>
+                     <partition-attributes redundant-copies="1">
+                       <partition-resolver name="QuarterFixedPartitionResolver">
+                          <class-name>myPackage.QuarterFixedPartitionResolver</class-name>
+                       </partition-resolver>
+                       <fixed-partition-attributes partition-name="Q1" is-primary="true"/>
+                       <fixed-partition-attributes partition-name="Q3" is-primary="false" num-buckets="6"/>
+                     </partition-attributes> 
+                  </region-attributes>
+               </region>
+            </cache>
+            ```
+        -   Java:
 
--   Implement the resolver's `getName`, `init`, and `close` methods.
 
-    A simple implementation of `getName` is
+            ``` pre
+            FixedPartitionAttribute fpa1 = FixedPartitionAttributes.createFixedPartition("Q1", true);
+            FixedPartitionAttribute fpa3 = FixedPartitionAttributes.createFixedPartition("Q3", false, 6);
 
-    ``` pre
-    return getClass().getName();
-    ```
+            PartitionAttributesFactory paf = new PartitionAttributesFactory()
+                 .setPartitionResolver(new QuarterFixedPartitionResolver())
+                 .setTotalNumBuckets(12)
+                 .setRedundantCopies(2)
+                 .addFixedPartitionAttribute(fpa1)
+                 .addFixedPartitionAttribute(fpa3);
 
-    The `init` method does any initialization steps upon cache
-    start that relate to the partition resolver's task. 
+            Cache c = new CacheFactory().create();
 
-    The `close` method accomplishes any clean up that must be accomplished
-    before a cache close completes. For example, `close` might close
-    files or connections that the partition resolver opened. 
+            Region r = c.createRegionFactory()
+                .setPartitionAttributes(paf.create())
+                .create("Trades");
+            ```
+        -   gfsh:
 
--   Implement the resolver's `getRoutingObject` method to return 
-the routing object for each entry.
-A hash of that returned routing object determines the bucket
-within a partition.
-   
-    This method can be empty for fixed partitioning where there is
-only one bucket per partition.
-That implementation assigns partitions to servers
-such that the application has full control of grouping entries
-on servers.
+            You cannot specify a partition resolver using gfsh.
 
-    **Note:**
-    Only fields on the key should be used when creating the routing object. Do not use the value or additional metadata for this purpose.
+    2.  Program the `FixedPartitionResolver` `getPartitionName` method to return the name of the partition for each entry, based on where you want the entries to reside. <%=vars.product_name%> uses `getPartitionName` and `getRoutingObject` to determine where an entry is placed.
 
--   Implement the `getPartitionName` method 
-to return the name of the partition for each entry,
-based on where you want the entries to reside.
-All entries within a partition will be on a single server.
+        **Note:**
+        To group entries, assign every entry in the group the same routing object and the same partition name.
 
-    This example places the data based on date, with a different partition name for each quarter-year and a different routing object for each month.
+        This example places the data based on date, with a different partition name for each quarter-year and a different routing object for each month.
 
-    ``` pre
-    /**
-     * Returns one of four different partition names
-     * (Q1, Q2, Q3, Q4) depending on the entry's date
-     */
-    class QuarterFixedPartitionResolver implements
-        FixedPartitionResolver<String, String> {
-
-      @Override
-      public String getPartitionName(EntryOperation<String, String> opDetails,
-          Set<String> targetPartitions) {
-
-         Date date = (Date)opDetails.getKey();
-         Calendar cal = Calendar.getInstance();
-         cal.setTime(date);
-         int month = cal.get(Calendar.MONTH);
-         if (month >= 0 && month < 3) {
-            if (targetPartitions.contains("Q1")) return "Q1";
-         }
-         else if (month >= 3 && month < 6) {
-            if (targetPartitions.contains("Q2")) return "Q2";
-         }
-         else if (month >= 6 && month < 9) {
-            if (targetPartitions.contains("Q3")) return "Q3";
-         }
-         else if (month >= 9 && month < 12) {
-            if (targetPartitions.contains("Q4")) return "Q4";
-         }
-         return "Invalid Quarter";
-      }
-
-      @Override
-      public String getName() {
-         return "QuarterFixedPartitionResolver";
-      }
-
-      @Override
-      public Serializable getRoutingObject(EntryOperation<String, String> opDetails) {
-         Date date = (Date)opDetails.getKey();
-         Calendar cal = Calendar.getInstance();
-         cal.setTime(date);
-         int month = cal.get(Calendar.MONTH);
-         return month;
-      }
-
-      @Override
-      public void close() {
-      }
-    }
-    ```
-
-**Configuring Standard Partitioning**
+        ``` pre
+        /**
+         * Returns one of four different partition names
+         * (Q1, Q2, Q3, Q4) depending on the entry's date
+         */
+        class QuarterFixedPartitionResolver implements
+            FixedPartitionResolver<String, String> {
+
+          @Override
+          public String getPartitionName(EntryOperation<String, String> opDetails,
+              Set<String> targetPartitions) {
+
+             Date date = (Date)opDetails.getKey();
+             Calendar cal = Calendar.getInstance();
+             cal.setTime(date);
+             int month = cal.get(Calendar.MONTH);
+             if (month >= 0 && month < 3) {
+                if (targetPartitions.contains("Q1")) return "Q1";
+             }
+             else if (month >= 3 && month < 6) {
+                if (targetPartitions.contains("Q2")) return "Q2";
+             }
+             else if (month >= 6 && month < 9) {
+                if (targetPartitions.contains("Q3")) return "Q3";
+             }
+             else if (month >= 9 && month < 12) {
+                if (targetPartitions.contains("Q4")) return "Q4";
+             }
+             return "Invalid Quarter";
+          }
+
+          @Override
+          public String getName() {
+             return "QuarterFixedPartitionResolver";
+          }
+
+          @Override
+          public Serializable getRoutingObject(EntryOperation<String, String> opDetails) {
+             Date date = (Date)opDetails.getKey();
+             Calendar cal = Calendar.getInstance();
+             cal.setTime(date);
+             int month = cal.get(Calendar.MONTH);
+             return month;
+          }
+
+          @Override
+          public void close() {
+          }
+        }
+        ```
 
--   Configure the region so <%=vars.product_name%> finds your resolver
-for all region operations.
-How you do this depends on where you chose to implement
-your custom partitioning.
-    -   **Custom class**. Define the class for the region at creation.
-Use one of these methods:
+5.  Configure or program the region so <%=vars.product_name%> finds your resolver for every operation that you perform on the region's entries. How you do this depends on where you chose to program your custom partitioning implementation (step 1).
+    -   **Custom class**. Define the class for the region at creation. The resolver will be used for every entry operation. Use one of these methods:
 
         **XML:**
 
@@ -221,7 +197,7 @@ Use one of these methods:
         <region name="trades">
             <region-attributes>
                 <partition-attributes>
-                    <partition-resolver> 
+                    <partition-resolver name="TradesPartitionResolver"> 
                         <class-name>myPackage.TradesPartitionResolver
                         </class-name>
                     </partition-resolver>
@@ -250,25 +226,15 @@ Use one of these methods:
     -   **Entry key**. Use the key object with the resolver implementation for every entry operation.
     -   **Cache callback argument**. Provide the argument to every call that accesses an entry. This restricts you to calls that take a callback argument.
 
--   If your colocated data is in a server system,
-add the `PartitionResolver` implementation class to the `CLASSPATH`
-of your Java clients. 
-For Java single-hop access to work,
-the resolver class needs to have a zero-argument constructor,
-and the resolver class must not have any state;
-the `init` method is included in this restriction.
-
-**Configuring the String-Based Partition Resolver**
-
-- Define the class for the region at creation. The resolver will be used for every entry operation. Use one of these methods:
+    If using the default implementation of the string-based partition resolver, configure with one of:
 
     **XML:**
-    
+
     ``` pre
     <region name="customers">
         <region-attributes>
             <partition-attributes>
-                <partition-resolver> 
+                <partition-resolver name="StringPrefixPartitionResolver"> 
                     <class-name>org.apache.geode.cache.util.StringPrefixPartitionResolver
                     </class-name>
                 </partition-resolver>
@@ -277,85 +243,21 @@ the `init` method is included in this restriction.
     </region>
     ```
     **Java API:**
-    
+
     ``` pre
     PartitionAttributes attrs = 
         new PartitionAttributesFactory()
         .setPartitionResolver("StringPrefixPartitionResolver").create();
-    
+
     Cache c = new CacheFactory().create();
-    
+
     Region r = c.createRegionFactory()
         .setPartitionAttributes(attrs)
         .create("customers");
     ```
     **gfsh:**
-    
-    Add the option `--partition-resolver=org.apache.geode.cache.util.StringPrefixPartitionResolver` to the `gfsh create region` command.
-
--  For colocated data, add the `StringPrefixPartitionResolver`
-implementation class to the `CLASSPATH` of your Java clients.
-The resolver will work with Java single-hop clients.
-
-**Configuring Fixed Partitioning**
-
--  Set the fixed-partition attributes for each member.
-
-    These attributes define the data stored for the region by the member and must be different for different members. See `org.apache.geode.cache.FixedPartitionAttributes` for definitions of the attributes. Define each `partition-name` in your data-host members for the region. For each partition name, in the member you want to host the primary copy, define it with `is-primary` set to `true`. In every member you want to host the secondary copy, define it with `is-primary` set to `false` ( [...]
 
-    **Note:**
-    Buckets for a partition are hosted only by the members that have defined the partition name in their `FixedPartitionAttributes`.
-
-    These examples set the partition attributes for a member to be the primary host for the "Q1" partition data and a secondary host for "Q3" partition data.
-    -   XML:
-
-        ``` pre
-        <cache>
-           <region name="Trades">
-              <region-attributes>
-                 <partition-attributes redundant-copies="1">
-                   <partition-resolver>
-                      <class-name>myPackage.QuarterFixedPartitionResolver</class-name>
-                   </partition-resolver>
-                   <fixed-partition-attributes partition-name="Q1" is-primary="true"/>
-                   <fixed-partition-attributes partition-name="Q3" is-primary="false"
-                        num-buckets="6"/>
-                 </partition-attributes> 
-              </region-attributes>
-           </region>
-        </cache>
-        ```
-    -   Java:
-
-
-        ``` pre
-        FixedPartitionAttribute fpa1 = FixedPartitionAttributes
-             .createFixedPartition("Q1", true);
-        FixedPartitionAttribute fpa3 = FixedPartitionAttributes
-             .createFixedPartition("Q3", false, 6);
-
-        PartitionAttributesFactory paf = new PartitionAttributesFactory()
-             .setPartitionResolver(new QuarterFixedPartitionResolver())
-             .setTotalNumBuckets(12)
-             .setRedundantCopies(2)
-             .addFixedPartitionAttribute(fpa1)
-             .addFixedPartitionAttribute(fpa3);
-
-        Cache c = new CacheFactory().create();
-
-        Region r = c.createRegionFactory()
-            .setPartitionAttributes(paf.create())
-            .create("Trades");
-        ```
-    -   gfsh:
-
-        You cannot specify a fixed partition resolver using gfsh.
+    Add the option `--partition-resolver=org.apache.geode.cache.util.StringPrefixPartitionResolver` to the `gfsh create region` command.
 
--   If your colocated data is in a server system,
-add the class that implements the `FixedPartitionResolver` interface
-to the `CLASSPATH` of your Java clients.
-For Java single-hop access to work,
-the resolver class needs to have a zero-argument constructor,
-and the resolver class must not have any state;
-the `init` method is included in this restriction.
+6.  If your colocated data is in a server system, add the `PartitionResolver` implementation class to the `CLASSPATH` of your Java clients. The resolver is used for single hop access to partitioned region data in the servers.
 

-- 
To stop receiving notification emails like this one, please contact
['"commits@geode.apache.org" <co...@geode.apache.org>'].