http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
index 0b2b607..17f7ee5 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
@@ -60,7 +60,7 @@ public abstract class MetaDataProtocol extends 
MetaDataService {
     public static final long MIN_TABLE_TIMESTAMP = 0;
 
     // Incremented from 3 to 4 to salt the sequence table in 3.2/4.2
-    public static final long MIN_SYSTEM_TABLE_TIMESTAMP = MIN_TABLE_TIMESTAMP 
+ 5;
+    public static final long MIN_SYSTEM_TABLE_TIMESTAMP = MIN_TABLE_TIMESTAMP 
+ 6;
     public static final int DEFAULT_MAX_META_DATA_VERSIONS = 1000;
     public static final int DEFAULT_MAX_STAT_DATA_VERSIONS = 3;
     public static final boolean DEFAULT_META_DATA_KEEP_DELETED_CELLS = true;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PGuidePostsProtos.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PGuidePostsProtos.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PGuidePostsProtos.java
new file mode 100644
index 0000000..9f96530
--- /dev/null
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PGuidePostsProtos.java
@@ -0,0 +1,732 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: PGuidePosts.proto
+
+package org.apache.phoenix.coprocessor.generated;
+
+public final class PGuidePostsProtos {
+  private PGuidePostsProtos() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface PGuidePostsOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // repeated bytes guidePosts = 1;
+    /**
+     * <code>repeated bytes guidePosts = 1;</code>
+     */
+    java.util.List<com.google.protobuf.ByteString> getGuidePostsList();
+    /**
+     * <code>repeated bytes guidePosts = 1;</code>
+     */
+    int getGuidePostsCount();
+    /**
+     * <code>repeated bytes guidePosts = 1;</code>
+     */
+    com.google.protobuf.ByteString getGuidePosts(int index);
+
+    // optional int64 byteCount = 2;
+    /**
+     * <code>optional int64 byteCount = 2;</code>
+     */
+    boolean hasByteCount();
+    /**
+     * <code>optional int64 byteCount = 2;</code>
+     */
+    long getByteCount();
+
+    // optional int64 rowCount = 3;
+    /**
+     * <code>optional int64 rowCount = 3;</code>
+     */
+    boolean hasRowCount();
+    /**
+     * <code>optional int64 rowCount = 3;</code>
+     */
+    long getRowCount();
+  }
+  /**
+   * Protobuf type {@code PGuidePosts}
+   */
+  public static final class PGuidePosts extends
+      com.google.protobuf.GeneratedMessage
+      implements PGuidePostsOrBuilder {
+    // Use PGuidePosts.newBuilder() to construct.
+    private PGuidePosts(com.google.protobuf.GeneratedMessage.Builder<?> 
builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private PGuidePosts(boolean noInit) { this.unknownFields = 
com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final PGuidePosts defaultInstance;
+    public static PGuidePosts getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public PGuidePosts getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PGuidePosts(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+                guidePosts_ = new 
java.util.ArrayList<com.google.protobuf.ByteString>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              guidePosts_.add(input.readBytes());
+              break;
+            }
+            case 16: {
+              bitField0_ |= 0x00000001;
+              byteCount_ = input.readInt64();
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000002;
+              rowCount_ = input.readInt64();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+          guidePosts_ = java.util.Collections.unmodifiableList(guidePosts_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.internal_static_PGuidePosts_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.internal_static_PGuidePosts_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.class, 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<PGuidePosts> PARSER =
+        new com.google.protobuf.AbstractParser<PGuidePosts>() {
+      public PGuidePosts parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PGuidePosts(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PGuidePosts> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // repeated bytes guidePosts = 1;
+    public static final int GUIDEPOSTS_FIELD_NUMBER = 1;
+    private java.util.List<com.google.protobuf.ByteString> guidePosts_;
+    /**
+     * <code>repeated bytes guidePosts = 1;</code>
+     */
+    public java.util.List<com.google.protobuf.ByteString>
+        getGuidePostsList() {
+      return guidePosts_;
+    }
+    /**
+     * <code>repeated bytes guidePosts = 1;</code>
+     */
+    public int getGuidePostsCount() {
+      return guidePosts_.size();
+    }
+    /**
+     * <code>repeated bytes guidePosts = 1;</code>
+     */
+    public com.google.protobuf.ByteString getGuidePosts(int index) {
+      return guidePosts_.get(index);
+    }
+
+    // optional int64 byteCount = 2;
+    public static final int BYTECOUNT_FIELD_NUMBER = 2;
+    private long byteCount_;
+    /**
+     * <code>optional int64 byteCount = 2;</code>
+     */
+    public boolean hasByteCount() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>optional int64 byteCount = 2;</code>
+     */
+    public long getByteCount() {
+      return byteCount_;
+    }
+
+    // optional int64 rowCount = 3;
+    public static final int ROWCOUNT_FIELD_NUMBER = 3;
+    private long rowCount_;
+    /**
+     * <code>optional int64 rowCount = 3;</code>
+     */
+    public boolean hasRowCount() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional int64 rowCount = 3;</code>
+     */
+    public long getRowCount() {
+      return rowCount_;
+    }
+
+    private void initFields() {
+      guidePosts_ = java.util.Collections.emptyList();
+      byteCount_ = 0L;
+      rowCount_ = 0L;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      for (int i = 0; i < guidePosts_.size(); i++) {
+        output.writeBytes(1, guidePosts_.get(i));
+      }
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeInt64(2, byteCount_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeInt64(3, rowCount_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      {
+        int dataSize = 0;
+        for (int i = 0; i < guidePosts_.size(); i++) {
+          dataSize += com.google.protobuf.CodedOutputStream
+            .computeBytesSizeNoTag(guidePosts_.get(i));
+        }
+        size += dataSize;
+        size += 1 * getGuidePostsList().size();
+      }
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(2, byteCount_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt64Size(3, rowCount_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts)) {
+        return super.equals(obj);
+      }
+      org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
other = 
(org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts) obj;
+
+      boolean result = true;
+      result = result && getGuidePostsList()
+          .equals(other.getGuidePostsList());
+      result = result && (hasByteCount() == other.hasByteCount());
+      if (hasByteCount()) {
+        result = result && (getByteCount()
+            == other.getByteCount());
+      }
+      result = result && (hasRowCount() == other.hasRowCount());
+      if (hasRowCount()) {
+        result = result && (getRowCount()
+            == other.getRowCount());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (getGuidePostsCount() > 0) {
+        hash = (37 * hash) + GUIDEPOSTS_FIELD_NUMBER;
+        hash = (53 * hash) + getGuidePostsList().hashCode();
+      }
+      if (hasByteCount()) {
+        hash = (37 * hash) + BYTECOUNT_FIELD_NUMBER;
+        hash = (53 * hash) + hashLong(getByteCount());
+      }
+      if (hasRowCount()) {
+        hash = (37 * hash) + ROWCOUNT_FIELD_NUMBER;
+        hash = (53 * hash) + hashLong(getRowCount());
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder 
newBuilder(org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts
 prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code PGuidePosts}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePostsOrBuilder 
{
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.internal_static_PGuidePosts_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.internal_static_PGuidePosts_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.class, 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.Builder.class);
+      }
+
+      // Construct using 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        guidePosts_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        byteCount_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        rowCount_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.internal_static_PGuidePosts_descriptor;
+      }
+
+      public 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
getDefaultInstanceForType() {
+        return 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.getDefaultInstance();
+      }
+
+      public 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts build() {
+        org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
buildPartial() {
+        org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
result = new 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          guidePosts_ = java.util.Collections.unmodifiableList(guidePosts_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.guidePosts_ = guidePosts_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.byteCount_ = byteCount_;
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.rowCount_ = rowCount_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts) {
+          return 
mergeFrom((org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder 
mergeFrom(org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts
 other) {
+        if (other == 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.getDefaultInstance())
 return this;
+        if (!other.guidePosts_.isEmpty()) {
+          if (guidePosts_.isEmpty()) {
+            guidePosts_ = other.guidePosts_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureGuidePostsIsMutable();
+            guidePosts_.addAll(other.guidePosts_);
+          }
+          onChanged();
+        }
+        if (other.hasByteCount()) {
+          setByteCount(other.getByteCount());
+        }
+        if (other.hasRowCount()) {
+          setRowCount(other.getRowCount());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = 
(org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts) 
e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // repeated bytes guidePosts = 1;
+      private java.util.List<com.google.protobuf.ByteString> guidePosts_ = 
java.util.Collections.emptyList();
+      private void ensureGuidePostsIsMutable() {
+        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+          guidePosts_ = new 
java.util.ArrayList<com.google.protobuf.ByteString>(guidePosts_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+      /**
+       * <code>repeated bytes guidePosts = 1;</code>
+       */
+      public java.util.List<com.google.protobuf.ByteString>
+          getGuidePostsList() {
+        return java.util.Collections.unmodifiableList(guidePosts_);
+      }
+      /**
+       * <code>repeated bytes guidePosts = 1;</code>
+       */
+      public int getGuidePostsCount() {
+        return guidePosts_.size();
+      }
+      /**
+       * <code>repeated bytes guidePosts = 1;</code>
+       */
+      public com.google.protobuf.ByteString getGuidePosts(int index) {
+        return guidePosts_.get(index);
+      }
+      /**
+       * <code>repeated bytes guidePosts = 1;</code>
+       */
+      public Builder setGuidePosts(
+          int index, com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureGuidePostsIsMutable();
+        guidePosts_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bytes guidePosts = 1;</code>
+       */
+      public Builder addGuidePosts(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureGuidePostsIsMutable();
+        guidePosts_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bytes guidePosts = 1;</code>
+       */
+      public Builder addAllGuidePosts(
+          java.lang.Iterable<? extends com.google.protobuf.ByteString> values) 
{
+        ensureGuidePostsIsMutable();
+        super.addAll(values, guidePosts_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bytes guidePosts = 1;</code>
+       */
+      public Builder clearGuidePosts() {
+        guidePosts_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+        return this;
+      }
+
+      // optional int64 byteCount = 2;
+      private long byteCount_ ;
+      /**
+       * <code>optional int64 byteCount = 2;</code>
+       */
+      public boolean hasByteCount() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional int64 byteCount = 2;</code>
+       */
+      public long getByteCount() {
+        return byteCount_;
+      }
+      /**
+       * <code>optional int64 byteCount = 2;</code>
+       */
+      public Builder setByteCount(long value) {
+        bitField0_ |= 0x00000002;
+        byteCount_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 byteCount = 2;</code>
+       */
+      public Builder clearByteCount() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        byteCount_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // optional int64 rowCount = 3;
+      private long rowCount_ ;
+      /**
+       * <code>optional int64 rowCount = 3;</code>
+       */
+      public boolean hasRowCount() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional int64 rowCount = 3;</code>
+       */
+      public long getRowCount() {
+        return rowCount_;
+      }
+      /**
+       * <code>optional int64 rowCount = 3;</code>
+       */
+      public Builder setRowCount(long value) {
+        bitField0_ |= 0x00000004;
+        rowCount_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional int64 rowCount = 3;</code>
+       */
+      public Builder clearRowCount() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        rowCount_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:PGuidePosts)
+    }
+
+    static {
+      defaultInstance = new PGuidePosts(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:PGuidePosts)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_PGuidePosts_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_PGuidePosts_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\021PGuidePosts.proto\"F\n\013PGuidePosts\022\022\n\ngu" +
+      "idePosts\030\001 \003(\014\022\021\n\tbyteCount\030\002 
\001(\003\022\020\n\010row" +
+      "Count\030\003 \001(\003BE\n(org.apache.phoenix.coproc" +
+      "essor.generatedB\021PGuidePostsProtosH\001\210\001\001\240" +
+      "\001\001"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner 
assigner =
+      new 
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_PGuidePosts_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_PGuidePosts_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_PGuidePosts_descriptor,
+              new java.lang.String[] { "GuidePosts", "ByteCount", "RowCount", 
});
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
index ff2cfe4..1e34bc9 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/generated/PTableProtos.java
@@ -1631,6 +1631,20 @@ public final class PTableProtos {
      * <code>optional int32 guidePostsCount = 5;</code>
      */
     int getGuidePostsCount();
+
+    // optional .PGuidePosts pGuidePosts = 6;
+    /**
+     * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+     */
+    boolean hasPGuidePosts();
+    /**
+     * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+     */
+    org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
getPGuidePosts();
+    /**
+     * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+     */
+    
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePostsOrBuilder 
getPGuidePostsOrBuilder();
   }
   /**
    * Protobuf type {@code PTableStats}
@@ -1711,6 +1725,19 @@ public final class PTableProtos {
               guidePostsCount_ = input.readInt32();
               break;
             }
+            case 50: {
+              
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.Builder 
subBuilder = null;
+              if (((bitField0_ & 0x00000010) == 0x00000010)) {
+                subBuilder = pGuidePosts_.toBuilder();
+              }
+              pGuidePosts_ = 
input.readMessage(org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.PARSER,
 extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(pGuidePosts_);
+                pGuidePosts_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000010;
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -1841,12 +1868,35 @@ public final class PTableProtos {
       return guidePostsCount_;
     }
 
+    // optional .PGuidePosts pGuidePosts = 6;
+    public static final int PGUIDEPOSTS_FIELD_NUMBER = 6;
+    private 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
pGuidePosts_;
+    /**
+     * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+     */
+    public boolean hasPGuidePosts() {
+      return ((bitField0_ & 0x00000010) == 0x00000010);
+    }
+    /**
+     * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+     */
+    public 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
getPGuidePosts() {
+      return pGuidePosts_;
+    }
+    /**
+     * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+     */
+    public 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePostsOrBuilder 
getPGuidePostsOrBuilder() {
+      return pGuidePosts_;
+    }
+
     private void initFields() {
       key_ = com.google.protobuf.ByteString.EMPTY;
       values_ = java.util.Collections.emptyList();
       guidePostsByteCount_ = 0L;
       keyBytesCount_ = 0L;
       guidePostsCount_ = 0;
+      pGuidePosts_ = 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.getDefaultInstance();
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -1879,6 +1929,9 @@ public final class PTableProtos {
       if (((bitField0_ & 0x00000008) == 0x00000008)) {
         output.writeInt32(5, guidePostsCount_);
       }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        output.writeMessage(6, pGuidePosts_);
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -1913,6 +1966,10 @@ public final class PTableProtos {
         size += com.google.protobuf.CodedOutputStream
           .computeInt32Size(5, guidePostsCount_);
       }
+      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, pGuidePosts_);
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -1958,6 +2015,11 @@ public final class PTableProtos {
         result = result && (getGuidePostsCount()
             == other.getGuidePostsCount());
       }
+      result = result && (hasPGuidePosts() == other.hasPGuidePosts());
+      if (hasPGuidePosts()) {
+        result = result && getPGuidePosts()
+            .equals(other.getPGuidePosts());
+      }
       result = result &&
           getUnknownFields().equals(other.getUnknownFields());
       return result;
@@ -1991,6 +2053,10 @@ public final class PTableProtos {
         hash = (37 * hash) + GUIDEPOSTSCOUNT_FIELD_NUMBER;
         hash = (53 * hash) + getGuidePostsCount();
       }
+      if (hasPGuidePosts()) {
+        hash = (37 * hash) + PGUIDEPOSTS_FIELD_NUMBER;
+        hash = (53 * hash) + getPGuidePosts().hashCode();
+      }
       hash = (29 * hash) + getUnknownFields().hashCode();
       memoizedHashCode = hash;
       return hash;
@@ -2092,6 +2158,7 @@ public final class PTableProtos {
       }
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getPGuidePostsFieldBuilder();
         }
       }
       private static Builder create() {
@@ -2110,6 +2177,12 @@ public final class PTableProtos {
         bitField0_ = (bitField0_ & ~0x00000008);
         guidePostsCount_ = 0;
         bitField0_ = (bitField0_ & ~0x00000010);
+        if (pGuidePostsBuilder_ == null) {
+          pGuidePosts_ = 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.getDefaultInstance();
+        } else {
+          pGuidePostsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000020);
         return this;
       }
 
@@ -2159,6 +2232,14 @@ public final class PTableProtos {
           to_bitField0_ |= 0x00000008;
         }
         result.guidePostsCount_ = guidePostsCount_;
+        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
+          to_bitField0_ |= 0x00000010;
+        }
+        if (pGuidePostsBuilder_ == null) {
+          result.pGuidePosts_ = pGuidePosts_;
+        } else {
+          result.pGuidePosts_ = pGuidePostsBuilder_.build();
+        }
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -2197,6 +2278,9 @@ public final class PTableProtos {
         if (other.hasGuidePostsCount()) {
           setGuidePostsCount(other.getGuidePostsCount());
         }
+        if (other.hasPGuidePosts()) {
+          mergePGuidePosts(other.getPGuidePosts());
+        }
         this.mergeUnknownFields(other.getUnknownFields());
         return this;
       }
@@ -2435,6 +2519,123 @@ public final class PTableProtos {
         return this;
       }
 
+      // optional .PGuidePosts pGuidePosts = 6;
+      private 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
pGuidePosts_ = 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts, 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.Builder, 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePostsOrBuilder>
 pGuidePostsBuilder_;
+      /**
+       * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+       */
+      public boolean hasPGuidePosts() {
+        return ((bitField0_ & 0x00000020) == 0x00000020);
+      }
+      /**
+       * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+       */
+      public 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts 
getPGuidePosts() {
+        if (pGuidePostsBuilder_ == null) {
+          return pGuidePosts_;
+        } else {
+          return pGuidePostsBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+       */
+      public Builder 
setPGuidePosts(org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts
 value) {
+        if (pGuidePostsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          pGuidePosts_ = value;
+          onChanged();
+        } else {
+          pGuidePostsBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000020;
+        return this;
+      }
+      /**
+       * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+       */
+      public Builder setPGuidePosts(
+          
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.Builder 
builderForValue) {
+        if (pGuidePostsBuilder_ == null) {
+          pGuidePosts_ = builderForValue.build();
+          onChanged();
+        } else {
+          pGuidePostsBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000020;
+        return this;
+      }
+      /**
+       * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+       */
+      public Builder 
mergePGuidePosts(org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts
 value) {
+        if (pGuidePostsBuilder_ == null) {
+          if (((bitField0_ & 0x00000020) == 0x00000020) &&
+              pGuidePosts_ != 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.getDefaultInstance())
 {
+            pGuidePosts_ =
+              
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.newBuilder(pGuidePosts_).mergeFrom(value).buildPartial();
+          } else {
+            pGuidePosts_ = value;
+          }
+          onChanged();
+        } else {
+          pGuidePostsBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000020;
+        return this;
+      }
+      /**
+       * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+       */
+      public Builder clearPGuidePosts() {
+        if (pGuidePostsBuilder_ == null) {
+          pGuidePosts_ = 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.getDefaultInstance();
+          onChanged();
+        } else {
+          pGuidePostsBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000020);
+        return this;
+      }
+      /**
+       * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+       */
+      public 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.Builder 
getPGuidePostsBuilder() {
+        bitField0_ |= 0x00000020;
+        onChanged();
+        return getPGuidePostsFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+       */
+      public 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePostsOrBuilder 
getPGuidePostsOrBuilder() {
+        if (pGuidePostsBuilder_ != null) {
+          return pGuidePostsBuilder_.getMessageOrBuilder();
+        } else {
+          return pGuidePosts_;
+        }
+      }
+      /**
+       * <code>optional .PGuidePosts pGuidePosts = 6;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts, 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.Builder, 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePostsOrBuilder>
 
+          getPGuidePostsFieldBuilder() {
+        if (pGuidePostsBuilder_ == null) {
+          pGuidePostsBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts, 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts.Builder, 
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePostsOrBuilder>(
+                  pGuidePosts_,
+                  getParentForChildren(),
+                  isClean());
+          pGuidePosts_ = null;
+        }
+        return pGuidePostsBuilder_;
+      }
+
       // @@protoc_insertion_point(builder_scope:PTableStats)
     }
 
@@ -6003,33 +6204,34 @@ public final class PTableProtos {
       descriptor;
   static {
     java.lang.String[] descriptorData = {
-      "\n\014PTable.proto\"\347\001\n\007PColumn\022\027\n\017columnName" +
-      "Bytes\030\001 \002(\014\022\027\n\017familyNameBytes\030\002 
\001(\014\022\020\n\010" +
-      "dataType\030\003 \002(\t\022\021\n\tmaxLength\030\004 
\001(\005\022\r\n\005sca" +
-      "le\030\005 \001(\005\022\020\n\010nullable\030\006 
\002(\010\022\020\n\010position\030\007" +
-      " \002(\005\022\021\n\tsortOrder\030\010 
\002(\005\022\021\n\tarraySize\030\t \001" +
-      "(\005\022\024\n\014viewConstant\030\n 
\001(\014\022\026\n\016viewReferenc" +
-      "ed\030\013 \001(\010\"w\n\013PTableStats\022\013\n\003key\030\001 
\002(\014\022\016\n\006" +
-      "values\030\002 \003(\014\022\033\n\023guidePostsByteCount\030\003 
\001(" +
-      "\003\022\025\n\rkeyBytesCount\030\004 
\001(\003\022\027\n\017guidePostsCo" +
-      "unt\030\005 
\001(\005\"\242\004\n\006PTable\022\027\n\017schemaNameBytes\030",
-      "\001 \002(\014\022\026\n\016tableNameBytes\030\002 
\002(\014\022\036\n\ttableTy" +
-      "pe\030\003 \002(\0162\013.PTableType\022\022\n\nindexState\030\004 
\001(" +
-      "\t\022\026\n\016sequenceNumber\030\005 
\002(\003\022\021\n\ttimeStamp\030\006" +
-      " \002(\003\022\023\n\013pkNameBytes\030\007 
\001(\014\022\021\n\tbucketNum\030\010" +
-      " \002(\005\022\031\n\007columns\030\t 
\003(\0132\010.PColumn\022\030\n\007index" +
-      "es\030\n \003(\0132\007.PTable\022\027\n\017isImmutableRows\030\013 
\002" +
-      "(\010\022 \n\nguidePosts\030\014 
\003(\0132\014.PTableStats\022\032\n\022" +
-      "dataTableNameBytes\030\r \001(\014\022\031\n\021defaultFamil" +
-      "yName\030\016 \001(\014\022\022\n\ndisableWAL\030\017 
\002(\010\022\023\n\013multi" +
-      "Tenant\030\020 \002(\010\022\020\n\010viewType\030\021 
\001(\014\022\025\n\rviewSt",
-      "atement\030\022 \001(\014\022\025\n\rphysicalNames\030\023 
\003(\014\022\020\n\010" +
-      "tenantId\030\024 \001(\014\022\023\n\013viewIndexId\030\025 
\001(\005\022\021\n\ti" +
-      "ndexType\030\026 \001(\014\022\026\n\016statsTimeStamp\030\027 
\001(\003*A" +
-      
"\n\nPTableType\022\n\n\006SYSTEM\020\000\022\010\n\004USER\020\001\022\010\n\004VI"
 +
-      
"EW\020\002\022\t\n\005INDEX\020\003\022\010\n\004JOIN\020\004B@\n(org.apache." 
+
-      "phoenix.coprocessor.generatedB\014PTablePro" +
-      "tosH\001\210\001\001\240\001\001"
+      "\n\014PTable.proto\032\021PGuidePosts.proto\"\347\001\n\007PC" +
+      "olumn\022\027\n\017columnNameBytes\030\001 
\002(\014\022\027\n\017family" +
+      "NameBytes\030\002 \001(\014\022\020\n\010dataType\030\003 
\002(\t\022\021\n\tmax" +
+      "Length\030\004 \001(\005\022\r\n\005scale\030\005 
\001(\005\022\020\n\010nullable\030" +
+      "\006 \002(\010\022\020\n\010position\030\007 
\002(\005\022\021\n\tsortOrder\030\010 \002" +
+      "(\005\022\021\n\tarraySize\030\t 
\001(\005\022\024\n\014viewConstant\030\n " +
+      "\001(\014\022\026\n\016viewReferenced\030\013 
\001(\010\"\232\001\n\013PTableSt" +
+      "ats\022\013\n\003key\030\001 \002(\014\022\016\n\006values\030\002 
\003(\014\022\033\n\023guid" +
+      "ePostsByteCount\030\003 \001(\003\022\025\n\rkeyBytesCount\030\004" +
+      " \001(\003\022\027\n\017guidePostsCount\030\005 
\001(\005\022!\n\013pGuideP",
+      "osts\030\006 
\001(\0132\014.PGuidePosts\"\242\004\n\006PTable\022\027\n\017s" +
+      "chemaNameBytes\030\001 \002(\014\022\026\n\016tableNameBytes\030\002" +
+      " \002(\014\022\036\n\ttableType\030\003 
\002(\0162\013.PTableType\022\022\n\n" +
+      "indexState\030\004 \001(\t\022\026\n\016sequenceNumber\030\005 
\002(\003" +
+      "\022\021\n\ttimeStamp\030\006 
\002(\003\022\023\n\013pkNameBytes\030\007 \001(\014" +
+      "\022\021\n\tbucketNum\030\010 \002(\005\022\031\n\007columns\030\t 
\003(\0132\010.P" +
+      "Column\022\030\n\007indexes\030\n 
\003(\0132\007.PTable\022\027\n\017isIm" +
+      "mutableRows\030\013 \002(\010\022 \n\nguidePosts\030\014 
\003(\0132\014." +
+      "PTableStats\022\032\n\022dataTableNameBytes\030\r \001(\014\022" +
+      "\031\n\021defaultFamilyName\030\016 \001(\014\022\022\n\ndisableWAL",
+      "\030\017 \002(\010\022\023\n\013multiTenant\030\020 
\002(\010\022\020\n\010viewType\030" +
+      "\021 \001(\014\022\025\n\rviewStatement\030\022 
\001(\014\022\025\n\rphysical" +
+      "Names\030\023 \003(\014\022\020\n\010tenantId\030\024 
\001(\014\022\023\n\013viewInd" +
+      "exId\030\025 \001(\005\022\021\n\tindexType\030\026 
\001(\014\022\026\n\016statsTi" +
+      "meStamp\030\027 
\001(\003*A\n\nPTableType\022\n\n\006SYSTEM\020\000\022" +
+      
"\010\n\004USER\020\001\022\010\n\004VIEW\020\002\022\t\n\005INDEX\020\003\022\010\n\004JOIN\020\004"
 +
+      "B@\n(org.apache.phoenix.coprocessor.gener" +
+      "atedB\014PTableProtosH\001\210\001\001\240\001\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner 
assigner =
       new 
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -6047,7 +6249,7 @@ public final class PTableProtos {
           internal_static_PTableStats_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_PTableStats_descriptor,
-              new java.lang.String[] { "Key", "Values", "GuidePostsByteCount", 
"KeyBytesCount", "GuidePostsCount", });
+              new java.lang.String[] { "Key", "Values", "GuidePostsByteCount", 
"KeyBytesCount", "GuidePostsCount", "PGuidePosts", });
           internal_static_PTable_descriptor =
             getDescriptor().getMessageTypes().get(2);
           internal_static_PTable_fieldAccessorTable = new
@@ -6060,6 +6262,7 @@ public final class PTableProtos {
     com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
         new com.google.protobuf.Descriptors.FileDescriptor[] {
+          
org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.getDescriptor(),
         }, assigner);
   }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java 
b/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
index d82e8f4..d0a71f4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
@@ -112,7 +112,8 @@ public class ScanPlan extends BaseQueryPlan {
             estRegionSize = 
StatisticsUtil.getGuidePostDepth(guidepostPerRegion, guidepostWidth, desc);
         } else {
             // Region size estimated based on total number of bytes divided by 
number of regions
-            estRegionSize = gpsInfo.getByteCount() / 
(gpsInfo.getGuidePosts().size()+1);
+            long totByteSize = gpsInfo.getByteCount();
+            estRegionSize = totByteSize / (gpsInfo.getGuidePosts().size()+1);
         }
         // TODO: configurable number of bytes?
         boolean isSerial = (perScanLimit * estRowSize < estRegionSize);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
index ce27dfb..aa6fdf0 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
@@ -249,6 +249,8 @@ public class PhoenixDatabaseMetaData implements 
DatabaseMetaData, org.apache.pho
     public static final byte[] GUIDE_POSTS_COUNT_BYTES = 
Bytes.toBytes(GUIDE_POSTS_COUNT);
     public static final String GUIDE_POSTS_WIDTH = "GUIDE_POSTS_WIDTH";
     public static final byte[] GUIDE_POSTS_WIDTH_BYTES = 
Bytes.toBytes(GUIDE_POSTS_WIDTH);
+    public static final String GUIDE_POSTS_ROW_COUNT = "GUIDE_POSTS_ROW_COUNT";
+    public static final byte[] GUIDE_POSTS_ROW_COUNT_BYTES = 
Bytes.toBytes(GUIDE_POSTS_ROW_COUNT);
     public static final String MIN_KEY = "MIN_KEY";
     public static final byte[] MIN_KEY_BYTES = Bytes.toBytes(MIN_KEY);
     public static final String MAX_KEY = "MAX_KEY";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index 483bedc..3091b54 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -1727,9 +1727,13 @@ public class ConnectionQueryServicesImpl extends 
DelegateQueryServices implement
                                 metaConnection.createStatement().executeUpdate(
                                         
QueryConstants.CREATE_STATS_TABLE_METADATA);
                             } catch (NewerTableAlreadyExistsException ignore) {
-
                             } catch(TableAlreadyExistsException ignore) {
-                                
+                                metaConnection = addColumnsIfNotExists(
+                                        metaConnection,
+                                        
PhoenixDatabaseMetaData.SYSTEM_STATS_NAME,
+                                        
MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP,
+                                        
PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT + " "
+                                                + 
PLong.INSTANCE.getSqlTypeName());
                             }
                         } catch (Exception e) {
                             if (e instanceof SQLException) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
index 38c6139..da893e6 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
@@ -274,7 +274,6 @@ public class ConnectionlessQueryServicesImpl extends 
DelegateQueryServices imple
                     // A TableAlreadyExistsException is not thrown, since the 
table only exists *after* this fixed timestamp.
                 }
                 try {
-                    // TODO : Get this from a configuration
                     
metaConnection.createStatement().executeUpdate(QueryConstants.CREATE_STATS_TABLE_METADATA);
                 } catch (NewerTableAlreadyExistsException ignore) {
                     // Ignore, as this will happen if the SYSTEM.SEQUENCE 
already exists at this fixed

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java 
b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
index 555628d..985d3cc 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
@@ -36,6 +36,7 @@ import static 
org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAM
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS;
 import static 
org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS_COUNT;
+import static 
org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT;
 import static 
org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_ROWS;
 import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INCREMENT_BY;
@@ -245,6 +246,7 @@ public interface QueryConstants {
             MIN_KEY + " VARBINARY," + 
             MAX_KEY + " VARBINARY," +
             LAST_STATS_UPDATE_TIME+ " DATE, "+
+            GUIDE_POSTS_ROW_COUNT+ " BIGINT, "+
             "CONSTRAINT " + SYSTEM_TABLE_PK_NAME + " PRIMARY KEY ("
             + PHYSICAL_NAME + ","
             + COLUMN_FAMILY + ","+ REGION_NAME+"))\n" +

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 06f3a9c..ad50f73 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -40,6 +40,8 @@ import org.apache.hadoop.hbase.client.Mutation;
 import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.coprocessor.generated.PGuidePostsProtos;
+import org.apache.phoenix.coprocessor.generated.PGuidePostsProtos.PGuidePosts;
 import org.apache.phoenix.coprocessor.generated.PTableProtos;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
@@ -884,12 +886,21 @@ public class PTableImpl implements PTable {
       
       boolean isImmutableRows = table.getIsImmutableRows();
       SortedMap<byte[], GuidePostsInfo> tableGuidePosts = new TreeMap<byte[], 
GuidePostsInfo>(Bytes.BYTES_COMPARATOR);
-      for (PTableProtos.PTableStats pTableStatsProto : 
table.getGuidePostsList()) {
-          List<byte[]> value = 
Lists.newArrayListWithExpectedSize(pTableStatsProto.getValuesCount());
+        for (PTableProtos.PTableStats pTableStatsProto : 
table.getGuidePostsList()) {
+            List<byte[]> value = 
Lists.newArrayListWithExpectedSize(pTableStatsProto.getValuesCount());
             for (int j = 0; j < pTableStatsProto.getValuesCount(); j++) {
                 value.add(pTableStatsProto.getValues(j).toByteArray());
             }
-            GuidePostsInfo info = new 
GuidePostsInfo(pTableStatsProto.getGuidePostsByteCount(), value);
+            // No op
+            pTableStatsProto.getGuidePostsByteCount();
+            value = 
Lists.newArrayListWithExpectedSize(pTableStatsProto.getValuesCount());
+            PGuidePosts pGuidePosts = pTableStatsProto.getPGuidePosts();
+            for(int j = 0; j < pGuidePosts.getGuidePostsCount(); j++) {
+                value.add(pGuidePosts.getGuidePosts(j).toByteArray());
+            }
+            long guidePostsByteCount = pGuidePosts.getByteCount();
+            long rowCount = pGuidePosts.getRowCount();
+            GuidePostsInfo info = new GuidePostsInfo(guidePostsByteCount, 
value, rowCount);
             tableGuidePosts.put(pTableStatsProto.getKey().toByteArray(), info);
       }
       PTableStats stats = new PTableStatsImpl(tableGuidePosts, 
table.getStatsTimeStamp());
@@ -984,6 +995,13 @@ public class PTableImpl implements PTable {
              statsBuilder.addValues(HBaseZeroCopyByteString.wrap(stat));
          }
          statsBuilder.setGuidePostsByteCount(entry.getValue().getByteCount());
+         PGuidePostsProtos.PGuidePosts.Builder guidePstsBuilder = 
PGuidePostsProtos.PGuidePosts.newBuilder();
+         for (byte[] stat : entry.getValue().getGuidePosts()) {
+             
guidePstsBuilder.addGuidePosts(HBaseZeroCopyByteString.wrap(stat));
+         }
+         guidePstsBuilder.setByteCount(entry.getValue().getByteCount());
+         guidePstsBuilder.setRowCount(entry.getValue().getRowCount());
+         statsBuilder.setPGuidePosts(guidePstsBuilder);
          builder.addGuidePosts(statsBuilder.build());
       }
       builder.setStatsTimeStamp(table.getTableStats().getTimestamp());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/GuidePostsInfo.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/GuidePostsInfo.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/GuidePostsInfo.java
index b4aa0b8..c3cc8fd 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/GuidePostsInfo.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/GuidePostsInfo.java
@@ -1,19 +1,3 @@
-package org.apache.phoenix.schema.stats;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.io.WritableUtils;
-import org.apache.phoenix.util.TrustedByteArrayOutputStream;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -31,26 +15,116 @@ import com.google.common.collect.Lists;
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.phoenix.schema.stats;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.io.WritableUtils;
+import org.apache.phoenix.util.TrustedByteArrayOutputStream;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 /**
- *  A simple POJO class that holds the information related to GuidePosts serDe.
+ *  A class that holds the guidePosts of a region and also allows combining 
the 
+ *  guidePosts of different regions when the GuidePostsInfo is formed for a 
table.
  */
 public class GuidePostsInfo {
-       public static final GuidePostsInfo EMPTY_GUIDE_POSTS_INFO = new 
GuidePostsInfo(0L, Collections.<byte[]>emptyList());
-       
-    private long byteCount; // Number of bytes traversed in the region
-    private long keyByteSize; // Total number of bytes in keys stored in 
guidePosts
+
+    /**
+     * the total number of guidePosts for the table combining all the 
guidePosts per region per cf.
+     */
     private List<byte[]> guidePosts;
+    /**
+     * The bytecount that is flattened across the total number of guide posts.
+     */
+    private long byteCount = 0;
+    
+    /**
+     * The rowCount that is flattened across the total number of guide posts.
+     */
+    private long rowCount = 0;
+    
+    private long keyByteSize; // Total number of bytes in keys stored in 
guidePosts
 
-    public GuidePostsInfo(long byteCount, List<byte[]> guidePosts) {
-        this.byteCount = byteCount;
+    /**
+     * Constructor that creates GuidePostsInfo per region
+     * @param byteCount
+     * @param guidePosts
+     * @param rowCount
+     */
+    public GuidePostsInfo(long byteCount, List<byte[]> guidePosts, long 
rowCount) {
         this.guidePosts = ImmutableList.copyOf(guidePosts);
         int size = 0;
         for (byte[] key : guidePosts) {
             size += key.length;
         }
         this.keyByteSize = size;
+        this.byteCount = byteCount;
+        this.rowCount = rowCount;
+    }
+    
+    public long getByteCount() {
+        return byteCount;
     }
 
+    public List<byte[]> getGuidePosts() {
+        return guidePosts;
+    }
+
+    public long getRowCount() {
+        return this.rowCount;
+    }
+    
+    public void incrementRowCount() {
+        this.rowCount++;
+    }
+    
+    /**
+     * Combines the GuidePosts per region into one.
+     * @param oldInfo
+     */
+    public void combine(GuidePostsInfo oldInfo) {
+        byte[] newFirstKey = oldInfo.getGuidePosts().get(0);
+        byte[] existingLastKey;
+        if (!this.getGuidePosts().isEmpty()) {
+            existingLastKey = 
this.getGuidePosts().get(this.getGuidePosts().size() - 1);
+        } else {
+            existingLastKey = HConstants.EMPTY_BYTE_ARRAY;
+        }
+        int size = oldInfo.getGuidePosts().size();
+        // If the existing guidePosts is lesser than the new RegionInfo that 
we are combining
+        // then add the new Region info to the end of the current GuidePosts.
+        // If the new region info is smaller than the existing guideposts then 
add the existing
+        // guide posts after the new guideposts.
+        List<byte[]> newTotalGuidePosts = new 
ArrayList<byte[]>(this.getGuidePosts().size() + size);
+        if (Bytes.compareTo(existingLastKey, newFirstKey) <= 0) {
+            newTotalGuidePosts.addAll(this.getGuidePosts());
+            newTotalGuidePosts.addAll(oldInfo.getGuidePosts());
+        } else {
+            newTotalGuidePosts.addAll(oldInfo.getGuidePosts());
+            newTotalGuidePosts.addAll(this.getGuidePosts());
+        }
+        this.guidePosts = ImmutableList.copyOf(newTotalGuidePosts);
+        this.byteCount += oldInfo.getByteCount();
+        this.keyByteSize += oldInfo.keyByteSize;
+        this.rowCount += oldInfo.getRowCount();
+    }
+    
+    /**
+     * The guide posts, rowCount and byteCount are accumulated every time a 
guidePosts depth is
+     * reached while collecting stats.
+     * @param row
+     * @param byteCount
+     * @param rowCount
+     * @return
+     */
     public boolean addGuidePost(byte[] row, long byteCount) {
         if (guidePosts.isEmpty() || Bytes.compareTo(row, 
guidePosts.get(guidePosts.size() - 1)) > 0) {
             List<byte[]> newGuidePosts = 
Lists.newArrayListWithExpectedSize(this.getGuidePosts().size() + 1);
@@ -64,23 +138,14 @@ public class GuidePostsInfo {
         return false;
     }
     
-    public void combine(GuidePostsInfo oldInfo) {
-        // FIXME: I don't think we need to do a merge sort here, as the keys 
won't be interleaved.
-        // We just need to concatenate them in the correct way.
-        this.guidePosts = 
ImmutableList.copyOf(Iterators.mergeSorted(ImmutableList.of(this.getGuidePosts().iterator(),
 oldInfo.getGuidePosts().iterator()), Bytes.BYTES_COMPARATOR));
-        this.byteCount += oldInfo.getByteCount();
-        this.keyByteSize += oldInfo.keyByteSize;
-    }
-    
-    public long getByteCount() {
-        return byteCount;
-    }
-
-    public List<byte[]> getGuidePosts() {
-        return guidePosts;
-    }
-
-    public static GuidePostsInfo fromBytes(byte[] buf, int offset, int l) {
+    /**
+     * Deserializes the per row guidePosts info from the value part of each 
cell in the SYSTEM.STATS table
+     * @param buf
+     * @param offset
+     * @param l
+     * @return
+     */
+    public static GuidePostsInfo deserializeGuidePostsInfo(byte[] buf, int 
offset, int l, long rowCount) {
         try {
             ByteArrayInputStream bytesIn = new ByteArrayInputStream(buf, 
offset, l);
             try {
@@ -99,7 +164,7 @@ public class GuidePostsInfo {
                             }
                         }
                     }
-                    return new GuidePostsInfo(byteCount, guidePosts);
+                    return new GuidePostsInfo(byteCount, guidePosts, rowCount);
                 } catch (IOException e) {
                     throw new RuntimeException(e); // not possible
                 } finally {
@@ -116,18 +181,29 @@ public class GuidePostsInfo {
             throw new RuntimeException(e); // not possible
         }
     }
-    
-    public byte[] toBytes() {
+
+    /**
+     * Serailizes the guidePosts info as value in the SYSTEM.STATS table.
+     * <br>
+     * The format is,
+     * <br>
+     *  - number of bytes traversed
+     * <br>
+     *  - number of key bytes in the region
+     * <br>
+     *  - number of guideposts for that family
+     * <br> u
+     *  - [guidepostSize][guidePostsArray],[guidePostsSize][guidePostArray]
+     * @return the byte[] to be serialized in the cell
+     */
+    public byte[] serializeGuidePostsInfo() {
         int size = guidePosts.size();
-        // Serialize the number of bytes traversed, number of key bytes in the 
region,
-        // number of guideposts for that family, 
<<guidepostSize><guidePostsArray>,<guidePostsSize> <guidePostArray>>
         // We will lose precision here?
-        TrustedByteArrayOutputStream bs = new TrustedByteArrayOutputStream(
-                (int)(Bytes.SIZEOF_LONG + Bytes.SIZEOF_LONG + Bytes.SIZEOF_INT 
+ this.keyByteSize + (WritableUtils
-                        .getVIntSize(size) * size)));
+        TrustedByteArrayOutputStream bs = new 
TrustedByteArrayOutputStream((int)(Bytes.SIZEOF_LONG + Bytes.SIZEOF_LONG
+                + Bytes.SIZEOF_INT + this.keyByteSize + 
(WritableUtils.getVIntSize(size) * size)));
         DataOutputStream os = new DataOutputStream(bs);
         try {
-            os.writeLong(this.getByteCount());
+            os.writeLong(byteCount);
             os.writeInt(size);
             for (byte[] element : guidePosts) {
                 WritableUtils.writeVInt(os, element.length);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollector.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollector.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollector.java
index b943b97..ade0fba 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollector.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollector.java
@@ -33,7 +33,6 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.regionserver.HRegion;
 import org.apache.hadoop.hbase.regionserver.InternalScanner;
 import org.apache.hadoop.hbase.regionserver.Store;
-import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
@@ -62,8 +61,6 @@ public class StatisticsCollector {
     private long guidepostDepth;
     private long maxTimeStamp = MetaDataProtocol.MIN_TABLE_TIMESTAMP;
     private Map<ImmutableBytesPtr, Pair<Long,GuidePostsInfo>> guidePostsMap = 
Maps.newHashMap();
-    // Tracks the bytecount per family if it has reached the guidePostsDepth
-    private Map<ImmutableBytesPtr, Boolean> familyMap = Maps.newHashMap();
     protected StatisticsWriter statsTable;
     private Pair<Long,GuidePostsInfo> cachedGps = null;
 
@@ -84,8 +81,8 @@ public class StatisticsCollector {
         // in a compaction we know the one family ahead of time
         if (family != null) {
             ImmutableBytesPtr cfKey = new ImmutableBytesPtr(family);
-            familyMap.put(cfKey, true);
-            cachedGps = new Pair<Long,GuidePostsInfo>(0L,new GuidePostsInfo(0, 
Collections.<byte[]>emptyList()));
+            cachedGps = new Pair<Long, GuidePostsInfo>(0l, new 
GuidePostsInfo(0,
+                    Collections.<byte[]> emptyList(), 0l));
             guidePostsMap.put(cfKey, cachedGps);
         }
     }
@@ -117,7 +114,7 @@ public class StatisticsCollector {
             boolean delete, List<Mutation> mutations, long currentTime) throws 
IOException {
         try {
             // update the statistics table
-            for (ImmutableBytesPtr fam : familyMap.keySet()) {
+            for (ImmutableBytesPtr fam : guidePostsMap.keySet()) {
                 if (delete) {
                     if(logger.isDebugEnabled()) {
                         logger.debug("Deleting the stats for the region 
"+region.getRegionInfo());
@@ -148,9 +145,49 @@ public class StatisticsCollector {
      *            next batch of {@link KeyValue}s
      */
     public void collectStatistics(final List<Cell> results) {
-        for (Cell c : results) {
-            KeyValue kv = KeyValueUtil.ensureKeyValue(c);
-            updateStatistic(kv);
+        Map<ImmutableBytesPtr, Boolean> famMap = Maps.newHashMap();
+        List<GuidePostsInfo> rowTracker = null;
+        if(cachedGps == null) {
+            rowTracker = 
+                    new ArrayList<GuidePostsInfo>();
+        }
+        for (Cell cell : results) {
+            KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
+            maxTimeStamp = Math.max(maxTimeStamp, kv.getTimestamp());
+            Pair<Long, GuidePostsInfo> gps;
+            if (cachedGps == null) {
+                ImmutableBytesPtr cfKey = new 
ImmutableBytesPtr(kv.getFamilyArray(), kv.getFamilyOffset(),
+                        kv.getFamilyLength());
+                gps = guidePostsMap.get(cfKey);
+                if (gps == null) {
+                    gps = new Pair<Long, GuidePostsInfo>(0l, new 
GuidePostsInfo(0,
+                            Collections.<byte[]> emptyList(), 0l));
+                    guidePostsMap.put(cfKey, gps);
+                }
+                if (famMap.get(cfKey) == null) {
+                    famMap.put(cfKey, true);
+                    rowTracker.add(gps.getSecond());
+                }
+            } else {
+                gps = cachedGps;
+            }
+            int kvLength = kv.getLength();
+            long byteCount = gps.getFirst() + kvLength;
+            gps.setFirst(byteCount);
+            if (byteCount >= guidepostDepth) {
+                byte[] row = ByteUtil.copyKeyBytesIfNecessary(new 
ImmutableBytesWritable(kv.getRowArray(), kv
+                        .getRowOffset(), kv.getRowLength()));
+                if (gps.getSecond().addGuidePost(row, byteCount)) {
+                    gps.setFirst(0l);
+                }
+            }
+        }
+        if(cachedGps == null) {
+            for (GuidePostsInfo s : rowTracker) {
+                s.incrementRowCount();
+            }
+        } else {
+            cachedGps.getSecond().incrementRowCount();
         }
     }
 
@@ -189,47 +226,17 @@ public class StatisticsCollector {
 
     public void clear() {
         this.guidePostsMap.clear();
-        this.familyMap.clear();
         maxTimeStamp = MetaDataProtocol.MIN_TABLE_TIMESTAMP;
     }
 
     public void addGuidePost(ImmutableBytesPtr cfKey, GuidePostsInfo info, 
long byteSize, long timestamp) {
-       Pair<Long,GuidePostsInfo> newInfo = new 
Pair<Long,GuidePostsInfo>(byteSize,info);
-       Pair<Long,GuidePostsInfo> oldInfo = guidePostsMap.put(cfKey, newInfo);
-       if (oldInfo != null) {
-               info.combine(oldInfo.getSecond());
-               newInfo.setFirst(oldInfo.getFirst() + newInfo.getFirst());
-       }
-        maxTimeStamp = Math.max(maxTimeStamp, timestamp);
-    }
-    
-    public void updateStatistic(KeyValue kv) {
-        maxTimeStamp = Math.max(maxTimeStamp, kv.getTimestamp());
-
-        Pair<Long,GuidePostsInfo> gps;
-        if (cachedGps == null) {
-            ImmutableBytesPtr cfKey = new 
ImmutableBytesPtr(kv.getFamilyArray(), kv.getFamilyOffset(), 
kv.getFamilyLength());
-            familyMap.put(cfKey, true);
-
-            // TODO : This can be moved to an interface so that we could 
collect guide posts in different ways
-            gps = guidePostsMap.get(cfKey);
-            if (gps == null) {
-                gps = new Pair<Long,GuidePostsInfo>(0L,new GuidePostsInfo(0, 
Collections.<byte[]>emptyList()));
-                guidePostsMap.put(cfKey, gps);
-            }
-        } else {
-            gps = cachedGps;
-        }
-        int kvLength = kv.getLength();
-        long byteCount = gps.getFirst() + kvLength;
-        gps.setFirst(byteCount);
-        if (byteCount >= guidepostDepth) {
-            byte[] row = ByteUtil.copyKeyBytesIfNecessary(
-                    new ImmutableBytesWritable(kv.getRowArray(), 
kv.getRowOffset(), kv.getRowLength()));
-            if (gps.getSecond().addGuidePost(row, byteCount)) {
-                gps.setFirst(0L);
-            }
+        Pair<Long, GuidePostsInfo> newInfo = new Pair<Long, 
GuidePostsInfo>(byteSize, info);
+        Pair<Long, GuidePostsInfo> oldInfo = guidePostsMap.put(cfKey, newInfo);
+        if (oldInfo != null) {
+            info.combine(oldInfo.getSecond());
+            newInfo.setFirst(oldInfo.getFirst() + newInfo.getFirst());
         }
+        maxTimeStamp = Math.max(maxTimeStamp, timestamp);
     }
 
     public GuidePostsInfo getGuidePosts(ImmutableBytesPtr fam) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsScanner.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsScanner.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsScanner.java
index dddfc52..e012040 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsScanner.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsScanner.java
@@ -1,10 +1,19 @@
 /*
- * 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.
+ * 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.
  */
 package org.apache.phoenix.schema.stats;
 
@@ -16,7 +25,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.KeyValue;
-import org.apache.hadoop.hbase.KeyValueUtil;
 import org.apache.hadoop.hbase.client.Mutation;
 import org.apache.hadoop.hbase.regionserver.HRegion;
 import org.apache.hadoop.hbase.regionserver.InternalScanner;
@@ -63,12 +71,7 @@ public class StatisticsScanner implements InternalScanner {
      *            next batch of {@link KeyValue}s
      */
     protected void updateStat(final List<Cell> results) {
-        for (Cell c : results) {
-            KeyValue kv = KeyValueUtil.ensureKeyValue(c);
-            if (c.getTypeByte() == KeyValue.Type.Put.getCode()) {
-                tracker.updateStatistic(kv);
-            }
-        }
+        tracker.collectStatistics(results);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/phoenix/blob/2fb019a2/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsUtil.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsUtil.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsUtil.java
index bf9d80e..aab3a11 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsUtil.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsUtil.java
@@ -38,6 +38,8 @@ import org.apache.phoenix.coprocessor.MetaDataProtocol;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.types.PLong;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.MetaDataUtil;
 /**
@@ -50,6 +52,7 @@ public class StatisticsUtil {
 
     /** Number of parts in our complex key */
     protected static final int NUM_KEY_PARTS = 3;
+    
 
     public static byte[] getRowKey(byte[] table, ImmutableBytesPtr fam, byte[] 
region) {
         // always starts with the source table
@@ -76,6 +79,7 @@ public class StatisticsUtil {
         get.setTimeRange(MetaDataProtocol.MIN_TABLE_TIMESTAMP, 
clientTimeStamp);
         get.addColumn(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, 
PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH_BYTES);
         get.addColumn(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, 
PhoenixDatabaseMetaData.GUIDE_POSTS_BYTES);
+        get.addColumn(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, 
PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT_BYTES);
         return statsHTable.get(get);
     }
     
@@ -84,29 +88,54 @@ public class StatisticsUtil {
         ImmutableBytesWritable ptr = new ImmutableBytesWritable();
         Scan s = MetaDataUtil.newTableRowsScan(tableNameBytes, 
MetaDataProtocol.MIN_TABLE_TIMESTAMP, clientTimeStamp);
         s.addColumn(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, 
PhoenixDatabaseMetaData.GUIDE_POSTS_BYTES);
+        s.addColumn(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, 
PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT_BYTES);
         ResultScanner scanner = statsHTable.getScanner(s);
         Result result = null;
         long timeStamp = MetaDataProtocol.MIN_TABLE_TIMESTAMP;
-        TreeMap<byte[], GuidePostsInfo> guidePostsPerCf = new TreeMap<byte[], 
GuidePostsInfo>(Bytes.BYTES_COMPARATOR);
+        TreeMap<byte[], GuidePostsInfo> guidePostsPerCf = new TreeMap<byte[], 
GuidePostsInfo>(
+                Bytes.BYTES_COMPARATOR);
         while ((result = scanner.next()) != null) {
             CellScanner cellScanner = result.cellScanner();
+            long rowCount = 0;
+            ImmutableBytesPtr valuePtr = new 
ImmutableBytesPtr(HConstants.EMPTY_BYTE_ARRAY);
+            byte[] cfName = null;
+            int tableNameLength;
+            int cfOffset;
+            int cfLength;
+            boolean valuesSet = false;
+            // Only the two cells with quals GUIDE_POSTS_ROW_COUNT_BYTES and 
GUIDE_POSTS_BYTES would be retrieved
             while (cellScanner.advance()) {
                 Cell current = cellScanner.current();
-                int tableNameLength = tableNameBytes.length + 1;
-                int cfOffset = current.getRowOffset() + tableNameLength;
-                int cfLength = getVarCharLength(current.getRowArray(), 
cfOffset, current.getRowLength()
-                        - tableNameLength);
-                ptr.set(current.getRowArray(), cfOffset, cfLength);
-                byte[] cfName = ByteUtil.copyKeyBytesIfNecessary(ptr);
-                GuidePostsInfo newInfo = 
GuidePostsInfo.fromBytes(current.getValueArray(), current.getValueOffset(), 
current.getValueLength());
-                GuidePostsInfo oldInfo = guidePostsPerCf.put(cfName, newInfo);
-                if (oldInfo != null) {
-                    newInfo.combine(oldInfo);
+                if (!valuesSet) {
+                    tableNameLength = tableNameBytes.length + 1;
+                    cfOffset = current.getRowOffset() + tableNameLength;
+                    cfLength = getVarCharLength(current.getRowArray(), 
cfOffset, current.getRowLength()
+                            - tableNameLength);
+                    ptr.set(current.getRowArray(), cfOffset, cfLength);
+                    valuesSet = true;
+                }
+                cfName = ByteUtil.copyKeyBytesIfNecessary(ptr);
+                if (Bytes.equals(current.getQualifierArray(), 
current.getQualifierOffset(),
+                        current.getQualifierLength(), 
PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT_BYTES, 0,
+                        
PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT_BYTES.length)) {
+                    rowCount = 
PLong.INSTANCE.getCodec().decodeLong(current.getValueArray(),
+                            current.getValueOffset(), SortOrder.getDefault());
+                } else {
+                    valuePtr.set(current.getValueArray(), 
current.getValueOffset(),
+                        current.getValueLength());
                 }
                 if (current.getTimestamp() > timeStamp) {
                     timeStamp = current.getTimestamp();
                 }
             }
+            if (cfName != null) {
+                GuidePostsInfo newGPInfo = 
GuidePostsInfo.deserializeGuidePostsInfo(
+                        valuePtr.get(), valuePtr.getOffset(), 
valuePtr.getLength(), rowCount);
+                GuidePostsInfo oldInfo = guidePostsPerCf.put(cfName, 
newGPInfo);
+                if (oldInfo != null) {
+                    newGPInfo.combine(oldInfo);
+                }
+            }
         }
         if (!guidePostsPerCf.isEmpty()) {
             return new PTableStatsImpl(guidePostsPerCf, timeStamp);

Reply via email to