incubator-blur-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From amccu...@apache.org
Subject [17/51] [abbrv] Added a new method during mutations, block waiting for visibility. This allows the client to perform a lot of updates and collect the generation information and then block once for all the mutations.
Date Tue, 11 Dec 2012 02:20:59 GMT
http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/interface/gen-java/org/apache/blur/thrift/generated/Generation.java
----------------------------------------------------------------------
diff --git a/interface/gen-java/org/apache/blur/thrift/generated/Generation.java b/interface/gen-java/org/apache/blur/thrift/generated/Generation.java
new file mode 100644
index 0000000..6580d5f
--- /dev/null
+++ b/interface/gen-java/org/apache/blur/thrift/generated/Generation.java
@@ -0,0 +1,597 @@
+/**
+ * Autogenerated by Thrift Compiler (0.9.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.blur.thrift.generated;
+
+/**
+ * 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.
+ */
+
+
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Generation implements org.apache.thrift.TBase<Generation, Generation._Fields>, java.io.Serializable, Cloneable {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Generation");
+
+  private static final org.apache.thrift.protocol.TField TABLE_FIELD_DESC = new org.apache.thrift.protocol.TField("table", org.apache.thrift.protocol.TType.STRING, (short)1);
+  private static final org.apache.thrift.protocol.TField SHARD_INDEX_FIELD_DESC = new org.apache.thrift.protocol.TField("shardIndex", org.apache.thrift.protocol.TType.I32, (short)2);
+  private static final org.apache.thrift.protocol.TField GENERATION_FIELD_DESC = new org.apache.thrift.protocol.TField("generation", org.apache.thrift.protocol.TType.I64, (short)3);
+
+  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+  static {
+    schemes.put(StandardScheme.class, new GenerationStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new GenerationTupleSchemeFactory());
+  }
+
+  public String table; // required
+  public int shardIndex; // required
+  public long generation; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    TABLE((short)1, "table"),
+    SHARD_INDEX((short)2, "shardIndex"),
+    GENERATION((short)3, "generation");
+
+    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // TABLE
+          return TABLE;
+        case 2: // SHARD_INDEX
+          return SHARD_INDEX;
+        case 3: // GENERATION
+          return GENERATION;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  private static final int __SHARDINDEX_ISSET_ID = 0;
+  private static final int __GENERATION_ISSET_ID = 1;
+  private byte __isset_bitfield = 0;
+  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.TABLE, new org.apache.thrift.meta_data.FieldMetaData("table", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.SHARD_INDEX, new org.apache.thrift.meta_data.FieldMetaData("shardIndex", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+    tmpMap.put(_Fields.GENERATION, new org.apache.thrift.meta_data.FieldMetaData("generation", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Generation.class, metaDataMap);
+  }
+
+  public Generation() {
+  }
+
+  public Generation(
+    String table,
+    int shardIndex,
+    long generation)
+  {
+    this();
+    this.table = table;
+    this.shardIndex = shardIndex;
+    setShardIndexIsSet(true);
+    this.generation = generation;
+    setGenerationIsSet(true);
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public Generation(Generation other) {
+    __isset_bitfield = other.__isset_bitfield;
+    if (other.isSetTable()) {
+      this.table = other.table;
+    }
+    this.shardIndex = other.shardIndex;
+    this.generation = other.generation;
+  }
+
+  public Generation deepCopy() {
+    return new Generation(this);
+  }
+
+  @Override
+  public void clear() {
+    this.table = null;
+    setShardIndexIsSet(false);
+    this.shardIndex = 0;
+    setGenerationIsSet(false);
+    this.generation = 0;
+  }
+
+  public String getTable() {
+    return this.table;
+  }
+
+  public Generation setTable(String table) {
+    this.table = table;
+    return this;
+  }
+
+  public void unsetTable() {
+    this.table = null;
+  }
+
+  /** Returns true if field table is set (has been assigned a value) and false otherwise */
+  public boolean isSetTable() {
+    return this.table != null;
+  }
+
+  public void setTableIsSet(boolean value) {
+    if (!value) {
+      this.table = null;
+    }
+  }
+
+  public int getShardIndex() {
+    return this.shardIndex;
+  }
+
+  public Generation setShardIndex(int shardIndex) {
+    this.shardIndex = shardIndex;
+    setShardIndexIsSet(true);
+    return this;
+  }
+
+  public void unsetShardIndex() {
+    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __SHARDINDEX_ISSET_ID);
+  }
+
+  /** Returns true if field shardIndex is set (has been assigned a value) and false otherwise */
+  public boolean isSetShardIndex() {
+    return EncodingUtils.testBit(__isset_bitfield, __SHARDINDEX_ISSET_ID);
+  }
+
+  public void setShardIndexIsSet(boolean value) {
+    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SHARDINDEX_ISSET_ID, value);
+  }
+
+  public long getGeneration() {
+    return this.generation;
+  }
+
+  public Generation setGeneration(long generation) {
+    this.generation = generation;
+    setGenerationIsSet(true);
+    return this;
+  }
+
+  public void unsetGeneration() {
+    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __GENERATION_ISSET_ID);
+  }
+
+  /** Returns true if field generation is set (has been assigned a value) and false otherwise */
+  public boolean isSetGeneration() {
+    return EncodingUtils.testBit(__isset_bitfield, __GENERATION_ISSET_ID);
+  }
+
+  public void setGenerationIsSet(boolean value) {
+    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __GENERATION_ISSET_ID, value);
+  }
+
+  public void setFieldValue(_Fields field, Object value) {
+    switch (field) {
+    case TABLE:
+      if (value == null) {
+        unsetTable();
+      } else {
+        setTable((String)value);
+      }
+      break;
+
+    case SHARD_INDEX:
+      if (value == null) {
+        unsetShardIndex();
+      } else {
+        setShardIndex((Integer)value);
+      }
+      break;
+
+    case GENERATION:
+      if (value == null) {
+        unsetGeneration();
+      } else {
+        setGeneration((Long)value);
+      }
+      break;
+
+    }
+  }
+
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case TABLE:
+      return getTable();
+
+    case SHARD_INDEX:
+      return Integer.valueOf(getShardIndex());
+
+    case GENERATION:
+      return Long.valueOf(getGeneration());
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case TABLE:
+      return isSetTable();
+    case SHARD_INDEX:
+      return isSetShardIndex();
+    case GENERATION:
+      return isSetGeneration();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof Generation)
+      return this.equals((Generation)that);
+    return false;
+  }
+
+  public boolean equals(Generation that) {
+    if (that == null)
+      return false;
+
+    boolean this_present_table = true && this.isSetTable();
+    boolean that_present_table = true && that.isSetTable();
+    if (this_present_table || that_present_table) {
+      if (!(this_present_table && that_present_table))
+        return false;
+      if (!this.table.equals(that.table))
+        return false;
+    }
+
+    boolean this_present_shardIndex = true;
+    boolean that_present_shardIndex = true;
+    if (this_present_shardIndex || that_present_shardIndex) {
+      if (!(this_present_shardIndex && that_present_shardIndex))
+        return false;
+      if (this.shardIndex != that.shardIndex)
+        return false;
+    }
+
+    boolean this_present_generation = true;
+    boolean that_present_generation = true;
+    if (this_present_generation || that_present_generation) {
+      if (!(this_present_generation && that_present_generation))
+        return false;
+      if (this.generation != that.generation)
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return 0;
+  }
+
+  public int compareTo(Generation other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+    Generation typedOther = (Generation)other;
+
+    lastComparison = Boolean.valueOf(isSetTable()).compareTo(typedOther.isSetTable());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetTable()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.table, typedOther.table);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetShardIndex()).compareTo(typedOther.isSetShardIndex());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetShardIndex()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.shardIndex, typedOther.shardIndex);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetGeneration()).compareTo(typedOther.isSetGeneration());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetGeneration()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.generation, typedOther.generation);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("Generation(");
+    boolean first = true;
+
+    sb.append("table:");
+    if (this.table == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.table);
+    }
+    first = false;
+    if (!first) sb.append(", ");
+    sb.append("shardIndex:");
+    sb.append(this.shardIndex);
+    first = false;
+    if (!first) sb.append(", ");
+    sb.append("generation:");
+    sb.append(this.generation);
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+      __isset_bitfield = 0;
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class GenerationStandardSchemeFactory implements SchemeFactory {
+    public GenerationStandardScheme getScheme() {
+      return new GenerationStandardScheme();
+    }
+  }
+
+  private static class GenerationStandardScheme extends StandardScheme<Generation> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, Generation struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // TABLE
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.table = iprot.readString();
+              struct.setTableIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 2: // SHARD_INDEX
+            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+              struct.shardIndex = iprot.readI32();
+              struct.setShardIndexIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 3: // GENERATION
+            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+              struct.generation = iprot.readI64();
+              struct.setGenerationIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, Generation struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.table != null) {
+        oprot.writeFieldBegin(TABLE_FIELD_DESC);
+        oprot.writeString(struct.table);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldBegin(SHARD_INDEX_FIELD_DESC);
+      oprot.writeI32(struct.shardIndex);
+      oprot.writeFieldEnd();
+      oprot.writeFieldBegin(GENERATION_FIELD_DESC);
+      oprot.writeI64(struct.generation);
+      oprot.writeFieldEnd();
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class GenerationTupleSchemeFactory implements SchemeFactory {
+    public GenerationTupleScheme getScheme() {
+      return new GenerationTupleScheme();
+    }
+  }
+
+  private static class GenerationTupleScheme extends TupleScheme<Generation> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, Generation struct) throws org.apache.thrift.TException {
+      TTupleProtocol oprot = (TTupleProtocol) prot;
+      BitSet optionals = new BitSet();
+      if (struct.isSetTable()) {
+        optionals.set(0);
+      }
+      if (struct.isSetShardIndex()) {
+        optionals.set(1);
+      }
+      if (struct.isSetGeneration()) {
+        optionals.set(2);
+      }
+      oprot.writeBitSet(optionals, 3);
+      if (struct.isSetTable()) {
+        oprot.writeString(struct.table);
+      }
+      if (struct.isSetShardIndex()) {
+        oprot.writeI32(struct.shardIndex);
+      }
+      if (struct.isSetGeneration()) {
+        oprot.writeI64(struct.generation);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, Generation struct) throws org.apache.thrift.TException {
+      TTupleProtocol iprot = (TTupleProtocol) prot;
+      BitSet incoming = iprot.readBitSet(3);
+      if (incoming.get(0)) {
+        struct.table = iprot.readString();
+        struct.setTableIsSet(true);
+      }
+      if (incoming.get(1)) {
+        struct.shardIndex = iprot.readI32();
+        struct.setShardIndexIsSet(true);
+      }
+      if (incoming.get(2)) {
+        struct.generation = iprot.readI64();
+        struct.setGenerationIsSet(true);
+      }
+    }
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/interface/gen-perl/Blur/Blur.pm
----------------------------------------------------------------------
diff --git a/interface/gen-perl/Blur/Blur.pm b/interface/gen-perl/Blur/Blur.pm
index 43954b8..e626758 100644
--- a/interface/gen-perl/Blur/Blur.pm
+++ b/interface/gen-perl/Blur/Blur.pm
@@ -813,14 +813,18 @@ sub write {
 
 package Blur::Blur_addDocuments_result;
 use base qw(Class::Accessor);
-Blur::Blur_addDocuments_result->mk_accessors( qw( ) );
+Blur::Blur_addDocuments_result->mk_accessors( qw( success ) );
 
 sub new {
   my $classname = shift;
   my $self      = {};
   my $vals      = shift || {};
+  $self->{success} = undef;
   $self->{e} = undef;
   if (UNIVERSAL::isa($vals,'HASH')) {
+    if (defined $vals->{success}) {
+      $self->{success} = $vals->{success};
+    }
     if (defined $vals->{e}) {
       $self->{e} = $vals->{e};
     }
@@ -847,6 +851,25 @@ sub read {
     }
     SWITCH: for($fid)
     {
+      /^0$/ && do{      if ($ftype == TType::LIST) {
+        {
+          my $_size141 = 0;
+          $self->{success} = [];
+          my $_etype144 = 0;
+          $xfer += $input->readListBegin(\$_etype144, \$_size141);
+          for (my $_i145 = 0; $_i145 < $_size141; ++$_i145)
+          {
+            my $elem146 = undef;
+            $elem146 = new Blur::Generation();
+            $xfer += $elem146->read($input);
+            push(@{$self->{success}},$elem146);
+          }
+          $xfer += $input->readListEnd();
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
       /^1$/ && do{      if ($ftype == TType::STRUCT) {
         $self->{e} = new Blur::BlurException();
         $xfer += $self->{e}->read($input);
@@ -866,6 +889,20 @@ sub write {
   my ($self, $output) = @_;
   my $xfer   = 0;
   $xfer += $output->writeStructBegin('Blur_addDocuments_result');
+  if (defined $self->{success}) {
+    $xfer += $output->writeFieldBegin('success', TType::LIST, 0);
+    {
+      $xfer += $output->writeListBegin(TType::STRUCT, scalar(@{$self->{success}}));
+      {
+        foreach my $iter147 (@{$self->{success}}) 
+        {
+          $xfer += ${iter147}->write($output);
+        }
+      }
+      $xfer += $output->writeListEnd();
+    }
+    $xfer += $output->writeFieldEnd();
+  }
   if (defined $self->{e}) {
     $xfer += $output->writeFieldBegin('e', TType::STRUCT, 1);
     $xfer += $self->{e}->write($output);
@@ -925,15 +962,15 @@ sub read {
       last; };
       /^2$/ && do{      if ($ftype == TType::LIST) {
         {
-          my $_size141 = 0;
+          my $_size148 = 0;
           $self->{queries} = [];
-          my $_etype144 = 0;
-          $xfer += $input->readListBegin(\$_etype144, \$_size141);
-          for (my $_i145 = 0; $_i145 < $_size141; ++$_i145)
+          my $_etype151 = 0;
+          $xfer += $input->readListBegin(\$_etype151, \$_size148);
+          for (my $_i152 = 0; $_i152 < $_size148; ++$_i152)
           {
-            my $elem146 = undef;
-            $xfer += $input->readString(\$elem146);
-            push(@{$self->{queries}},$elem146);
+            my $elem153 = undef;
+            $xfer += $input->readString(\$elem153);
+            push(@{$self->{queries}},$elem153);
           }
           $xfer += $input->readListEnd();
         }
@@ -963,9 +1000,9 @@ sub write {
     {
       $xfer += $output->writeListBegin(TType::STRING, scalar(@{$self->{queries}}));
       {
-        foreach my $iter147 (@{$self->{queries}}) 
+        foreach my $iter154 (@{$self->{queries}}) 
         {
-          $xfer += $output->writeString($iter147);
+          $xfer += $output->writeString($iter154);
         }
       }
       $xfer += $output->writeListEnd();
@@ -979,14 +1016,18 @@ sub write {
 
 package Blur::Blur_deleteDocumentsByQueries_result;
 use base qw(Class::Accessor);
-Blur::Blur_deleteDocumentsByQueries_result->mk_accessors( qw( ) );
+Blur::Blur_deleteDocumentsByQueries_result->mk_accessors( qw( success ) );
 
 sub new {
   my $classname = shift;
   my $self      = {};
   my $vals      = shift || {};
+  $self->{success} = undef;
   $self->{e} = undef;
   if (UNIVERSAL::isa($vals,'HASH')) {
+    if (defined $vals->{success}) {
+      $self->{success} = $vals->{success};
+    }
     if (defined $vals->{e}) {
       $self->{e} = $vals->{e};
     }
@@ -1013,6 +1054,25 @@ sub read {
     }
     SWITCH: for($fid)
     {
+      /^0$/ && do{      if ($ftype == TType::LIST) {
+        {
+          my $_size155 = 0;
+          $self->{success} = [];
+          my $_etype158 = 0;
+          $xfer += $input->readListBegin(\$_etype158, \$_size155);
+          for (my $_i159 = 0; $_i159 < $_size155; ++$_i159)
+          {
+            my $elem160 = undef;
+            $elem160 = new Blur::Generation();
+            $xfer += $elem160->read($input);
+            push(@{$self->{success}},$elem160);
+          }
+          $xfer += $input->readListEnd();
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
       /^1$/ && do{      if ($ftype == TType::STRUCT) {
         $self->{e} = new Blur::BlurException();
         $xfer += $self->{e}->read($input);
@@ -1032,6 +1092,20 @@ sub write {
   my ($self, $output) = @_;
   my $xfer   = 0;
   $xfer += $output->writeStructBegin('Blur_deleteDocumentsByQueries_result');
+  if (defined $self->{success}) {
+    $xfer += $output->writeFieldBegin('success', TType::LIST, 0);
+    {
+      $xfer += $output->writeListBegin(TType::STRUCT, scalar(@{$self->{success}}));
+      {
+        foreach my $iter161 (@{$self->{success}}) 
+        {
+          $xfer += ${iter161}->write($output);
+        }
+      }
+      $xfer += $output->writeListEnd();
+    }
+    $xfer += $output->writeFieldEnd();
+  }
   if (defined $self->{e}) {
     $xfer += $output->writeFieldBegin('e', TType::STRUCT, 1);
     $xfer += $self->{e}->write($output);
@@ -1091,16 +1165,16 @@ sub read {
       last; };
       /^2$/ && do{      if ($ftype == TType::LIST) {
         {
-          my $_size148 = 0;
+          my $_size162 = 0;
           $self->{terms} = [];
-          my $_etype151 = 0;
-          $xfer += $input->readListBegin(\$_etype151, \$_size148);
-          for (my $_i152 = 0; $_i152 < $_size148; ++$_i152)
+          my $_etype165 = 0;
+          $xfer += $input->readListBegin(\$_etype165, \$_size162);
+          for (my $_i166 = 0; $_i166 < $_size162; ++$_i166)
           {
-            my $elem153 = undef;
-            $elem153 = new Blur::Term();
-            $xfer += $elem153->read($input);
-            push(@{$self->{terms}},$elem153);
+            my $elem167 = undef;
+            $elem167 = new Blur::Term();
+            $xfer += $elem167->read($input);
+            push(@{$self->{terms}},$elem167);
           }
           $xfer += $input->readListEnd();
         }
@@ -1130,9 +1204,9 @@ sub write {
     {
       $xfer += $output->writeListBegin(TType::STRUCT, scalar(@{$self->{terms}}));
       {
-        foreach my $iter154 (@{$self->{terms}}) 
+        foreach my $iter168 (@{$self->{terms}}) 
         {
-          $xfer += ${iter154}->write($output);
+          $xfer += ${iter168}->write($output);
         }
       }
       $xfer += $output->writeListEnd();
@@ -1146,14 +1220,18 @@ sub write {
 
 package Blur::Blur_deleteDocuments_result;
 use base qw(Class::Accessor);
-Blur::Blur_deleteDocuments_result->mk_accessors( qw( ) );
+Blur::Blur_deleteDocuments_result->mk_accessors( qw( success ) );
 
 sub new {
   my $classname = shift;
   my $self      = {};
   my $vals      = shift || {};
+  $self->{success} = undef;
   $self->{e} = undef;
   if (UNIVERSAL::isa($vals,'HASH')) {
+    if (defined $vals->{success}) {
+      $self->{success} = $vals->{success};
+    }
     if (defined $vals->{e}) {
       $self->{e} = $vals->{e};
     }
@@ -1180,6 +1258,25 @@ sub read {
     }
     SWITCH: for($fid)
     {
+      /^0$/ && do{      if ($ftype == TType::LIST) {
+        {
+          my $_size169 = 0;
+          $self->{success} = [];
+          my $_etype172 = 0;
+          $xfer += $input->readListBegin(\$_etype172, \$_size169);
+          for (my $_i173 = 0; $_i173 < $_size169; ++$_i173)
+          {
+            my $elem174 = undef;
+            $elem174 = new Blur::Generation();
+            $xfer += $elem174->read($input);
+            push(@{$self->{success}},$elem174);
+          }
+          $xfer += $input->readListEnd();
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
       /^1$/ && do{      if ($ftype == TType::STRUCT) {
         $self->{e} = new Blur::BlurException();
         $xfer += $self->{e}->read($input);
@@ -1199,6 +1296,20 @@ sub write {
   my ($self, $output) = @_;
   my $xfer   = 0;
   $xfer += $output->writeStructBegin('Blur_deleteDocuments_result');
+  if (defined $self->{success}) {
+    $xfer += $output->writeFieldBegin('success', TType::LIST, 0);
+    {
+      $xfer += $output->writeListBegin(TType::STRUCT, scalar(@{$self->{success}}));
+      {
+        foreach my $iter175 (@{$self->{success}}) 
+        {
+          $xfer += ${iter175}->write($output);
+        }
+      }
+      $xfer += $output->writeListEnd();
+    }
+    $xfer += $output->writeFieldEnd();
+  }
   if (defined $self->{e}) {
     $xfer += $output->writeFieldBegin('e', TType::STRUCT, 1);
     $xfer += $self->{e}->write($output);
@@ -1258,16 +1369,16 @@ sub read {
       last; };
       /^2$/ && do{      if ($ftype == TType::LIST) {
         {
-          my $_size155 = 0;
+          my $_size176 = 0;
           $self->{updatePackages} = [];
-          my $_etype158 = 0;
-          $xfer += $input->readListBegin(\$_etype158, \$_size155);
-          for (my $_i159 = 0; $_i159 < $_size155; ++$_i159)
+          my $_etype179 = 0;
+          $xfer += $input->readListBegin(\$_etype179, \$_size176);
+          for (my $_i180 = 0; $_i180 < $_size176; ++$_i180)
           {
-            my $elem160 = undef;
-            $elem160 = new Blur::UpdatePackage();
-            $xfer += $elem160->read($input);
-            push(@{$self->{updatePackages}},$elem160);
+            my $elem181 = undef;
+            $elem181 = new Blur::UpdatePackage();
+            $xfer += $elem181->read($input);
+            push(@{$self->{updatePackages}},$elem181);
           }
           $xfer += $input->readListEnd();
         }
@@ -1297,9 +1408,9 @@ sub write {
     {
       $xfer += $output->writeListBegin(TType::STRUCT, scalar(@{$self->{updatePackages}}));
       {
-        foreach my $iter161 (@{$self->{updatePackages}}) 
+        foreach my $iter182 (@{$self->{updatePackages}}) 
         {
-          $xfer += ${iter161}->write($output);
+          $xfer += ${iter182}->write($output);
         }
       }
       $xfer += $output->writeListEnd();
@@ -1313,14 +1424,18 @@ sub write {
 
 package Blur::Blur_updateDocuments_result;
 use base qw(Class::Accessor);
-Blur::Blur_updateDocuments_result->mk_accessors( qw( ) );
+Blur::Blur_updateDocuments_result->mk_accessors( qw( success ) );
 
 sub new {
   my $classname = shift;
   my $self      = {};
   my $vals      = shift || {};
+  $self->{success} = undef;
   $self->{e} = undef;
   if (UNIVERSAL::isa($vals,'HASH')) {
+    if (defined $vals->{success}) {
+      $self->{success} = $vals->{success};
+    }
     if (defined $vals->{e}) {
       $self->{e} = $vals->{e};
     }
@@ -1347,6 +1462,25 @@ sub read {
     }
     SWITCH: for($fid)
     {
+      /^0$/ && do{      if ($ftype == TType::LIST) {
+        {
+          my $_size183 = 0;
+          $self->{success} = [];
+          my $_etype186 = 0;
+          $xfer += $input->readListBegin(\$_etype186, \$_size183);
+          for (my $_i187 = 0; $_i187 < $_size183; ++$_i187)
+          {
+            my $elem188 = undef;
+            $elem188 = new Blur::Generation();
+            $xfer += $elem188->read($input);
+            push(@{$self->{success}},$elem188);
+          }
+          $xfer += $input->readListEnd();
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
       /^1$/ && do{      if ($ftype == TType::STRUCT) {
         $self->{e} = new Blur::BlurException();
         $xfer += $self->{e}->read($input);
@@ -1366,6 +1500,186 @@ sub write {
   my ($self, $output) = @_;
   my $xfer   = 0;
   $xfer += $output->writeStructBegin('Blur_updateDocuments_result');
+  if (defined $self->{success}) {
+    $xfer += $output->writeFieldBegin('success', TType::LIST, 0);
+    {
+      $xfer += $output->writeListBegin(TType::STRUCT, scalar(@{$self->{success}}));
+      {
+        foreach my $iter189 (@{$self->{success}}) 
+        {
+          $xfer += ${iter189}->write($output);
+        }
+      }
+      $xfer += $output->writeListEnd();
+    }
+    $xfer += $output->writeFieldEnd();
+  }
+  if (defined $self->{e}) {
+    $xfer += $output->writeFieldBegin('e', TType::STRUCT, 1);
+    $xfer += $self->{e}->write($output);
+    $xfer += $output->writeFieldEnd();
+  }
+  $xfer += $output->writeFieldStop();
+  $xfer += $output->writeStructEnd();
+  return $xfer;
+}
+
+package Blur::Blur_blockUntilGenerationIsVisible_args;
+use base qw(Class::Accessor);
+Blur::Blur_blockUntilGenerationIsVisible_args->mk_accessors( qw( generations forceRefresh ) );
+
+sub new {
+  my $classname = shift;
+  my $self      = {};
+  my $vals      = shift || {};
+  $self->{generations} = undef;
+  $self->{forceRefresh} = undef;
+  if (UNIVERSAL::isa($vals,'HASH')) {
+    if (defined $vals->{generations}) {
+      $self->{generations} = $vals->{generations};
+    }
+    if (defined $vals->{forceRefresh}) {
+      $self->{forceRefresh} = $vals->{forceRefresh};
+    }
+  }
+  return bless ($self, $classname);
+}
+
+sub getName {
+  return 'Blur_blockUntilGenerationIsVisible_args';
+}
+
+sub read {
+  my ($self, $input) = @_;
+  my $xfer  = 0;
+  my $fname;
+  my $ftype = 0;
+  my $fid   = 0;
+  $xfer += $input->readStructBegin(\$fname);
+  while (1) 
+  {
+    $xfer += $input->readFieldBegin(\$fname, \$ftype, \$fid);
+    if ($ftype == TType::STOP) {
+      last;
+    }
+    SWITCH: for($fid)
+    {
+      /^1$/ && do{      if ($ftype == TType::LIST) {
+        {
+          my $_size190 = 0;
+          $self->{generations} = [];
+          my $_etype193 = 0;
+          $xfer += $input->readListBegin(\$_etype193, \$_size190);
+          for (my $_i194 = 0; $_i194 < $_size190; ++$_i194)
+          {
+            my $elem195 = undef;
+            $elem195 = new Blur::Generation();
+            $xfer += $elem195->read($input);
+            push(@{$self->{generations}},$elem195);
+          }
+          $xfer += $input->readListEnd();
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
+      /^2$/ && do{      if ($ftype == TType::BOOL) {
+        $xfer += $input->readBool(\$self->{forceRefresh});
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
+        $xfer += $input->skip($ftype);
+    }
+    $xfer += $input->readFieldEnd();
+  }
+  $xfer += $input->readStructEnd();
+  return $xfer;
+}
+
+sub write {
+  my ($self, $output) = @_;
+  my $xfer   = 0;
+  $xfer += $output->writeStructBegin('Blur_blockUntilGenerationIsVisible_args');
+  if (defined $self->{generations}) {
+    $xfer += $output->writeFieldBegin('generations', TType::LIST, 1);
+    {
+      $xfer += $output->writeListBegin(TType::STRUCT, scalar(@{$self->{generations}}));
+      {
+        foreach my $iter196 (@{$self->{generations}}) 
+        {
+          $xfer += ${iter196}->write($output);
+        }
+      }
+      $xfer += $output->writeListEnd();
+    }
+    $xfer += $output->writeFieldEnd();
+  }
+  if (defined $self->{forceRefresh}) {
+    $xfer += $output->writeFieldBegin('forceRefresh', TType::BOOL, 2);
+    $xfer += $output->writeBool($self->{forceRefresh});
+    $xfer += $output->writeFieldEnd();
+  }
+  $xfer += $output->writeFieldStop();
+  $xfer += $output->writeStructEnd();
+  return $xfer;
+}
+
+package Blur::Blur_blockUntilGenerationIsVisible_result;
+use base qw(Class::Accessor);
+Blur::Blur_blockUntilGenerationIsVisible_result->mk_accessors( qw( ) );
+
+sub new {
+  my $classname = shift;
+  my $self      = {};
+  my $vals      = shift || {};
+  $self->{e} = undef;
+  if (UNIVERSAL::isa($vals,'HASH')) {
+    if (defined $vals->{e}) {
+      $self->{e} = $vals->{e};
+    }
+  }
+  return bless ($self, $classname);
+}
+
+sub getName {
+  return 'Blur_blockUntilGenerationIsVisible_result';
+}
+
+sub read {
+  my ($self, $input) = @_;
+  my $xfer  = 0;
+  my $fname;
+  my $ftype = 0;
+  my $fid   = 0;
+  $xfer += $input->readStructBegin(\$fname);
+  while (1) 
+  {
+    $xfer += $input->readFieldBegin(\$fname, \$ftype, \$fid);
+    if ($ftype == TType::STOP) {
+      last;
+    }
+    SWITCH: for($fid)
+    {
+      /^1$/ && do{      if ($ftype == TType::STRUCT) {
+        $self->{e} = new Blur::BlurException();
+        $xfer += $self->{e}->read($input);
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
+        $xfer += $input->skip($ftype);
+    }
+    $xfer += $input->readFieldEnd();
+  }
+  $xfer += $input->readStructEnd();
+  return $xfer;
+}
+
+sub write {
+  my ($self, $output) = @_;
+  my $xfer   = 0;
+  $xfer += $output->writeStructBegin('Blur_blockUntilGenerationIsVisible_result');
   if (defined $self->{e}) {
     $xfer += $output->writeFieldBegin('e', TType::STRUCT, 1);
     $xfer += $self->{e}->write($output);
@@ -1464,15 +1778,15 @@ sub read {
     {
       /^0$/ && do{      if ($ftype == TType::LIST) {
         {
-          my $_size162 = 0;
+          my $_size197 = 0;
           $self->{success} = [];
-          my $_etype165 = 0;
-          $xfer += $input->readListBegin(\$_etype165, \$_size162);
-          for (my $_i166 = 0; $_i166 < $_size162; ++$_i166)
+          my $_etype200 = 0;
+          $xfer += $input->readListBegin(\$_etype200, \$_size197);
+          for (my $_i201 = 0; $_i201 < $_size197; ++$_i201)
           {
-            my $elem167 = undef;
-            $xfer += $input->readString(\$elem167);
-            push(@{$self->{success}},$elem167);
+            my $elem202 = undef;
+            $xfer += $input->readString(\$elem202);
+            push(@{$self->{success}},$elem202);
           }
           $xfer += $input->readListEnd();
         }
@@ -1504,9 +1818,9 @@ sub write {
     {
       $xfer += $output->writeListBegin(TType::STRING, scalar(@{$self->{success}}));
       {
-        foreach my $iter168 (@{$self->{success}}) 
+        foreach my $iter203 (@{$self->{success}}) 
         {
-          $xfer += $output->writeString($iter168);
+          $xfer += $output->writeString($iter203);
         }
       }
       $xfer += $output->writeListEnd();
@@ -1644,15 +1958,15 @@ sub read {
     {
       /^0$/ && do{      if ($ftype == TType::LIST) {
         {
-          my $_size169 = 0;
+          my $_size204 = 0;
           $self->{success} = [];
-          my $_etype172 = 0;
-          $xfer += $input->readListBegin(\$_etype172, \$_size169);
-          for (my $_i173 = 0; $_i173 < $_size169; ++$_i173)
+          my $_etype207 = 0;
+          $xfer += $input->readListBegin(\$_etype207, \$_size204);
+          for (my $_i208 = 0; $_i208 < $_size204; ++$_i208)
           {
-            my $elem174 = undef;
-            $xfer += $input->readI32(\$elem174);
-            push(@{$self->{success}},$elem174);
+            my $elem209 = undef;
+            $xfer += $input->readI32(\$elem209);
+            push(@{$self->{success}},$elem209);
           }
           $xfer += $input->readListEnd();
         }
@@ -1684,9 +1998,9 @@ sub write {
     {
       $xfer += $output->writeListBegin(TType::I32, scalar(@{$self->{success}}));
       {
-        foreach my $iter175 (@{$self->{success}}) 
+        foreach my $iter210 (@{$self->{success}}) 
         {
-          $xfer += $output->writeI32($iter175);
+          $xfer += $output->writeI32($iter210);
         }
       }
       $xfer += $output->writeListEnd();
@@ -1791,15 +2105,15 @@ sub read {
     {
       /^0$/ && do{      if ($ftype == TType::LIST) {
         {
-          my $_size176 = 0;
+          my $_size211 = 0;
           $self->{success} = [];
-          my $_etype179 = 0;
-          $xfer += $input->readListBegin(\$_etype179, \$_size176);
-          for (my $_i180 = 0; $_i180 < $_size176; ++$_i180)
+          my $_etype214 = 0;
+          $xfer += $input->readListBegin(\$_etype214, \$_size211);
+          for (my $_i215 = 0; $_i215 < $_size211; ++$_i215)
           {
-            my $elem181 = undef;
-            $xfer += $input->readString(\$elem181);
-            push(@{$self->{success}},$elem181);
+            my $elem216 = undef;
+            $xfer += $input->readString(\$elem216);
+            push(@{$self->{success}},$elem216);
           }
           $xfer += $input->readListEnd();
         }
@@ -1831,9 +2145,9 @@ sub write {
     {
       $xfer += $output->writeListBegin(TType::STRING, scalar(@{$self->{success}}));
       {
-        foreach my $iter182 (@{$self->{success}}) 
+        foreach my $iter217 (@{$self->{success}}) 
         {
-          $xfer += $output->writeString($iter182);
+          $xfer += $output->writeString($iter217);
         }
       }
       $xfer += $output->writeListEnd();
@@ -2905,15 +3219,15 @@ sub read {
     {
       /^0$/ && do{      if ($ftype == TType::LIST) {
         {
-          my $_size183 = 0;
+          my $_size218 = 0;
           $self->{success} = [];
-          my $_etype186 = 0;
-          $xfer += $input->readListBegin(\$_etype186, \$_size183);
-          for (my $_i187 = 0; $_i187 < $_size183; ++$_i187)
+          my $_etype221 = 0;
+          $xfer += $input->readListBegin(\$_etype221, \$_size218);
+          for (my $_i222 = 0; $_i222 < $_size218; ++$_i222)
           {
-            my $elem188 = undef;
-            $xfer += $input->readI64(\$elem188);
-            push(@{$self->{success}},$elem188);
+            my $elem223 = undef;
+            $xfer += $input->readI64(\$elem223);
+            push(@{$self->{success}},$elem223);
           }
           $xfer += $input->readListEnd();
         }
@@ -2945,9 +3259,9 @@ sub write {
     {
       $xfer += $output->writeListBegin(TType::I64, scalar(@{$self->{success}}));
       {
-        foreach my $iter189 (@{$self->{success}}) 
+        foreach my $iter224 (@{$self->{success}}) 
         {
-          $xfer += $output->writeI64($iter189);
+          $xfer += $output->writeI64($iter224);
         }
       }
       $xfer += $output->writeListEnd();
@@ -3483,6 +3797,14 @@ sub updateDocuments{
   die 'implement interface';
 }
 
+sub blockUntilGenerationIsVisible{
+  my $self = shift;
+  my $generations = shift;
+  my $forceRefresh = shift;
+
+  die 'implement interface';
+}
+
 sub serverList{
   my $self = shift;
 
@@ -3657,6 +3979,14 @@ sub updateDocuments{
   return $self->{impl}->updateDocuments($options, $updatePackages);
 }
 
+sub blockUntilGenerationIsVisible{
+  my ($self, $request) = @_;
+
+  my $generations = ($request->{'generations'}) ? $request->{'generations'} : undef;
+  my $forceRefresh = ($request->{'forceRefresh'}) ? $request->{'forceRefresh'} : undef;
+  return $self->{impl}->blockUntilGenerationIsVisible($generations, $forceRefresh);
+}
+
 sub serverList{
   my ($self, $request) = @_;
 
@@ -3965,7 +4295,7 @@ sub addDocuments{
   my $documents = shift;
 
     $self->send_addDocuments($options, $documents);
-  $self->recv_addDocuments();
+  return $self->recv_addDocuments();
 }
 
 sub send_addDocuments{
@@ -4000,10 +4330,13 @@ sub recv_addDocuments{
   $result->read($self->{input});
   $self->{input}->readMessageEnd();
 
+  if (defined $result->{success} ) {
+    return $result->{success};
+  }
   if (defined $result->{e}) {
     die $result->{e};
   }
-  return;
+  die "addDocuments failed: unknown result";
 }
 sub deleteDocumentsByQueries{
   my $self = shift;
@@ -4011,7 +4344,7 @@ sub deleteDocumentsByQueries{
   my $queries = shift;
 
     $self->send_deleteDocumentsByQueries($options, $queries);
-  $self->recv_deleteDocumentsByQueries();
+  return $self->recv_deleteDocumentsByQueries();
 }
 
 sub send_deleteDocumentsByQueries{
@@ -4046,10 +4379,13 @@ sub recv_deleteDocumentsByQueries{
   $result->read($self->{input});
   $self->{input}->readMessageEnd();
 
+  if (defined $result->{success} ) {
+    return $result->{success};
+  }
   if (defined $result->{e}) {
     die $result->{e};
   }
-  return;
+  die "deleteDocumentsByQueries failed: unknown result";
 }
 sub deleteDocuments{
   my $self = shift;
@@ -4057,7 +4393,7 @@ sub deleteDocuments{
   my $terms = shift;
 
     $self->send_deleteDocuments($options, $terms);
-  $self->recv_deleteDocuments();
+  return $self->recv_deleteDocuments();
 }
 
 sub send_deleteDocuments{
@@ -4092,10 +4428,13 @@ sub recv_deleteDocuments{
   $result->read($self->{input});
   $self->{input}->readMessageEnd();
 
+  if (defined $result->{success} ) {
+    return $result->{success};
+  }
   if (defined $result->{e}) {
     die $result->{e};
   }
-  return;
+  die "deleteDocuments failed: unknown result";
 }
 sub updateDocuments{
   my $self = shift;
@@ -4103,7 +4442,7 @@ sub updateDocuments{
   my $updatePackages = shift;
 
     $self->send_updateDocuments($options, $updatePackages);
-  $self->recv_updateDocuments();
+  return $self->recv_updateDocuments();
 }
 
 sub send_updateDocuments{
@@ -4138,6 +4477,55 @@ sub recv_updateDocuments{
   $result->read($self->{input});
   $self->{input}->readMessageEnd();
 
+  if (defined $result->{success} ) {
+    return $result->{success};
+  }
+  if (defined $result->{e}) {
+    die $result->{e};
+  }
+  die "updateDocuments failed: unknown result";
+}
+sub blockUntilGenerationIsVisible{
+  my $self = shift;
+  my $generations = shift;
+  my $forceRefresh = shift;
+
+    $self->send_blockUntilGenerationIsVisible($generations, $forceRefresh);
+  $self->recv_blockUntilGenerationIsVisible();
+}
+
+sub send_blockUntilGenerationIsVisible{
+  my $self = shift;
+  my $generations = shift;
+  my $forceRefresh = shift;
+
+  $self->{output}->writeMessageBegin('blockUntilGenerationIsVisible', TMessageType::CALL, $self->{seqid});
+  my $args = new Blur::Blur_blockUntilGenerationIsVisible_args();
+  $args->{generations} = $generations;
+  $args->{forceRefresh} = $forceRefresh;
+  $args->write($self->{output});
+  $self->{output}->writeMessageEnd();
+  $self->{output}->getTransport()->flush();
+}
+
+sub recv_blockUntilGenerationIsVisible{
+  my $self = shift;
+
+  my $rseqid = 0;
+  my $fname;
+  my $mtype = 0;
+
+  $self->{input}->readMessageBegin(\$fname, \$mtype, \$rseqid);
+  if ($mtype == TMessageType::EXCEPTION) {
+    my $x = new TApplicationException();
+    $x->read($self->{input});
+    $self->{input}->readMessageEnd();
+    die $x;
+  }
+  my $result = new Blur::Blur_blockUntilGenerationIsVisible_result();
+  $result->read($self->{input});
+  $self->{input}->readMessageEnd();
+
   if (defined $result->{e}) {
     die $result->{e};
   }
@@ -4884,7 +5272,7 @@ sub process_addDocuments {
     $input->readMessageEnd();
     my $result = new Blur::Blur_addDocuments_result();
     eval {
-      $self->{handler}->addDocuments($args->options, $args->documents);
+      $result->{success} = $self->{handler}->addDocuments($args->options, $args->documents);
     }; if( UNIVERSAL::isa($@,'Blur::BlurException') ){ 
       $result->{e} = $@;
     }
@@ -4901,7 +5289,7 @@ sub process_deleteDocumentsByQueries {
     $input->readMessageEnd();
     my $result = new Blur::Blur_deleteDocumentsByQueries_result();
     eval {
-      $self->{handler}->deleteDocumentsByQueries($args->options, $args->queries);
+      $result->{success} = $self->{handler}->deleteDocumentsByQueries($args->options, $args->queries);
     }; if( UNIVERSAL::isa($@,'Blur::BlurException') ){ 
       $result->{e} = $@;
     }
@@ -4918,7 +5306,7 @@ sub process_deleteDocuments {
     $input->readMessageEnd();
     my $result = new Blur::Blur_deleteDocuments_result();
     eval {
-      $self->{handler}->deleteDocuments($args->options, $args->terms);
+      $result->{success} = $self->{handler}->deleteDocuments($args->options, $args->terms);
     }; if( UNIVERSAL::isa($@,'Blur::BlurException') ){ 
       $result->{e} = $@;
     }
@@ -4935,7 +5323,7 @@ sub process_updateDocuments {
     $input->readMessageEnd();
     my $result = new Blur::Blur_updateDocuments_result();
     eval {
-      $self->{handler}->updateDocuments($args->options, $args->updatePackages);
+      $result->{success} = $self->{handler}->updateDocuments($args->options, $args->updatePackages);
     }; if( UNIVERSAL::isa($@,'Blur::BlurException') ){ 
       $result->{e} = $@;
     }
@@ -4945,6 +5333,23 @@ sub process_updateDocuments {
     $output->getTransport()->flush();
 }
 
+sub process_blockUntilGenerationIsVisible {
+    my ($self, $seqid, $input, $output) = @_;
+    my $args = new Blur::Blur_blockUntilGenerationIsVisible_args();
+    $args->read($input);
+    $input->readMessageEnd();
+    my $result = new Blur::Blur_blockUntilGenerationIsVisible_result();
+    eval {
+      $self->{handler}->blockUntilGenerationIsVisible($args->generations, $args->forceRefresh);
+    }; if( UNIVERSAL::isa($@,'Blur::BlurException') ){ 
+      $result->{e} = $@;
+    }
+    $output->writeMessageBegin('blockUntilGenerationIsVisible', TMessageType::REPLY, $seqid);
+    $result->write($output);
+    $output->writeMessageEnd();
+    $output->getTransport()->flush();
+}
+
 sub process_serverList {
     my ($self, $seqid, $input, $output) = @_;
     my $args = new Blur::Blur_serverList_args();

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/interface/gen-perl/Blur/Types.pm
----------------------------------------------------------------------
diff --git a/interface/gen-perl/Blur/Types.pm b/interface/gen-perl/Blur/Types.pm
index b73886d..32f5fca 100644
--- a/interface/gen-perl/Blur/Types.pm
+++ b/interface/gen-perl/Blur/Types.pm
@@ -2346,4 +2346,98 @@ sub write {
   return $xfer;
 }
 
+package Blur::Generation;
+use base qw(Class::Accessor);
+Blur::Generation->mk_accessors( qw( table shardIndex generation ) );
+
+sub new {
+  my $classname = shift;
+  my $self      = {};
+  my $vals      = shift || {};
+  $self->{table} = undef;
+  $self->{shardIndex} = undef;
+  $self->{generation} = undef;
+  if (UNIVERSAL::isa($vals,'HASH')) {
+    if (defined $vals->{table}) {
+      $self->{table} = $vals->{table};
+    }
+    if (defined $vals->{shardIndex}) {
+      $self->{shardIndex} = $vals->{shardIndex};
+    }
+    if (defined $vals->{generation}) {
+      $self->{generation} = $vals->{generation};
+    }
+  }
+  return bless ($self, $classname);
+}
+
+sub getName {
+  return 'Generation';
+}
+
+sub read {
+  my ($self, $input) = @_;
+  my $xfer  = 0;
+  my $fname;
+  my $ftype = 0;
+  my $fid   = 0;
+  $xfer += $input->readStructBegin(\$fname);
+  while (1) 
+  {
+    $xfer += $input->readFieldBegin(\$fname, \$ftype, \$fid);
+    if ($ftype == TType::STOP) {
+      last;
+    }
+    SWITCH: for($fid)
+    {
+      /^1$/ && do{      if ($ftype == TType::STRING) {
+        $xfer += $input->readString(\$self->{table});
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
+      /^2$/ && do{      if ($ftype == TType::I32) {
+        $xfer += $input->readI32(\$self->{shardIndex});
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
+      /^3$/ && do{      if ($ftype == TType::I64) {
+        $xfer += $input->readI64(\$self->{generation});
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      last; };
+        $xfer += $input->skip($ftype);
+    }
+    $xfer += $input->readFieldEnd();
+  }
+  $xfer += $input->readStructEnd();
+  return $xfer;
+}
+
+sub write {
+  my ($self, $output) = @_;
+  my $xfer   = 0;
+  $xfer += $output->writeStructBegin('Generation');
+  if (defined $self->{table}) {
+    $xfer += $output->writeFieldBegin('table', TType::STRING, 1);
+    $xfer += $output->writeString($self->{table});
+    $xfer += $output->writeFieldEnd();
+  }
+  if (defined $self->{shardIndex}) {
+    $xfer += $output->writeFieldBegin('shardIndex', TType::I32, 2);
+    $xfer += $output->writeI32($self->{shardIndex});
+    $xfer += $output->writeFieldEnd();
+  }
+  if (defined $self->{generation}) {
+    $xfer += $output->writeFieldBegin('generation', TType::I64, 3);
+    $xfer += $output->writeI64($self->{generation});
+    $xfer += $output->writeFieldEnd();
+  }
+  $xfer += $output->writeFieldStop();
+  $xfer += $output->writeStructEnd();
+  return $xfer;
+}
+
 1;

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/interface/gen-rb/blur.rb
----------------------------------------------------------------------
diff --git a/interface/gen-rb/blur.rb b/interface/gen-rb/blur.rb
index 2288816..68b0a27 100644
--- a/interface/gen-rb/blur.rb
+++ b/interface/gen-rb/blur.rb
@@ -77,7 +77,7 @@ module Blur
 
       def addDocuments(options, documents)
         send_addDocuments(options, documents)
-        recv_addDocuments()
+        return recv_addDocuments()
       end
 
       def send_addDocuments(options, documents)
@@ -86,13 +86,14 @@ module Blur
 
       def recv_addDocuments()
         result = receive_message(AddDocuments_result)
+        return result.success unless result.success.nil?
         raise result.e unless result.e.nil?
-        return
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'addDocuments failed: unknown result')
       end
 
       def deleteDocumentsByQueries(options, queries)
         send_deleteDocumentsByQueries(options, queries)
-        recv_deleteDocumentsByQueries()
+        return recv_deleteDocumentsByQueries()
       end
 
       def send_deleteDocumentsByQueries(options, queries)
@@ -101,13 +102,14 @@ module Blur
 
       def recv_deleteDocumentsByQueries()
         result = receive_message(DeleteDocumentsByQueries_result)
+        return result.success unless result.success.nil?
         raise result.e unless result.e.nil?
-        return
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'deleteDocumentsByQueries failed: unknown result')
       end
 
       def deleteDocuments(options, terms)
         send_deleteDocuments(options, terms)
-        recv_deleteDocuments()
+        return recv_deleteDocuments()
       end
 
       def send_deleteDocuments(options, terms)
@@ -116,13 +118,14 @@ module Blur
 
       def recv_deleteDocuments()
         result = receive_message(DeleteDocuments_result)
+        return result.success unless result.success.nil?
         raise result.e unless result.e.nil?
-        return
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'deleteDocuments failed: unknown result')
       end
 
       def updateDocuments(options, updatePackages)
         send_updateDocuments(options, updatePackages)
-        recv_updateDocuments()
+        return recv_updateDocuments()
       end
 
       def send_updateDocuments(options, updatePackages)
@@ -131,6 +134,22 @@ module Blur
 
       def recv_updateDocuments()
         result = receive_message(UpdateDocuments_result)
+        return result.success unless result.success.nil?
+        raise result.e unless result.e.nil?
+        raise ::Thrift::ApplicationException.new(::Thrift::ApplicationException::MISSING_RESULT, 'updateDocuments failed: unknown result')
+      end
+
+      def blockUntilGenerationIsVisible(generations, forceRefresh)
+        send_blockUntilGenerationIsVisible(generations, forceRefresh)
+        recv_blockUntilGenerationIsVisible()
+      end
+
+      def send_blockUntilGenerationIsVisible(generations, forceRefresh)
+        send_message('blockUntilGenerationIsVisible', BlockUntilGenerationIsVisible_args, :generations => generations, :forceRefresh => forceRefresh)
+      end
+
+      def recv_blockUntilGenerationIsVisible()
+        result = receive_message(BlockUntilGenerationIsVisible_result)
         raise result.e unless result.e.nil?
         return
       end
@@ -407,7 +426,7 @@ module Blur
         args = read_args(iprot, AddDocuments_args)
         result = AddDocuments_result.new()
         begin
-          @handler.addDocuments(args.options, args.documents)
+          result.success = @handler.addDocuments(args.options, args.documents)
         rescue ::Blur::BlurException => e
           result.e = e
         end
@@ -418,7 +437,7 @@ module Blur
         args = read_args(iprot, DeleteDocumentsByQueries_args)
         result = DeleteDocumentsByQueries_result.new()
         begin
-          @handler.deleteDocumentsByQueries(args.options, args.queries)
+          result.success = @handler.deleteDocumentsByQueries(args.options, args.queries)
         rescue ::Blur::BlurException => e
           result.e = e
         end
@@ -429,7 +448,7 @@ module Blur
         args = read_args(iprot, DeleteDocuments_args)
         result = DeleteDocuments_result.new()
         begin
-          @handler.deleteDocuments(args.options, args.terms)
+          result.success = @handler.deleteDocuments(args.options, args.terms)
         rescue ::Blur::BlurException => e
           result.e = e
         end
@@ -440,13 +459,24 @@ module Blur
         args = read_args(iprot, UpdateDocuments_args)
         result = UpdateDocuments_result.new()
         begin
-          @handler.updateDocuments(args.options, args.updatePackages)
+          result.success = @handler.updateDocuments(args.options, args.updatePackages)
         rescue ::Blur::BlurException => e
           result.e = e
         end
         write_result(result, oprot, 'updateDocuments', seqid)
       end
 
+      def process_blockUntilGenerationIsVisible(seqid, iprot, oprot)
+        args = read_args(iprot, BlockUntilGenerationIsVisible_args)
+        result = BlockUntilGenerationIsVisible_result.new()
+        begin
+          @handler.blockUntilGenerationIsVisible(args.generations, args.forceRefresh)
+        rescue ::Blur::BlurException => e
+          result.e = e
+        end
+        write_result(result, oprot, 'blockUntilGenerationIsVisible', seqid)
+      end
+
       def process_serverList(seqid, iprot, oprot)
         args = read_args(iprot, ServerList_args)
         result = ServerList_result.new()
@@ -765,9 +795,11 @@ module Blur
 
     class AddDocuments_result
       include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
       E = 1
 
       FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::LIST, :name => 'success', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Blur::Generation}},
         E => {:type => ::Thrift::Types::STRUCT, :name => 'e', :class => ::Blur::BlurException}
       }
 
@@ -799,9 +831,11 @@ module Blur
 
     class DeleteDocumentsByQueries_result
       include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
       E = 1
 
       FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::LIST, :name => 'success', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Blur::Generation}},
         E => {:type => ::Thrift::Types::STRUCT, :name => 'e', :class => ::Blur::BlurException}
       }
 
@@ -833,9 +867,11 @@ module Blur
 
     class DeleteDocuments_result
       include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
       E = 1
 
       FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::LIST, :name => 'success', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Blur::Generation}},
         E => {:type => ::Thrift::Types::STRUCT, :name => 'e', :class => ::Blur::BlurException}
       }
 
@@ -867,6 +903,42 @@ module Blur
 
     class UpdateDocuments_result
       include ::Thrift::Struct, ::Thrift::Struct_Union
+      SUCCESS = 0
+      E = 1
+
+      FIELDS = {
+        SUCCESS => {:type => ::Thrift::Types::LIST, :name => 'success', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Blur::Generation}},
+        E => {:type => ::Thrift::Types::STRUCT, :name => 'e', :class => ::Blur::BlurException}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class BlockUntilGenerationIsVisible_args
+      include ::Thrift::Struct, ::Thrift::Struct_Union
+      GENERATIONS = 1
+      FORCEREFRESH = 2
+
+      FIELDS = {
+        GENERATIONS => {:type => ::Thrift::Types::LIST, :name => 'generations', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Blur::Generation}},
+        FORCEREFRESH => {:type => ::Thrift::Types::BOOL, :name => 'forceRefresh'}
+      }
+
+      def struct_fields; FIELDS; end
+
+      def validate
+      end
+
+      ::Thrift::Struct.generate_accessors self
+    end
+
+    class BlockUntilGenerationIsVisible_result
+      include ::Thrift::Struct, ::Thrift::Struct_Union
       E = 1
 
       FIELDS = {

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/interface/gen-rb/blur_types.rb
----------------------------------------------------------------------
diff --git a/interface/gen-rb/blur_types.rb b/interface/gen-rb/blur_types.rb
index 0fc8dc4..01f01e3 100644
--- a/interface/gen-rb/blur_types.rb
+++ b/interface/gen-rb/blur_types.rb
@@ -527,4 +527,24 @@ module Blur
     ::Thrift::Struct.generate_accessors self
   end
 
+  class Generation
+    include ::Thrift::Struct, ::Thrift::Struct_Union
+    TABLE = 1
+    SHARDINDEX = 2
+    GENERATION = 3
+
+    FIELDS = {
+      TABLE => {:type => ::Thrift::Types::STRING, :name => 'table'},
+      SHARDINDEX => {:type => ::Thrift::Types::I32, :name => 'shardIndex'},
+      GENERATION => {:type => ::Thrift::Types::I64, :name => 'generation'}
+    }
+
+    def struct_fields; FIELDS; end
+
+    def validate
+    end
+
+    ::Thrift::Struct.generate_accessors self
+  end
+
 end

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndex.java
----------------------------------------------------------------------
diff --git a/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndex.java b/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndex.java
index ed54de6..ef27d73 100644
--- a/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndex.java
+++ b/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndex.java
@@ -34,9 +34,10 @@ public abstract class BlurIndex {
   public abstract AtomicBoolean isClosed();
   public abstract void optimize(int numberOfSegmentsPerShard) throws IOException;
 
-  public abstract void addDocuments(boolean waitToBeVisible, boolean wal, List<Document> documents) throws IOException;
-  public abstract void deleteDocuments(boolean waitToBeVisible, boolean wal, Term... deleteTerms) throws IOException;
-  public abstract void deleteDocuments(boolean waitToBeVisible, boolean wal, ByteBuffer... deleteQueries) throws IOException;
-  public abstract void updateDocuments(boolean waitToBeVisible, boolean wal, List<UpdatePackage> updatePackages) throws IOException;
+  public abstract long addDocuments(boolean waitToBeVisible, boolean wal, List<Document> documents) throws IOException;
+  public abstract long deleteDocuments(boolean waitToBeVisible, boolean wal, Term... deleteTerms) throws IOException;
+  public abstract long deleteDocuments(boolean waitToBeVisible, boolean wal, ByteBuffer... deleteQueries) throws IOException;
+  public abstract long updateDocuments(boolean waitToBeVisible, boolean wal, List<UpdatePackage> updatePackages) throws IOException;
+  public abstract void blockUntilGenerationIsVisible(long generation, boolean forceRefresh) throws IOException;
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndexReader.java
----------------------------------------------------------------------
diff --git a/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndexReader.java b/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndexReader.java
index d10a3e5..88df8ec 100644
--- a/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndexReader.java
+++ b/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurIndexReader.java
@@ -65,22 +65,27 @@ public class BlurIndexReader extends AbstractBlurIndex {
   }
 
   @Override
-  public void addDocuments(boolean waitToBeVisible, boolean wal, List<Document> documents) throws IOException {
+  public long addDocuments(boolean waitToBeVisible, boolean wal, List<Document> documents) throws IOException {
     throw new RuntimeException("Read-only shard");
   }
 
   @Override
-  public void deleteDocuments(boolean waitToBeVisible, boolean wal, Term... deleteTerm) throws IOException {
+  public long deleteDocuments(boolean waitToBeVisible, boolean wal, Term... deleteTerm) throws IOException {
     throw new RuntimeException("Read-only shard");
   }
 
   @Override
-  public void deleteDocuments(boolean waitToBeVisible, boolean wal, ByteBuffer... deleteQueries) throws IOException {
+  public long deleteDocuments(boolean waitToBeVisible, boolean wal, ByteBuffer... deleteQueries) throws IOException {
     throw new RuntimeException("Read-only shard"); 
   }
 
   @Override
-  public void updateDocuments(boolean waitToBeVisible, boolean wal, List<UpdatePackage> updatePackages) throws IOException {
+  public long updateDocuments(boolean waitToBeVisible, boolean wal, List<UpdatePackage> updatePackages) throws IOException {
+    throw new RuntimeException("Read-only shard");
+  }
+
+  @Override
+  public void blockUntilGenerationIsVisible(long generation, boolean forceRefresh) {
     throw new RuntimeException("Read-only shard");
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurNRTIndex.java
----------------------------------------------------------------------
diff --git a/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurNRTIndex.java b/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurNRTIndex.java
index bfa5314..397573c 100644
--- a/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurNRTIndex.java
+++ b/src/blur-core/src/main/java/org/apache/blur/manager/writer/BlurNRTIndex.java
@@ -128,27 +128,40 @@ public class BlurNRTIndex extends BlurIndex {
   }
 
   @Override
-  public void addDocuments(boolean waitToBeVisible, boolean wal, List<Document> documents) throws IOException {
+  public long addDocuments(boolean waitToBeVisible, boolean wal, List<Document> documents) throws IOException {
     long generation = _recorder.addDocuments(wal, documents, _trackingWriter);
     waitToBeVisible(waitToBeVisible, generation);
+    return generation;
   }
 
   @Override
-  public void deleteDocuments(boolean waitToBeVisible, boolean wal, Term... deleteTerm) throws IOException {
+  public long deleteDocuments(boolean waitToBeVisible, boolean wal, Term... deleteTerm) throws IOException {
     long generation = _recorder.deleteDocuments(wal, deleteTerm, _trackingWriter);
     waitToBeVisible(waitToBeVisible, generation);
+    return generation;
   }
 
   @Override
-  public void deleteDocuments(boolean waitToBeVisible, boolean wal, ByteBuffer... deleteQueries) throws IOException {
+  public long deleteDocuments(boolean waitToBeVisible, boolean wal, ByteBuffer... deleteQueries) throws IOException {
     long generation = _recorder.deleteDocuments(wal, deleteQueries, _trackingWriter);
     waitToBeVisible(waitToBeVisible, generation);
+    return generation;
   }
-  
+
   @Override
-  public void updateDocuments(boolean waitToBeVisible, boolean wal, List<UpdatePackage> updatePackages) throws IOException {
-    long generation = _recorder.updateDocuments(wal, updatePackages, _trackingWriter);    
+  public long updateDocuments(boolean waitToBeVisible, boolean wal, List<UpdatePackage> updatePackages) throws IOException {
+    long generation = _recorder.updateDocuments(wal, updatePackages, _trackingWriter);
     waitToBeVisible(waitToBeVisible, generation);
+    return generation;
+  }
+
+  @Override
+  public synchronized void blockUntilGenerationIsVisible(long generation, boolean forceRefresh) throws IOException {
+    if (forceRefresh) {
+      _nrtManager.maybeRefresh();
+      swap();
+    }
+    waitToBeVisible(true, generation);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/src/blur-core/src/main/java/org/apache/blur/thrift/BlurShardServer.java
----------------------------------------------------------------------
diff --git a/src/blur-core/src/main/java/org/apache/blur/thrift/BlurShardServer.java b/src/blur-core/src/main/java/org/apache/blur/thrift/BlurShardServer.java
index 032aa3c..d362653 100644
--- a/src/blur-core/src/main/java/org/apache/blur/thrift/BlurShardServer.java
+++ b/src/blur-core/src/main/java/org/apache/blur/thrift/BlurShardServer.java
@@ -24,6 +24,7 @@ import static org.apache.blur.utils.ThriftLuceneConversion.toThrift;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -51,6 +52,7 @@ import org.apache.blur.thrift.generated.Blur.Client;
 import org.apache.blur.thrift.generated.Blur.Iface;
 import org.apache.blur.thrift.generated.BlurException;
 import org.apache.blur.thrift.generated.Document;
+import org.apache.blur.thrift.generated.Generation;
 import org.apache.blur.thrift.generated.LiveSchema;
 import org.apache.blur.thrift.generated.MutateOptions;
 import org.apache.blur.thrift.generated.QueryArgs;
@@ -396,64 +398,75 @@ public class BlurShardServer extends TableAdmin implements Iface {
   }
 
   @Override
-  public void addDocuments(MutateOptions options, List<Document> documents) throws BlurException, TException {
+  public List<Generation> addDocuments(MutateOptions options, List<Document> documents) throws BlurException, TException {
     String table = options.getTable();
     int shardIndex = options.getShardIndex();
     boolean waitToBeVisible = options.isWaitToBeVisible();
     boolean writeAheadLog = options.isWriteAheadLog();
+    List<Generation> generations = new ArrayList<Generation>();
     try {
       BlurIndex index = getIndex(table, shardIndex);
       if (index == null) {
-        forwardAddDocuments(options, documents);
+        generations.addAll(forwardAddDocuments(options, documents));
       } else {
-        index.addDocuments(waitToBeVisible, writeAheadLog, documents);
+        long generation = index.addDocuments(waitToBeVisible, writeAheadLog, documents);
+        generations.add(new Generation(table, shardIndex, generation));
       }
+      return generations;
     } catch (Throwable t) {
       LOG.error("Unknown error", t);
       throw new BException(t.getMessage(), t);
     }
   }
 
-  private void forwardAddDocuments(final MutateOptions options, final List<Document> documents) throws BlurException, TException, IOException {
-    String table = options.getTable();
-    int shardIndex = options.getShardIndex();
-    Connection connection = getConnection(table, shardIndex);
-    BlurClientManager.execute(connection, new BlurCommand<Void>() {
-      @Override
-      public Void call(Client client) throws BlurException, TException {
-        client.addDocuments(options, documents);
-        return null;
+  @Override
+  public void blockUntilGenerationIsVisible(List<Generation> generations, boolean forceRefresh) throws BlurException, TException {
+    try {
+      for (Generation generation : generations) {
+        String table = generation.getTable();
+        int shardIndex = generation.getShardIndex();
+        BlurIndex index = getIndex(table, shardIndex);
+        if (index == null) {
+          forwardBlockUntilGenerationIsVisible(generation, forceRefresh);
+        } else {
+          index.blockUntilGenerationIsVisible(generation.getGeneration(), forceRefresh);
+        }
       }
-    });
+    } catch (Throwable t) {
+      LOG.error("Unknown error", t);
+      throw new BException(t.getMessage(), t);
+    }
   }
-  
-  private void forwardUpdateDocuments(final MutateOptions options, final List<UpdatePackage> updatePackages) throws BlurException, TException, IOException {
-    String table = options.getTable();
-    int shardIndex = options.getShardIndex();
+
+  private void forwardBlockUntilGenerationIsVisible(final Generation generation, final boolean forceRefresh) throws BlurException, TException, IOException {
+    String table = generation.getTable();
+    int shardIndex = generation.getShardIndex();
     Connection connection = getConnection(table, shardIndex);
     BlurClientManager.execute(connection, new BlurCommand<Void>() {
       @Override
       public Void call(Client client) throws BlurException, TException {
-        client.updateDocuments(options, updatePackages);
+        client.blockUntilGenerationIsVisible(Arrays.asList(generation), forceRefresh);
         return null;
       }
     });
   }
 
-  private Connection getConnection(String table, int shardIndex) {
-    String server = _layout.findServer(table, shardIndex, TYPE.WRITABLE);
-    return new Connection(server);
-  }
-
   @Override
-  public void deleteDocumentsByQueries(MutateOptions options, List<ByteBuffer> queries) throws BlurException, TException {
+  public List<Generation> deleteDocumentsByQueries(MutateOptions options, List<ByteBuffer> queries) throws BlurException, TException {
     String table = options.getTable();
     int shardIndex = options.getShardIndex();
     boolean waitToBeVisible = options.isWaitToBeVisible();
     boolean writeAheadLog = options.isWriteAheadLog();
+    List<Generation> generations = new ArrayList<Generation>();
     try {
       BlurIndex index = getIndex(table, shardIndex);
-      index.deleteDocuments(waitToBeVisible, writeAheadLog, queries.toArray(new ByteBuffer[queries.size()]));
+      if (index == null) {
+        generations.addAll(forwardDeleteDocumentsByQueries(options, queries));
+      } else {
+        long generation = index.deleteDocuments(waitToBeVisible, writeAheadLog, queries.toArray(new ByteBuffer[queries.size()]));
+        generations.add(new Generation(table, shardIndex, generation));
+      }
+      return generations;
     } catch (Throwable t) {
       LOG.error("Unknown error", t);
       throw new BException(t.getMessage(), t);
@@ -461,14 +474,21 @@ public class BlurShardServer extends TableAdmin implements Iface {
   }
 
   @Override
-  public void deleteDocuments(MutateOptions options, List<Term> terms) throws BlurException, TException {
+  public List<Generation> deleteDocuments(MutateOptions options, List<Term> terms) throws BlurException, TException {
     String table = options.getTable();
     int shardIndex = options.getShardIndex();
     boolean waitToBeVisible = options.isWaitToBeVisible();
     boolean writeAheadLog = options.isWriteAheadLog();
+    List<Generation> generations = new ArrayList<Generation>();
     try {
       BlurIndex index = getIndex(table, shardIndex);
-      index.deleteDocuments(waitToBeVisible, writeAheadLog, terms.toArray(new Term[terms.size()]));
+      if (index == null) {
+        generations.addAll(forwardDeleteDocuments(options, terms));
+      } else {
+        long generation = index.deleteDocuments(waitToBeVisible, writeAheadLog, terms.toArray(new Term[terms.size()]));
+        generations.add(new Generation(table, shardIndex, generation));
+      }
+      return generations;
     } catch (Throwable t) {
       LOG.error("Unknown error", t);
       throw new BException(t.getMessage(), t);
@@ -476,18 +496,21 @@ public class BlurShardServer extends TableAdmin implements Iface {
   }
 
   @Override
-  public void updateDocuments(MutateOptions options, List<UpdatePackage> updatePackages) throws BlurException, TException {
+  public List<Generation> updateDocuments(MutateOptions options, List<UpdatePackage> updatePackages) throws BlurException, TException {
     String table = options.getTable();
     int shardIndex = options.getShardIndex();
     boolean waitToBeVisible = options.isWaitToBeVisible();
     boolean writeAheadLog = options.isWriteAheadLog();
+    List<Generation> generations = new ArrayList<Generation>();
     try {
       BlurIndex index = getIndex(table, shardIndex);
       if (index == null) {
-        forwardUpdateDocuments(options, updatePackages);
+        generations.addAll(forwardUpdateDocuments(options, updatePackages));
       } else {
-        index.updateDocuments(waitToBeVisible, writeAheadLog, updatePackages);
+        long generation = index.updateDocuments(waitToBeVisible, writeAheadLog, updatePackages);
+        generations.add(new Generation(table, shardIndex, generation));
       }
+      return generations;
     } catch (Throwable t) {
       LOG.error("Unknown error", t);
       throw new BException(t.getMessage(), t);
@@ -539,4 +562,57 @@ public class BlurShardServer extends TableAdmin implements Iface {
     this._layout = layout;
   }
 
+  private List<Generation> forwardAddDocuments(final MutateOptions options, final List<Document> documents) throws BlurException, TException, IOException {
+    String table = options.getTable();
+    int shardIndex = options.getShardIndex();
+    Connection connection = getConnection(table, shardIndex);
+    return BlurClientManager.execute(connection, new BlurCommand<List<Generation>>() {
+      @Override
+      public List<Generation> call(Client client) throws BlurException, TException {
+        return client.addDocuments(options, documents);
+      }
+    });
+  }
+
+  private List<Generation> forwardUpdateDocuments(final MutateOptions options, final List<UpdatePackage> updatePackages) throws BlurException, TException, IOException {
+    String table = options.getTable();
+    int shardIndex = options.getShardIndex();
+    Connection connection = getConnection(table, shardIndex);
+    return BlurClientManager.execute(connection, new BlurCommand<List<Generation>>() {
+      @Override
+      public List<Generation> call(Client client) throws BlurException, TException {
+        return client.updateDocuments(options, updatePackages);
+      }
+    });
+  }
+
+  private List<Generation> forwardDeleteDocumentsByQueries(final MutateOptions options, final List<ByteBuffer> queries) throws BlurException, TException, IOException {
+    String table = options.getTable();
+    int shardIndex = options.getShardIndex();
+    Connection connection = getConnection(table, shardIndex);
+    return BlurClientManager.execute(connection, new BlurCommand<List<Generation>>() {
+      @Override
+      public List<Generation> call(Client client) throws BlurException, TException {
+        return client.deleteDocumentsByQueries(options, queries);
+      }
+    });
+  }
+
+  private List<Generation> forwardDeleteDocuments(final MutateOptions options, final List<Term> terms) throws BlurException, TException, IOException {
+    String table = options.getTable();
+    int shardIndex = options.getShardIndex();
+    Connection connection = getConnection(table, shardIndex);
+    return BlurClientManager.execute(connection, new BlurCommand<List<Generation>>() {
+      @Override
+      public List<Generation> call(Client client) throws BlurException, TException {
+        return client.deleteDocuments(options, terms);
+      }
+    });
+  }
+
+  private Connection getConnection(String table, int shardIndex) {
+    String server = _layout.findServer(table, shardIndex, TYPE.WRITABLE);
+    return new Connection(server);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/ce72e544/src/blur-core/src/test/java/org/apache/blur/thrift/ITBlurClusterTest.java
----------------------------------------------------------------------
diff --git a/src/blur-core/src/test/java/org/apache/blur/thrift/ITBlurClusterTest.java b/src/blur-core/src/test/java/org/apache/blur/thrift/ITBlurClusterTest.java
index 35c9fea..83d9ceb 100644
--- a/src/blur-core/src/test/java/org/apache/blur/thrift/ITBlurClusterTest.java
+++ b/src/blur-core/src/test/java/org/apache/blur/thrift/ITBlurClusterTest.java
@@ -33,6 +33,7 @@ import org.apache.blur.thrift.generated.Blur.Iface;
 import org.apache.blur.thrift.generated.BlurException;
 import org.apache.blur.thrift.generated.Document;
 import org.apache.blur.thrift.generated.Field;
+import org.apache.blur.thrift.generated.Generation;
 import org.apache.blur.thrift.generated.MutateOptions;
 import org.apache.blur.thrift.generated.QueryArgs;
 import org.apache.blur.thrift.generated.Session;
@@ -58,7 +59,7 @@ public class ITBlurClusterTest {
 
   private static final int SHARD_COUNT = 5;
   private static final File TMPDIR = new File(System.getProperty("blur.tmp.dir", "/tmp"));
-  private static final int SHARD_SERVERS = 2;
+  private static final int SHARD_SERVERS = 3;
 
   @BeforeClass
   public static void startCluster() throws IOException {
@@ -112,7 +113,9 @@ public class ITBlurClusterTest {
     tableDescriptor.setShardCount(SHARD_COUNT);
     tableDescriptor.setStoragePath(MiniCluster.getFileSystemUri().toString() + "/blur/test-add-table");
     client.createTable(tableDescriptor);
-    
+
+    List<Generation> generations = new ArrayList<Generation>();
+
     for (int s = 0; s < SHARD_COUNT; s++) {
       int length = 100;
       List<Document> documents = new ArrayList<Document>();
@@ -124,11 +127,13 @@ public class ITBlurClusterTest {
       }
       MutateOptions options = new MutateOptions();
       options.setTable(tableDescriptor.getName());
-      options.setWaitToBeVisible(true);
+      options.setWaitToBeVisible(false);
       options.setShardIndex(s);
-      client.addDocuments(options, documents);
+      generations.addAll(client.addDocuments(options, documents));
     }
 
+    client.blockUntilGenerationIsVisible(generations, true);
+
     Session session = client.openReadSession(tableDescriptor.getName());
     QueryArgs queryArgs = new QueryArgs();
     Term term = new Term("value", "test");
@@ -141,7 +146,7 @@ public class ITBlurClusterTest {
     }
     assertEquals(SHARD_COUNT * 100, totalHits);
   }
-  
+
   @Test
   public void testUpdateDocuments() throws BlurException, TException, InterruptedException, IOException {
     Iface client = getClient();
@@ -150,7 +155,7 @@ public class ITBlurClusterTest {
     tableDescriptor.setShardCount(SHARD_COUNT);
     tableDescriptor.setStoragePath(MiniCluster.getFileSystemUri().toString() + "/blur/test-update-table");
     client.createTable(tableDescriptor);
-    
+    List<Generation> generations = new ArrayList<Generation>();
     for (int s = 0; s < SHARD_COUNT; s++) {
       int length = 100;
       List<UpdatePackage> updatePackages = new ArrayList<UpdatePackage>();
@@ -166,11 +171,13 @@ public class ITBlurClusterTest {
       }
       MutateOptions options = new MutateOptions();
       options.setTable(tableDescriptor.getName());
-      options.setWaitToBeVisible(true);
+      options.setWaitToBeVisible(false);
       options.setShardIndex(s);
-      client.updateDocuments(options, updatePackages);
+      generations.addAll(client.updateDocuments(options, updatePackages));
     }
 
+    client.blockUntilGenerationIsVisible(generations, true);
+
     Session session = client.openReadSession(tableDescriptor.getName());
     QueryArgs queryArgs = new QueryArgs();
     Term term = new Term("value", "test");


Mime
View raw message