You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@gora.apache.org by le...@apache.org on 2014/09/01 21:54:16 UTC
[1/4] GORA 73 Merge goraci testing suite with master branch
Repository: gora
Updated Branches:
refs/heads/master dd35192ac -> 90d1cc0af
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/java/org/apache/gora/goraci/generated/CINode.java
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/java/org/apache/gora/goraci/generated/CINode.java b/gora-goraci/src/main/java/org/apache/gora/goraci/generated/CINode.java
new file mode 100644
index 0000000..134d688
--- /dev/null
+++ b/gora-goraci/src/main/java/org/apache/gora/goraci/generated/CINode.java
@@ -0,0 +1,424 @@
+/**
+ * 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.gora.goraci.generated;
+@SuppressWarnings("all")
+public class CINode extends org.apache.gora.persistency.impl.PersistentBase implements org.apache.avro.specific.SpecificRecord, org.apache.gora.persistency.Persistent {
+ public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"CINode\",\"namespace\":\"org.apache.gora.goraci.generated\",\"fields\":[{\"name\":\"prev\",\"type\":\"long\"},{\"name\":\"client\",\"type\":\"string\"},{\"name\":\"count\",\"type\":\"long\"}]}");
+
+ /** Enum containing all data bean's fields. */
+ public static enum Field {
+ PREV(0, "prev"),
+ CLIENT(1, "client"),
+ COUNT(2, "count"),
+ ;
+ /**
+ * Field's index.
+ */
+ private int index;
+
+ /**
+ * Field's name.
+ */
+ private String name;
+
+ /**
+ * Field's constructor
+ * @param index field's index.
+ * @param name field's name.
+ */
+ Field(int index, String name) {this.index=index;this.name=name;}
+
+ /**
+ * Gets field's index.
+ * @return int field's index.
+ */
+ public int getIndex() {return index;}
+
+ /**
+ * Gets field's name.
+ * @return String field's name.
+ */
+ public String getName() {return name;}
+
+ /**
+ * Gets field's attributes to string.
+ * @return String field's attributes to string.
+ */
+ public String toString() {return name;}
+ };
+
+ public static final String[] _ALL_FIELDS = {
+ "prev",
+ "client",
+ "count",
+ };
+
+ /**
+ * Gets the total field count.
+ * @return int field count
+ */
+ public int getFieldsCount() {
+ return CINode._ALL_FIELDS.length;
+ }
+
+ private long prev;
+ private java.lang.CharSequence client;
+ private long count;
+ public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+ // Used by DatumWriter. Applications should not call.
+ public java.lang.Object get(int field$) {
+ switch (field$) {
+ case 0: return prev;
+ case 1: return client;
+ case 2: return count;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ // Used by DatumReader. Applications should not call.
+ @SuppressWarnings(value="unchecked")
+ public void put(int field$, java.lang.Object value) {
+ switch (field$) {
+ case 0: prev = (java.lang.Long)(value); break;
+ case 1: client = (java.lang.CharSequence)(value); break;
+ case 2: count = (java.lang.Long)(value); break;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ /**
+ * Gets the value of the 'prev' field.
+ */
+ public java.lang.Long getPrev() {
+ return prev;
+ }
+
+ /**
+ * Sets the value of the 'prev' field.
+ * @param value the value to set.
+ */
+ public void setPrev(java.lang.Long value) {
+ this.prev = value;
+ setDirty(0);
+ }
+
+ /**
+ * Checks the dirty status of the 'prev' field. A field is dirty if it represents a change that has not yet been written to the database.
+ * @param value the value to set.
+ */
+ public boolean isPrevDirty(java.lang.Long value) {
+ return isDirty(0);
+ }
+
+ /**
+ * Gets the value of the 'client' field.
+ */
+ public java.lang.CharSequence getClient() {
+ return client;
+ }
+
+ /**
+ * Sets the value of the 'client' field.
+ * @param value the value to set.
+ */
+ public void setClient(java.lang.CharSequence value) {
+ this.client = value;
+ setDirty(1);
+ }
+
+ /**
+ * Checks the dirty status of the 'client' field. A field is dirty if it represents a change that has not yet been written to the database.
+ * @param value the value to set.
+ */
+ public boolean isClientDirty(java.lang.CharSequence value) {
+ return isDirty(1);
+ }
+
+ /**
+ * Gets the value of the 'count' field.
+ */
+ public java.lang.Long getCount() {
+ return count;
+ }
+
+ /**
+ * Sets the value of the 'count' field.
+ * @param value the value to set.
+ */
+ public void setCount(java.lang.Long value) {
+ this.count = value;
+ setDirty(2);
+ }
+
+ /**
+ * Checks the dirty status of the 'count' field. A field is dirty if it represents a change that has not yet been written to the database.
+ * @param value the value to set.
+ */
+ public boolean isCountDirty(java.lang.Long value) {
+ return isDirty(2);
+ }
+
+ /** Creates a new CINode RecordBuilder */
+ public static org.apache.gora.goraci.generated.CINode.Builder newBuilder() {
+ return new org.apache.gora.goraci.generated.CINode.Builder();
+ }
+
+ /** Creates a new CINode RecordBuilder by copying an existing Builder */
+ public static org.apache.gora.goraci.generated.CINode.Builder newBuilder(org.apache.gora.goraci.generated.CINode.Builder other) {
+ return new org.apache.gora.goraci.generated.CINode.Builder(other);
+ }
+
+ /** Creates a new CINode RecordBuilder by copying an existing CINode instance */
+ public static org.apache.gora.goraci.generated.CINode.Builder newBuilder(org.apache.gora.goraci.generated.CINode other) {
+ return new org.apache.gora.goraci.generated.CINode.Builder(other);
+ }
+
+ private static java.nio.ByteBuffer deepCopyToReadOnlyBuffer(
+ java.nio.ByteBuffer input) {
+ java.nio.ByteBuffer copy = java.nio.ByteBuffer.allocate(input.capacity());
+ int position = input.position();
+ input.reset();
+ int mark = input.position();
+ int limit = input.limit();
+ input.rewind();
+ input.limit(input.capacity());
+ copy.put(input);
+ input.rewind();
+ copy.rewind();
+ input.position(mark);
+ input.mark();
+ copy.position(mark);
+ copy.mark();
+ input.position(position);
+ copy.position(position);
+ input.limit(limit);
+ copy.limit(limit);
+ return copy.asReadOnlyBuffer();
+ }
+
+ /**
+ * RecordBuilder for CINode instances.
+ */
+ public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<CINode>
+ implements org.apache.avro.data.RecordBuilder<CINode> {
+
+ private long prev;
+ private java.lang.CharSequence client;
+ private long count;
+
+ /** Creates a new Builder */
+ private Builder() {
+ super(org.apache.gora.goraci.generated.CINode.SCHEMA$);
+ }
+
+ /** Creates a Builder by copying an existing Builder */
+ private Builder(org.apache.gora.goraci.generated.CINode.Builder other) {
+ super(other);
+ }
+
+ /** Creates a Builder by copying an existing CINode instance */
+ private Builder(org.apache.gora.goraci.generated.CINode other) {
+ super(org.apache.gora.goraci.generated.CINode.SCHEMA$);
+ if (isValidValue(fields()[0], other.prev)) {
+ this.prev = (java.lang.Long) data().deepCopy(fields()[0].schema(), other.prev);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.client)) {
+ this.client = (java.lang.CharSequence) data().deepCopy(fields()[1].schema(), other.client);
+ fieldSetFlags()[1] = true;
+ }
+ if (isValidValue(fields()[2], other.count)) {
+ this.count = (java.lang.Long) data().deepCopy(fields()[2].schema(), other.count);
+ fieldSetFlags()[2] = true;
+ }
+ }
+
+ /** Gets the value of the 'prev' field */
+ public java.lang.Long getPrev() {
+ return prev;
+ }
+
+ /** Sets the value of the 'prev' field */
+ public org.apache.gora.goraci.generated.CINode.Builder setPrev(long value) {
+ validate(fields()[0], value);
+ this.prev = value;
+ fieldSetFlags()[0] = true;
+ return this;
+ }
+
+ /** Checks whether the 'prev' field has been set */
+ public boolean hasPrev() {
+ return fieldSetFlags()[0];
+ }
+
+ /** Clears the value of the 'prev' field */
+ public org.apache.gora.goraci.generated.CINode.Builder clearPrev() {
+ fieldSetFlags()[0] = false;
+ return this;
+ }
+
+ /** Gets the value of the 'client' field */
+ public java.lang.CharSequence getClient() {
+ return client;
+ }
+
+ /** Sets the value of the 'client' field */
+ public org.apache.gora.goraci.generated.CINode.Builder setClient(java.lang.CharSequence value) {
+ validate(fields()[1], value);
+ this.client = value;
+ fieldSetFlags()[1] = true;
+ return this;
+ }
+
+ /** Checks whether the 'client' field has been set */
+ public boolean hasClient() {
+ return fieldSetFlags()[1];
+ }
+
+ /** Clears the value of the 'client' field */
+ public org.apache.gora.goraci.generated.CINode.Builder clearClient() {
+ client = null;
+ fieldSetFlags()[1] = false;
+ return this;
+ }
+
+ /** Gets the value of the 'count' field */
+ public java.lang.Long getCount() {
+ return count;
+ }
+
+ /** Sets the value of the 'count' field */
+ public org.apache.gora.goraci.generated.CINode.Builder setCount(long value) {
+ validate(fields()[2], value);
+ this.count = value;
+ fieldSetFlags()[2] = true;
+ return this;
+ }
+
+ /** Checks whether the 'count' field has been set */
+ public boolean hasCount() {
+ return fieldSetFlags()[2];
+ }
+
+ /** Clears the value of the 'count' field */
+ public org.apache.gora.goraci.generated.CINode.Builder clearCount() {
+ fieldSetFlags()[2] = false;
+ return this;
+ }
+
+ @Override
+ public CINode build() {
+ try {
+ CINode record = new CINode();
+ record.prev = fieldSetFlags()[0] ? this.prev : (java.lang.Long) defaultValue(fields()[0]);
+ record.client = fieldSetFlags()[1] ? this.client : (java.lang.CharSequence) defaultValue(fields()[1]);
+ record.count = fieldSetFlags()[2] ? this.count : (java.lang.Long) defaultValue(fields()[2]);
+ return record;
+ } catch (Exception e) {
+ throw new org.apache.avro.AvroRuntimeException(e);
+ }
+ }
+ }
+
+ public CINode.Tombstone getTombstone(){
+ return TOMBSTONE;
+ }
+
+ public CINode newInstance(){
+ return newBuilder().build();
+ }
+
+ private static final Tombstone TOMBSTONE = new Tombstone();
+
+ public static final class Tombstone extends CINode implements org.apache.gora.persistency.Tombstone {
+
+ private Tombstone() { }
+
+ /**
+ * Gets the value of the 'prev' field.
+ */
+ public java.lang.Long getPrev() {
+ throw new java.lang.UnsupportedOperationException("Get is not supported on tombstones");
+ }
+
+ /**
+ * Sets the value of the 'prev' field.
+ * @param value the value to set.
+ */
+ public void setPrev(java.lang.Long value) {
+ throw new java.lang.UnsupportedOperationException("Set is not supported on tombstones");
+ }
+
+ /**
+ * Checks the dirty status of the 'prev' field. A field is dirty if it represents a change that has not yet been written to the database.
+ * @param value the value to set.
+ */
+ public boolean isPrevDirty(java.lang.Long value) {
+ throw new java.lang.UnsupportedOperationException("IsDirty is not supported on tombstones");
+ }
+
+ /**
+ * Gets the value of the 'client' field.
+ */
+ public java.lang.CharSequence getClient() {
+ throw new java.lang.UnsupportedOperationException("Get is not supported on tombstones");
+ }
+
+ /**
+ * Sets the value of the 'client' field.
+ * @param value the value to set.
+ */
+ public void setClient(java.lang.CharSequence value) {
+ throw new java.lang.UnsupportedOperationException("Set is not supported on tombstones");
+ }
+
+ /**
+ * Checks the dirty status of the 'client' field. A field is dirty if it represents a change that has not yet been written to the database.
+ * @param value the value to set.
+ */
+ public boolean isClientDirty(java.lang.CharSequence value) {
+ throw new java.lang.UnsupportedOperationException("IsDirty is not supported on tombstones");
+ }
+
+ /**
+ * Gets the value of the 'count' field.
+ */
+ public java.lang.Long getCount() {
+ throw new java.lang.UnsupportedOperationException("Get is not supported on tombstones");
+ }
+
+ /**
+ * Sets the value of the 'count' field.
+ * @param value the value to set.
+ */
+ public void setCount(java.lang.Long value) {
+ throw new java.lang.UnsupportedOperationException("Set is not supported on tombstones");
+ }
+
+ /**
+ * Checks the dirty status of the 'count' field. A field is dirty if it represents a change that has not yet been written to the database.
+ * @param value the value to set.
+ */
+ public boolean isCountDirty(java.lang.Long value) {
+ throw new java.lang.UnsupportedOperationException("IsDirty is not supported on tombstones");
+ }
+
+
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/java/org/apache/gora/goraci/generated/Flushed.java
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/java/org/apache/gora/goraci/generated/Flushed.java b/gora-goraci/src/main/java/org/apache/gora/goraci/generated/Flushed.java
new file mode 100644
index 0000000..c6a2107
--- /dev/null
+++ b/gora-goraci/src/main/java/org/apache/gora/goraci/generated/Flushed.java
@@ -0,0 +1,259 @@
+/**
+ * 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.gora.goraci.generated;
+@SuppressWarnings("all")
+public class Flushed extends org.apache.gora.persistency.impl.PersistentBase implements org.apache.avro.specific.SpecificRecord, org.apache.gora.persistency.Persistent {
+ public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"Flushed\",\"namespace\":\"org.apache.gora.goraci.generated\",\"fields\":[{\"name\":\"count\",\"type\":\"long\"}]}");
+
+ /** Enum containing all data bean's fields. */
+ public static enum Field {
+ COUNT(0, "count"),
+ ;
+ /**
+ * Field's index.
+ */
+ private int index;
+
+ /**
+ * Field's name.
+ */
+ private String name;
+
+ /**
+ * Field's constructor
+ * @param index field's index.
+ * @param name field's name.
+ */
+ Field(int index, String name) {this.index=index;this.name=name;}
+
+ /**
+ * Gets field's index.
+ * @return int field's index.
+ */
+ public int getIndex() {return index;}
+
+ /**
+ * Gets field's name.
+ * @return String field's name.
+ */
+ public String getName() {return name;}
+
+ /**
+ * Gets field's attributes to string.
+ * @return String field's attributes to string.
+ */
+ public String toString() {return name;}
+ };
+
+ public static final String[] _ALL_FIELDS = {
+ "count",
+ };
+
+ /**
+ * Gets the total field count.
+ * @return int field count
+ */
+ public int getFieldsCount() {
+ return Flushed._ALL_FIELDS.length;
+ }
+
+ private long count;
+ public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+ // Used by DatumWriter. Applications should not call.
+ public java.lang.Object get(int field$) {
+ switch (field$) {
+ case 0: return count;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ // Used by DatumReader. Applications should not call.
+ @SuppressWarnings(value="unchecked")
+ public void put(int field$, java.lang.Object value) {
+ switch (field$) {
+ case 0: count = (java.lang.Long)(value); break;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ /**
+ * Gets the value of the 'count' field.
+ */
+ public java.lang.Long getCount() {
+ return count;
+ }
+
+ /**
+ * Sets the value of the 'count' field.
+ * @param value the value to set.
+ */
+ public void setCount(java.lang.Long value) {
+ this.count = value;
+ setDirty(0);
+ }
+
+ /**
+ * Checks the dirty status of the 'count' field. A field is dirty if it represents a change that has not yet been written to the database.
+ * @param value the value to set.
+ */
+ public boolean isCountDirty(java.lang.Long value) {
+ return isDirty(0);
+ }
+
+ /** Creates a new Flushed RecordBuilder */
+ public static org.apache.gora.goraci.generated.Flushed.Builder newBuilder() {
+ return new org.apache.gora.goraci.generated.Flushed.Builder();
+ }
+
+ /** Creates a new Flushed RecordBuilder by copying an existing Builder */
+ public static org.apache.gora.goraci.generated.Flushed.Builder newBuilder(org.apache.gora.goraci.generated.Flushed.Builder other) {
+ return new org.apache.gora.goraci.generated.Flushed.Builder(other);
+ }
+
+ /** Creates a new Flushed RecordBuilder by copying an existing Flushed instance */
+ public static org.apache.gora.goraci.generated.Flushed.Builder newBuilder(org.apache.gora.goraci.generated.Flushed other) {
+ return new org.apache.gora.goraci.generated.Flushed.Builder(other);
+ }
+
+ private static java.nio.ByteBuffer deepCopyToReadOnlyBuffer(
+ java.nio.ByteBuffer input) {
+ java.nio.ByteBuffer copy = java.nio.ByteBuffer.allocate(input.capacity());
+ int position = input.position();
+ input.reset();
+ int mark = input.position();
+ int limit = input.limit();
+ input.rewind();
+ input.limit(input.capacity());
+ copy.put(input);
+ input.rewind();
+ copy.rewind();
+ input.position(mark);
+ input.mark();
+ copy.position(mark);
+ copy.mark();
+ input.position(position);
+ copy.position(position);
+ input.limit(limit);
+ copy.limit(limit);
+ return copy.asReadOnlyBuffer();
+ }
+
+ /**
+ * RecordBuilder for Flushed instances.
+ */
+ public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<Flushed>
+ implements org.apache.avro.data.RecordBuilder<Flushed> {
+
+ private long count;
+
+ /** Creates a new Builder */
+ private Builder() {
+ super(org.apache.gora.goraci.generated.Flushed.SCHEMA$);
+ }
+
+ /** Creates a Builder by copying an existing Builder */
+ private Builder(org.apache.gora.goraci.generated.Flushed.Builder other) {
+ super(other);
+ }
+
+ /** Creates a Builder by copying an existing Flushed instance */
+ private Builder(org.apache.gora.goraci.generated.Flushed other) {
+ super(org.apache.gora.goraci.generated.Flushed.SCHEMA$);
+ if (isValidValue(fields()[0], other.count)) {
+ this.count = (java.lang.Long) data().deepCopy(fields()[0].schema(), other.count);
+ fieldSetFlags()[0] = true;
+ }
+ }
+
+ /** Gets the value of the 'count' field */
+ public java.lang.Long getCount() {
+ return count;
+ }
+
+ /** Sets the value of the 'count' field */
+ public org.apache.gora.goraci.generated.Flushed.Builder setCount(long value) {
+ validate(fields()[0], value);
+ this.count = value;
+ fieldSetFlags()[0] = true;
+ return this;
+ }
+
+ /** Checks whether the 'count' field has been set */
+ public boolean hasCount() {
+ return fieldSetFlags()[0];
+ }
+
+ /** Clears the value of the 'count' field */
+ public org.apache.gora.goraci.generated.Flushed.Builder clearCount() {
+ fieldSetFlags()[0] = false;
+ return this;
+ }
+
+ @Override
+ public Flushed build() {
+ try {
+ Flushed record = new Flushed();
+ record.count = fieldSetFlags()[0] ? this.count : (java.lang.Long) defaultValue(fields()[0]);
+ return record;
+ } catch (Exception e) {
+ throw new org.apache.avro.AvroRuntimeException(e);
+ }
+ }
+ }
+
+ public Flushed.Tombstone getTombstone(){
+ return TOMBSTONE;
+ }
+
+ public Flushed newInstance(){
+ return newBuilder().build();
+ }
+
+ private static final Tombstone TOMBSTONE = new Tombstone();
+
+ public static final class Tombstone extends Flushed implements org.apache.gora.persistency.Tombstone {
+
+ private Tombstone() { }
+
+ /**
+ * Gets the value of the 'count' field.
+ */
+ public java.lang.Long getCount() {
+ throw new java.lang.UnsupportedOperationException("Get is not supported on tombstones");
+ }
+
+ /**
+ * Sets the value of the 'count' field.
+ * @param value the value to set.
+ */
+ public void setCount(java.lang.Long value) {
+ throw new java.lang.UnsupportedOperationException("Set is not supported on tombstones");
+ }
+
+ /**
+ * Checks the dirty status of the 'count' field. A field is dirty if it represents a change that has not yet been written to the database.
+ * @param value the value to set.
+ */
+ public boolean isCountDirty(java.lang.Long value) {
+ throw new java.lang.UnsupportedOperationException("IsDirty is not supported on tombstones");
+ }
+
+
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/resources/gora-accumulo-mapping.xml
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/resources/gora-accumulo-mapping.xml b/gora-goraci/src/main/resources/gora-accumulo-mapping.xml
new file mode 100644
index 0000000..fff2f22
--- /dev/null
+++ b/gora-goraci/src/main/resources/gora-accumulo-mapping.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<gora-orm>
+ <class name="org.apache.gora.goraci.generated.CINode" keyClass="java.lang.Long" table="ci">
+ <field name="prev" family="meta" qualifier="prev"/>
+ <field name="client" family="meta" qualifier="client"/>
+ <field name="count" family="meta" qualifier="count" />
+ </class>
+ <class name="org.apache.gora.goraci.generated.Flushed" keyClass="org.apache.avro.util.Utf8" table="ciFlushed">
+ <field name="count" family="gi" qualifier="count" />
+ </class>
+
+</gora-orm>
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/resources/gora-cassandra-mapping.xml
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/resources/gora-cassandra-mapping.xml b/gora-goraci/src/main/resources/gora-cassandra-mapping.xml
new file mode 100644
index 0000000..27d89dc
--- /dev/null
+++ b/gora-goraci/src/main/resources/gora-cassandra-mapping.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gora-orm>
+ <keyspace name="CINode" host="localhost" cluster="GoraCI Test Cluster">
+ <family name="p"/>
+ <family name="f"/>
+ <family name="sc" type="super" />
+ </keyspace>
+
+ <keyspace name="Flushed" host="localhost" cluster="GoraCI Test Cluster">
+ <family name="p"/>
+ <family name="f"/>
+ <family name="sc" type="super"/>
+ </keyspace>
+
+ <class name="org.apache.gora.goraci.generated.CINode" keyClass="java.lang.Long" keyspace="CINode">
+ <field name="prev" family="p" qualifier="prev"/>
+ <field name="client" family="p" qualifier="client"/>
+ <field name="count" family="p" qualifier="count"/>
+ </class>
+ <class name="org.apache.gora.goraci.generated.Flushed" keyClass="org.apache.avro.util.Utf8" keyspace="Flushed">
+ <field name="count" family="f" qualifier="count" />
+ </class>
+</gora-orm>
+<!-- Incorrect Mapping -->
+
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/resources/gora-hbase-mapping.xml
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/resources/gora-hbase-mapping.xml b/gora-goraci/src/main/resources/gora-hbase-mapping.xml
new file mode 100644
index 0000000..1a7fd62
--- /dev/null
+++ b/gora-goraci/src/main/resources/gora-hbase-mapping.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<gora-orm>
+ <class name="org.apache.gora.goraci.generated.CINode" keyClass="java.lang.Long" table="ci">
+ <field name="prev" family="meta" qualifier="prev"/>
+ <field name="client" family="meta" qualifier="client"/>
+ <field name="count" family="meta" qualifier="count"/>
+ </class>
+ <class name="org.apache.gora.goraci.generated.Flushed" keyClass="org.apache.avro.util.Utf8" table="ciFlushed">
+ <field name="count" family="gi" qualifier="count" />
+ </class>
+</gora-orm>
+
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/resources/gora-sql-mapping.xml
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/resources/gora-sql-mapping.xml b/gora-goraci/src/main/resources/gora-sql-mapping.xml
new file mode 100644
index 0000000..fe6c8b5
--- /dev/null
+++ b/gora-goraci/src/main/resources/gora-sql-mapping.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<gora-orm>
+ <class name="org.apache.gora.goraci.generated.CINode" keyClass="java.lang.Long" table="ci">
+ <primarykey column="" length=""/>
+ <field name="prev" column="" length=""/>
+ <field name="client" column=""/>
+ <field name="count" column="" jdbc-type="VARCHAR_IGNORECASE" length=""/> <!-- jdbc-type is HSQLDB specific for testing -->
+ </class>
+ <class name="org.apache.gora.goraci.generated.Flushed" keyClass="org.apache.avro.util.Utf8" table="ciFlushed">
+ <primarykey column="" length=""/>
+ <field name="count" column="" jdbc-type="VARCHAR_IGNORECASE" length=""/> <!-- jdbc-type is HSQLDB specific for testing -->
+ </class>
+</gora-orm>
+<!-- N.B. incorrect mapping -->
+
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/resources/gora.properties
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/resources/gora.properties b/gora-goraci/src/main/resources/gora.properties
new file mode 100644
index 0000000..7b4733b
--- /dev/null
+++ b/gora-goraci/src/main/resources/gora.properties
@@ -0,0 +1,76 @@
+# 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.
+
+###############################
+# Default Accumulo properties #
+###############################
+gora.datastore.default=org.apache.gora.goraci.accumulo.store.AccumuloStore
+gora.datastore.accumulo.instance=test14
+gora.datastore.accumulo.zookeepers=localhost
+gora.datastore.accumulo.user=root
+gora.datastore.accumulo.password=secret
+
+###############################
+# Default SqlStore properties #
+###############################
+
+#gora.sqlstore.jdbc.driver=org.hsqldb.jdbcDriver
+#gora.sqlstore.jdbc.url=jdbc:hsqldb:hsql://localhost/nutchtest
+# gora.sqlstore.jdbc.user=
+# gora.sqlstore.jdbc.password=
+
+################################
+# Default AvroStore properties #
+################################
+
+# gora.avrostore.codec.type=BINARY||JSON
+# gora.avrostore.output.path=file:///tmp/gora.avrostore.test.output
+
+################################
+# DatafileAvroStore properties #
+################################
+# DataFileAvroStore is file based store which uses Avro's
+# DataFile{Writer,Reader}'s as a backend. This datastore supports
+# mapreduce.
+
+# gora.datafileavrostore.###=
+
+#########################
+# HBaseStore properties #
+#########################
+# HBaseStore currently reads no Gora properties. However the HBase client
+# requires that the Configuration contains a valid "hbase.zookeeper.quorum"
+# property. It should be included within hbase-site.xml on the classpath. When
+# this property is omitted, it expects Zookeeper to run on localhost:2181.
+#gora.datastore.default=org.apache.gora.goraci.hbase.store.HBaseStore
+
+#############################
+# CassandraStore properties #
+#############################
+
+#gora.cassandrastore.servers=localhost:9160
+
+#######################
+# MemStore properties #
+#######################
+# This is a memory based {@link DataStore} implementation for tests.
+
+# gora.memstore.###=
+
+#######################
+# Misc properties #
+#######################
+#gora.datastore.default=org.apache.gora.goraci.mock.store.MockDataStore
+#gora.datastore.autocreateschema=true
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ce1c8fc..bea5b68 100644
--- a/pom.xml
+++ b/pom.xml
@@ -573,6 +573,7 @@
<module>gora-core</module>
<module>gora-accumulo</module>
<module>gora-cassandra</module>
+ <module>gora-goraci</module>
<module>gora-hbase</module>
<!-- module>gora-lucene</module -->
<!--module>gora-dynamodb</module -->
[2/4] git commit: GORA 73 Merge goraci testing suite with master
branch
Posted by le...@apache.org.
GORA 73 Merge goraci testing suite with master branch
Project: http://git-wip-us.apache.org/repos/asf/gora/repo
Commit: http://git-wip-us.apache.org/repos/asf/gora/commit/a60a3370
Tree: http://git-wip-us.apache.org/repos/asf/gora/tree/a60a3370
Diff: http://git-wip-us.apache.org/repos/asf/gora/diff/a60a3370
Branch: refs/heads/master
Commit: a60a33703ffa774a32f11bceb8f3bc2474874681
Parents: b167b3a
Author: Lewis John McGibbney <le...@jpl.nasa.gov>
Authored: Sun Aug 31 17:45:40 2014 -0700
Committer: Lewis John McGibbney <le...@jpl.nasa.gov>
Committed: Sun Aug 31 17:45:40 2014 -0700
----------------------------------------------------------------------
.../gora/examples/generated/Employee.java | 17 +-
.../examples/generated/ImmutableFields.java | 17 +-
.../gora/examples/generated/Metadata.java | 17 +-
.../gora/examples/generated/TokenDatum.java | 17 +-
.../org/apache/gora/examples/generated/V2.java | 17 +-
.../apache/gora/examples/generated/WebPage.java | 17 +-
gora-goraci/.gitignore | 34 ++
gora-goraci/README | 256 +++++++++++
gora-goraci/goraci.sh | 104 +++++
gora-goraci/pom.xml | 275 ++++++++++++
gora-goraci/src/main/avro/cinode.json | 10 +
gora-goraci/src/main/avro/flushed.json | 8 +
.../java/org/apache/gora/goraci/Delete.java | 57 +++
.../java/org/apache/gora/goraci/Generator.java | 351 +++++++++++++++
.../main/java/org/apache/gora/goraci/Loop.java | 164 +++++++
.../main/java/org/apache/gora/goraci/Print.java | 95 +++++
.../java/org/apache/gora/goraci/Verify.java | 294 +++++++++++++
.../java/org/apache/gora/goraci/Walker.java | 129 ++++++
.../apache/gora/goraci/generated/CINode.java | 424 +++++++++++++++++++
.../apache/gora/goraci/generated/Flushed.java | 259 +++++++++++
.../main/resources/gora-accumulo-mapping.xml | 22 +
.../main/resources/gora-cassandra-mapping.xml | 25 ++
.../src/main/resources/gora-hbase-mapping.xml | 22 +
.../src/main/resources/gora-sql-mapping.xml | 25 ++
gora-goraci/src/main/resources/gora.properties | 76 ++++
pom.xml | 1 +
26 files changed, 2715 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-core/src/examples/java/org/apache/gora/examples/generated/Employee.java
----------------------------------------------------------------------
diff --git a/gora-core/src/examples/java/org/apache/gora/examples/generated/Employee.java b/gora-core/src/examples/java/org/apache/gora/examples/generated/Employee.java
index fb76b30..dd6f3a9 100644
--- a/gora-core/src/examples/java/org/apache/gora/examples/generated/Employee.java
+++ b/gora-core/src/examples/java/org/apache/gora/examples/generated/Employee.java
@@ -1,7 +1,18 @@
/**
- * Autogenerated by Avro
- *
- * DO NOT EDIT DIRECTLY
+ * 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.gora.examples.generated;
@SuppressWarnings("all")
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-core/src/examples/java/org/apache/gora/examples/generated/ImmutableFields.java
----------------------------------------------------------------------
diff --git a/gora-core/src/examples/java/org/apache/gora/examples/generated/ImmutableFields.java b/gora-core/src/examples/java/org/apache/gora/examples/generated/ImmutableFields.java
index 85294bf..10f48dc 100644
--- a/gora-core/src/examples/java/org/apache/gora/examples/generated/ImmutableFields.java
+++ b/gora-core/src/examples/java/org/apache/gora/examples/generated/ImmutableFields.java
@@ -1,7 +1,18 @@
/**
- * Autogenerated by Avro
- *
- * DO NOT EDIT DIRECTLY
+ * 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.gora.examples.generated;
@SuppressWarnings("all")
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-core/src/examples/java/org/apache/gora/examples/generated/Metadata.java
----------------------------------------------------------------------
diff --git a/gora-core/src/examples/java/org/apache/gora/examples/generated/Metadata.java b/gora-core/src/examples/java/org/apache/gora/examples/generated/Metadata.java
index 3eb7b32..de6882b 100644
--- a/gora-core/src/examples/java/org/apache/gora/examples/generated/Metadata.java
+++ b/gora-core/src/examples/java/org/apache/gora/examples/generated/Metadata.java
@@ -1,7 +1,18 @@
/**
- * Autogenerated by Avro
- *
- * DO NOT EDIT DIRECTLY
+ * 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.gora.examples.generated;
@SuppressWarnings("all")
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-core/src/examples/java/org/apache/gora/examples/generated/TokenDatum.java
----------------------------------------------------------------------
diff --git a/gora-core/src/examples/java/org/apache/gora/examples/generated/TokenDatum.java b/gora-core/src/examples/java/org/apache/gora/examples/generated/TokenDatum.java
index e38d640..f0ad9b8 100644
--- a/gora-core/src/examples/java/org/apache/gora/examples/generated/TokenDatum.java
+++ b/gora-core/src/examples/java/org/apache/gora/examples/generated/TokenDatum.java
@@ -1,7 +1,18 @@
/**
- * Autogenerated by Avro
- *
- * DO NOT EDIT DIRECTLY
+ * 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.gora.examples.generated;
@SuppressWarnings("all")
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-core/src/examples/java/org/apache/gora/examples/generated/V2.java
----------------------------------------------------------------------
diff --git a/gora-core/src/examples/java/org/apache/gora/examples/generated/V2.java b/gora-core/src/examples/java/org/apache/gora/examples/generated/V2.java
index 1db2a0b..1dbb314 100644
--- a/gora-core/src/examples/java/org/apache/gora/examples/generated/V2.java
+++ b/gora-core/src/examples/java/org/apache/gora/examples/generated/V2.java
@@ -1,7 +1,18 @@
/**
- * Autogenerated by Avro
- *
- * DO NOT EDIT DIRECTLY
+ * 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.gora.examples.generated;
@SuppressWarnings("all")
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-core/src/examples/java/org/apache/gora/examples/generated/WebPage.java
----------------------------------------------------------------------
diff --git a/gora-core/src/examples/java/org/apache/gora/examples/generated/WebPage.java b/gora-core/src/examples/java/org/apache/gora/examples/generated/WebPage.java
index 604b560..6f9b688 100644
--- a/gora-core/src/examples/java/org/apache/gora/examples/generated/WebPage.java
+++ b/gora-core/src/examples/java/org/apache/gora/examples/generated/WebPage.java
@@ -1,7 +1,18 @@
/**
- * Autogenerated by Avro
- *
- * DO NOT EDIT DIRECTLY
+ * 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.gora.examples.generated;
@SuppressWarnings("all")
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/.gitignore
----------------------------------------------------------------------
diff --git a/gora-goraci/.gitignore b/gora-goraci/.gitignore
new file mode 100644
index 0000000..972a8df
--- /dev/null
+++ b/gora-goraci/.gitignore
@@ -0,0 +1,34 @@
+# 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.
+
+*~
+.idea
+*.iml
+*.iws
+*.ipr
+.classpath
+.externalToolBuilders
+.project
+.settings
+.git
+.svn
+build
+target
+dist
+lib
+**/lib/*.jar
+ivy/ivy*.jar
+/conf/*-site.xml
+**/conf/*-site.xml
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/README
----------------------------------------------------------------------
diff --git a/gora-goraci/README b/gora-goraci/README
new file mode 100644
index 0000000..54c60ed
--- /dev/null
+++ b/gora-goraci/README
@@ -0,0 +1,256 @@
+=================================
+= =
+= GORACI README =
+= @author Keith Turner =
+=================================
+
+BACKGROUND
+------------
+
+Apache Accumulo [0] has a simple test suite that verifies that data is not lost
+at scale. This test suite is called continuous ingest [5]. This test runs
+many ingest clients that continually create linked lists containing 25 million
+nodes. At some point the clients are stopped and a map reduce job is run to
+ensure no linked list has a hole. A hole indicates data was lost.
+
+The nodes in the linked list are random. This causes each linked list to
+spread across the table. Therefore if one part of a table loses data, then it
+will be detected by references in another part of the table.
+
+This project is a version of the test suite written using Apache Gora [1].
+Goraci has been tested against Accumulo and HBase.
+
+THE ANATOMY OF GORACI TESTS
+----------------------------
+
+Below is rough sketch of how data is written. For specific details look at the
+Generator code (src/main/java/org.apache.gora.goraci/Generator.java)
+
+ 1 Write out 1 million nodes
+ 2 Flush the client
+ 3 Write out 1 million that reference previous million
+ 4 If this is the 25th set of 1 million nodes, then update 1st set of million
+ to point to last
+ 5 goto 1
+
+The key is that nodes only reference flushed nodes. Therefore a node should
+never reference a missing node, even if the ingest client is killed at any
+point in time.
+
+When running this test suite w/ Accumulo there is a script running in parallel
+called the Aggitator that randomly and continuously kills server processes.
+The outcome was that many data loss bugs were found in Accumulo by doing this.
+This test suite can also help find bugs that impact uptime and stability when
+run for days or weeks.
+
+This test suite consists the following
+- a few Java programs
+- a little helper script to run the java programs
+- a maven script to build it.
+
+When generating data, its best to have each map task generate a multiple of 25
+million. The reason for this is that circular linked list are generated every
+25M. Not generating a multiple in 25M will result in some nodes in the linked
+list not having references. The loss of an unreferenced node can not be
+detected.
+
+BUILDING GORACI
+---------------
+
+This code currently depends on an unreleased version of Gora. To build Gora
+0.2 run the following commands.
+
+ svn export http://svn.apache.org/repos/asf/gora/trunk gora
+ cd gora
+ mvn install -DskipTests
+
+After this you can build org.apache.gora.goraci.
+
+ git clone git://github.com/keith-turner/org.apache.gora.goraci.git
+ cd org.apache.gora.goraci
+ mvn compile
+
+The maven pom file has some profiles that attempt to make it easier to run
+org.apache.gora.goraci against different gora backends by copying the jars you need into lib.
+Before packaging its important to edit gora.properties and set it correctly
+for your datastore. To run against accumulo do the following.
+
+ vim src/main/resources/gora.properties (set Accumulo properties)
+ mvn package -Paccumulo-1.4
+
+To run against hbase, do the following.
+
+ vim src/main/resources/gora.properties (set HBase properties)
+ mvn package -Phbase-0.92
+
+To run against cassandra, do the following.
+
+ vim src/main/resources/gora.properties (set Cassandra properties)
+ mvn package -Pcassandra-1.1.2
+
+For other datastores mentioned in gora.properties, you will need to copy the
+appropriate deps into lib. Feel free to update the pom with other profiles and
+send me pull request.
+
+JAVA CLASS DESCRIPTION
+-----------------
+
+Below is a description of the Java programs
+
+ * org.apache.gora.goraci.Generator - A map only job that generates data. As stated previously,
+ its best to generate data in multiples of 25M.
+ * org.apache.gora.goraci.Verify - A map reduce job that looks for holes. Look at the
+ counts after running. REFERENCED and UNREFERENCED are
+ ok, any UNDEFINED counts are bad. Do not run at the
+ same time as the Generator.
+ * org.apache.gora.goraci.Walker - A standalong program that start following a linked list
+ and emits timing info.
+ * org.apache.gora.goraci.Print - A standalone program that prints nodes in the linked list
+ * org.apache.gora.goraci.Delete - A standalone program that deletes a single node
+ * org.apache.gora.goraci.Loop - Runs generation and verify in a loop
+
+org.apache.gora.goraci.sh is a helper script that you can use to run the above programs. It
+assumes all needed jars are in the lib dir. It does not need the package name.
+You can just run "./org.apache.gora.goraci.sh Generator", below is an example.
+
+ $ ./org.apache.gora.goraci.sh Generator
+ Usage : Generator <num mappers> <num nodes>
+
+For Gora to work, it needs a gora.properties file on the classpath and a
+mapping file on the classpath, the contents of both are datastore specific,
+more details can be found here [2]. You can edit the ones in src/main/resources
+and build the org.apache.gora.goraci-${version}-SNAPSHOT.jar with those. Alternatively remove
+those and put them on the classpath through some other means.
+
+GORA AND HADOOP
+-----------------
+
+Gora uses Avro which uses a Json library that Hadoop has an old version of.
+The two libraries jackson-core and jackson-mapper need to be updated in
+<HADOOP_HOME>/lib and <HADOOP_HOME>/share/hadoop/lib/. I updated these to
+jackson-core-asl-1.4.2.jar and jackson-mapper-asl-1.4.2.jar. For details see
+HADOOP-6945 [3].
+
+GORACI AND HBASE
+-----------------
+
+To improve performance running read jobs such as the Verify step, enable
+scanner caching on the command line. For example:
+
+ $ ./gorachi.sh Verify -Dhbase.client.scanner.caching=1000 \
+ -Dmapred.map.tasks.speculative.execution=false verify_dir 1000
+
+Dependent on how you have your hadoop and hbase deployed, you may need to
+change the gorachi.sh script around some. Here is one suggestion that may help
+in the case where your hadoop and hbase configuration are other than under the
+hadoop and hbase home directories.
+
+ diff --git a/org.apache.gora.goraci.sh b/org.apache.gora.goraci.sh
+ index db1562a..31c3c94 100755
+ --- a/org.apache.gora.goraci.sh
+ +++ b/org.apache.gora.goraci.sh
+ @@ -95,6 +95,4 @@ done
+ #run it
+ export HADOOP_CLASSPATH="$CLASSPATH"
+ LIBJARS=`echo $HADOOP_CLASSPATH | tr : ,`
+ -hadoop jar "$GORACI_HOME/lib/org.apache.gora.goraci-0.0.1-SNAPSHOT.jar" $CLASS -libjars "$LIBJARS" "$@"
+ -
+ -
+ +CLASSPATH="${HBASE_CONF_DIR}" hadoop --config "${HADOOP_CONF_DIR} jar "$GORACI_HOME/lib/org.apache.gora.goraci-0.0.1-SNAPSHOT.jar" $CLASS -files "${HBASE_CONF_DIR}/hbase-site.xml" -libjars "$LIBJARS" "$@"
+
+You will need to define HBASE_CONF_DIR and HADOOP_CONF_DIR before you run your
+org.apache.gora.goraci jobs. For example:
+
+ $ export HADOOP_CONF_DIR=/home/you/hadoop-conf
+ $ export HBASE_CONF_DIR=/home/you/hbase-conf
+ $ PATH=/home/you/hadoop-1.0.2/bin:$PATH ./org.apache.gora.goraci.sh Generator 1000 1000000
+
+CONCURRENCY
+------------
+
+Its possible to run verification at the same time as generation. To do this
+supply the -c option to Generator and Verify. This will cause Genertor to
+create a secondary table which holds information about what verification can
+safely verify. Running Verify with the -c option will make it run slower
+because more information must be brought back to the client side for filtering
+purposes. The Loop program also supports the -c option, which will cause it to
+run verification concurrently with generation.
+
+If verification is run at the same time as generation without the -c option,
+then it will inevitably fail. This is because verification mappers read
+different parts of the table at different times and giving an inconsistent view
+of the table. So one mapper may read a part of a table before a node is
+written, when the node is later referenced it will appear to be missing. The
+-c option basically filters out newer information using data written to the
+secondary table.
+
+CONCLUSIONS
+------------
+
+This test suite does not do everything that the Accumulo test suite does,
+mainly it does not collect statistics and generate reports. The reports
+are useful for assesing performance.
+
+Below shows running a test of the test. Ingest one linked list, deleted a node
+in it, ensure the verifaction map reduce job notices that the node is missing.
+Not all output is shown, just the important parts.
+
+ $ ./org.apache.gora.goraci.sh Generator 1 25000000
+ $ ./org.apache.gora.goraci.sh Print -s 2000000000000000 -l 1
+ 2000001f65dbd238:30350f9ae6f6e8f7:000004265852:ef09f9dd-75b1-4c16-9f14-0fa84f3029b6
+ $ ./org.apache.gora.goraci.sh Print -s 30350f9ae6f6e8f7 -l 1
+ 30350f9ae6f6e8f7:4867fe03de6ea6c8:000003265852:ef09f9dd-75b1-4c16-9f14-0fa84f3029b6
+ $ ./org.apache.gora.goraci.sh Delete 30350f9ae6f6e8f7
+ Delete returned true
+ $ ./org.apache.gora.goraci.sh Verify gci_verify_1 2
+ 11/12/20 17:12:31 INFO mapred.JobClient: org.apache.gora.goraci.Verify$Counts
+ 11/12/20 17:12:31 INFO mapred.JobClient: UNDEFINED=1
+ 11/12/20 17:12:31 INFO mapred.JobClient: REFERENCED=24999998
+ 11/12/20 17:12:31 INFO mapred.JobClient: UNREFERENCED=1
+ $ hadoop fs -cat gci_verify_1/part\*
+ 30350f9ae6f6e8f7 2000001f65dbd238
+
+The map reduce job found the one undefined node and gave the node that
+referenced it.
+
+Below are some timing statistics for running org.apache.gora.goraci on a 10 node cluster.
+
+ Store | Task | Time | Undef | Unref | Ref
+ ----------------+------------------------+---------+--------+-------+------------
+ accumulo-1.4.0 | Generator 10 100000000 | 40m 16s | N/A | N/A | N/A
+ accumulo-1.4.0 | Verify /tmp/goraci1 40 | 6m 7s | 0 | 0 | 1000000000
+ hbase-0.92.1 | Generator 10 100000000 | 2h 44m | N/A | N/A | N/A
+ hbase-0.92.1 | Verify /tmp/goraci2 40 | 6m 34s | 0 | 0 | 1000000000
+
+Hbase and Accumulo are configured differently out-of-the-box. We used the Accumulo
+3G, native configuration examples in the conf/examples directory.
+
+To provide a comparable memory footprint, we increased the HBase jvm to "-Xmx4000m",
+and turned on compression for the ci table:
+
+create 'ci', {NAME=>'meta', COMPRESSION=>'GZ'}
+
+We also turned down the replication of write-ahead logs to be comparable to Accumulo:
+
+ <property>
+ <name>hbase.regionserver.hlog.replication</name>
+ <value>2</value>
+ </property>
+
+For the accumulo run, we set the split threshold to 512M:
+
+ shell> config -t ci -s table.split.threshold=512M
+
+This was done so that Accumulo would end up with 64 tablets, which is the
+number of regions hbase had. The number of tablets/regions determines how
+much parallelism there is in the map phase of the verify step.
+
+Sometimes when this test suite is run against HBase data is lost. This issue
+is being tracked under HBASE-5754 [4].
+
+[0] http://accumulo.apache.org
+[1] http://gora.apache.org
+[2] http://gora.apache.org/docs/current/gora-conf.html
+[3] https://issues.apache.org/jira/browse/HADOOP-6945
+[4] https://issues.apache.org/jira/browse/HBASE-5754
+[5] http://svn.apache.org/viewvc/accumulo/tags/1.4.0/test/system/continuous/ScaleTest.odp?view=co
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/goraci.sh
----------------------------------------------------------------------
diff --git a/gora-goraci/goraci.sh b/gora-goraci/goraci.sh
new file mode 100755
index 0000000..085fe3c
--- /dev/null
+++ b/gora-goraci/goraci.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+#
+# The Goraci command script
+#
+# Environment Variables
+#
+# GORACI_JAVA_HOME The java implementation to use. Overrides JAVA_HOME.
+#
+# GORACI_HEAPSIZE The maximum amount of heap to use, in MB.
+# Default is 1000.
+#
+# GORACI_OPTS Extra Java runtime options.
+#
+
+# resolve links - $0 may be a softlink
+THIS="$0"
+while [ -h "$THIS" ]; do
+ ls=`ls -ld "$THIS"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '.*/.*' > /dev/null; then
+ THIS="$link"
+ else
+ THIS=`dirname "$THIS"`/"$link"
+ fi
+done
+
+# if no args specified, show usage
+if [ $# = 0 ]; then
+ echo "Usage: run COMMAND [COMMAND options]"
+ echo "where COMMAND is one of:"
+ echo " Generator A map only job that generates data."
+ echo " Verify A map reduce job that looks for holes.
+ Look at the counts after running.
+ REFERENCED and UNREFERENCED are ok,
+ any UNDEFINED counts are bad. Do not
+ run at the same time as the Generator."
+ echo " Walker A standalong program that starts
+ following a linked list and emits
+ timing info."
+ echo " Print A standalone program that prints nodes
+ in the linked list."
+ echo " Delete A standalone program that deletes a
+ single node."
+ echo " Loop A program to Loop through Generator and
+ Verify steps"
+ echo " or"
+ echo " CLASSNAME run the class named CLASSNAME"
+ echo "Most commands print help when invoked w/o parameters."
+ exit 1
+fi
+
+# get arguments
+COMMAND=$1
+shift
+
+# some directories
+THIS_DIR=`dirname "$THIS"`
+GORACI_HOME=`cd "$THIS_DIR" ; pwd`
+
+# cath when JAVA_HOME is not set
+if [ "$JAVA_HOME" = "" ]; then
+ echo "Error: JAVA_HOME is not set."
+ exit 1
+fi
+# so that filenames w/ spaces are handled correctly in loops below
+IFS=
+
+# restore ordinary behaviour
+unset IFS
+
+# figure out which class to run
+if [ "$COMMAND" = "Generator" ] ; then
+ CLASS=org.apache.gora.goraci.Generator
+elif [ "$COMMAND" = "Verify" ] ; then
+ CLASS=org.apache.gora.goraci.Verify
+elif [ "$COMMAND" = "Walker" ] ; then
+ CLASS=org.apache.gora.goraci.Walker
+elif [ "$COMMAND" = "Print" ] ; then
+ CLASS=org.apache.gora.goraci.Print
+elif [ "$COMMAND" = "Delete" ] ; then
+ CLASS=org.apache.gora.goraci.Delete
+elif [ "$COMMAND" = "Loop" ] ; then
+ CLASS=org.apache.gora.goraci.Loop
+else
+ CLASS=$1
+ shift
+fi
+
+# initial CLASSPATH
+CLASSPATH=""
+
+# add libs to CLASSPATH
+SEP=""
+for f in $GORACI_HOME/lib/*.jar; do
+ CLASSPATH=${CLASSPATH}$SEP$f;
+ SEP=":"
+done
+
+#run it
+export HADOOP_CLASSPATH="$CLASSPATH"
+LIBJARS=`echo $HADOOP_CLASSPATH | tr : ,`
+hadoop jar "$GORACI_HOME/lib/org.apache.gora.goraci-0.0.1-SNAPSHOT.jar" $CLASS -libjars "$LIBJARS" "$@"
+
+
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/pom.xml
----------------------------------------------------------------------
diff --git a/gora-goraci/pom.xml b/gora-goraci/pom.xml
new file mode 100644
index 0000000..273361a
--- /dev/null
+++ b/gora-goraci/pom.xml
@@ -0,0 +1,275 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.gora</groupId>
+ <artifactId>gora</artifactId>
+ <version>0.5-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <artifactId>gora-goraci</artifactId>
+
+ <name>Apache Gora :: GoraCI</name>
+ <url>http://gora.apache.org</url>
+ <description>The GoraCI test runs many ingest clients that continually create
+ linked lists containing 25 million nodes. At some point the clients are stopped
+ and a map reduce job is run to ensure no linked list has a hole. A hole indicates
+ data was lost.</description>
+ <organization>
+ <name>The Apache Software Foundation</name>
+ <url>http://www.apache.org/</url>
+ </organization>
+ <issueManagement>
+ <system>JIRA</system>
+ <url>https://issues.apache.org/jira/browse/GORA</url>
+ </issueManagement>
+ <ciManagement>
+ <system>Jenkins</system>
+ <url>https://builds.apache.org/job/Gora-trunk/</url>
+ </ciManagement>
+
+ <build>
+ <directory>target</directory>
+ <outputDirectory>${basedir}/target/classes</outputDirectory>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>${maven-dependency-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>lib</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ <excludeTransitive>true</excludeTransitive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <outputDirectory>lib</outputDirectory>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>lib</directory>
+ <includes>
+ <include>**/*.jar</include>
+ </includes>
+ <followSymlinks>false</followSymlinks>
+ </fileset>
+ </filesets>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <versionRange>[2.0,)</versionRange>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore />
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ </build>
+
+ <profiles>
+ <profile>
+ <!-- this profile contains the runtime deps for accumulo-1.4 -->
+ <id>accumulo-1.4</id>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.gora</groupId>
+ <artifactId>gora-accumulo</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.accumulo</groupId>
+ <artifactId>accumulo-core</artifactId>
+ <version>1.4.0</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.accumulo</groupId>
+ <artifactId>cloudtrace</artifactId>
+ <version>1.4.0</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.thrift</groupId>
+ <artifactId>libthrift</artifactId>
+ <version>0.6.1</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>3.3.1</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+
+ <profile>
+ <id>hbase-0.92</id>
+ <!-- this profile contains the runtime deps for hbase-0.92 -->
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.gora</groupId>
+ <artifactId>gora-hbase</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hbase</groupId>
+ <artifactId>hbase</artifactId>
+ <!-- version>0.92.1</version -->
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jdom</groupId>
+ <artifactId>jdom</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>3.4.3</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+
+ <profile>
+ <id>cassandra-2.0.2</id>
+ <!-- this profile contains the runtime deps for Cassandra 1.1.2 -->
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.gora</groupId>
+ <artifactId>gora-cassandra</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cassandra</groupId>
+ <artifactId>cassandra-all</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cassandra</groupId>
+ <artifactId>cassandra-thrift</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hectorclient</groupId>
+ <artifactId>hector-core</artifactId>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.cassandra</groupId>
+ <artifactId>cassandra-all</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.jdom</groupId>
+ <artifactId>jdom</artifactId>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>maven-plugins</groupId>
+ <artifactId>maven-cobertura-plugin</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>maven-plugins</groupId>
+ <artifactId>maven-findbugs-plugin</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <!-- dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId>
+ <version>0.8.0</version> </dependency -->
+ </dependencies>
+
+ </profile>
+ <!-- profile> <id>sql</id> <dependencies> <dependency> <groupId>org.apache.gora.goraci</groupId>
+ <artifactId>gora-sql</artifactId> <version>${gora.version}</version> <scope>runtime</scope>
+ </dependency> </dependencies> </profile -->
+ </profiles>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.gora</groupId>
+ <artifactId>gora-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.avro</groupId>
+ <artifactId>avro</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ </dependency>
+
+ </dependencies>
+
+
+</project>
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/avro/cinode.json
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/avro/cinode.json b/gora-goraci/src/main/avro/cinode.json
new file mode 100644
index 0000000..207bb18
--- /dev/null
+++ b/gora-goraci/src/main/avro/cinode.json
@@ -0,0 +1,10 @@
+{
+ "type": "record",
+ "name": "CINode",
+ "namespace": "org.apache.gora.goraci.generated",
+ "fields" : [
+ {"name": "prev", "type": "long"},
+ {"name": "client", "type": "string"},
+ {"name": "count", "type": "long"}
+ ]
+}
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/avro/flushed.json
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/avro/flushed.json b/gora-goraci/src/main/avro/flushed.json
new file mode 100644
index 0000000..74872e6
--- /dev/null
+++ b/gora-goraci/src/main/avro/flushed.json
@@ -0,0 +1,8 @@
+{
+ "type": "record",
+ "name": "Flushed",
+ "namespace": "org.apache.gora.goraci.generated",
+ "fields" : [
+ {"name": "count", "type": "long"}
+ ]
+}
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/java/org/apache/gora/goraci/Delete.java
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/java/org/apache/gora/goraci/Delete.java b/gora-goraci/src/main/java/org/apache/gora/goraci/Delete.java
new file mode 100644
index 0000000..9884f64
--- /dev/null
+++ b/gora-goraci/src/main/java/org/apache/gora/goraci/Delete.java
@@ -0,0 +1,57 @@
+/**
+ * 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.gora.goraci;
+
+import org.apache.gora.goraci.generated.CINode;
+
+import java.math.BigInteger;
+
+import org.apache.gora.store.DataStore;
+import org.apache.gora.store.DataStoreFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.util.Tool;
+import org.apache.hadoop.util.ToolRunner;
+
+/**
+ * A stand alone program that deletes a single node.
+ */
+public class Delete extends Configured implements Tool {
+
+ public int run(String[] args) throws Exception {
+ if (args.length != 1) {
+ System.out.println("Usage : " + Delete.class.getSimpleName() + " <node to delete>");
+ return 0;
+ }
+
+ DataStore<Long,CINode> store = DataStoreFactory.getDataStore(Long.class, CINode.class, new Configuration());
+
+ boolean ret = store.delete(new BigInteger(args[0], 16).longValue());
+ store.flush();
+
+ System.out.println("Delete returned " + ret);
+
+ store.close();
+
+ return ret ? 0 : 1;
+ }
+
+ public static void main(String[] args) throws Exception {
+ int ret = ToolRunner.run(new Delete(), args);
+ System.exit(ret);
+ }
+}
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/java/org/apache/gora/goraci/Generator.java
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/java/org/apache/gora/goraci/Generator.java b/gora-goraci/src/main/java/org/apache/gora/goraci/Generator.java
new file mode 100644
index 0000000..53e58c6
--- /dev/null
+++ b/gora-goraci/src/main/java/org/apache/gora/goraci/Generator.java
@@ -0,0 +1,351 @@
+/**
+ * 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.gora.goraci;
+
+import org.apache.gora.goraci.generated.CINode;
+import org.apache.gora.goraci.generated.Flushed;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+
+import org.apache.avro.util.Utf8;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.gora.store.DataStore;
+import org.apache.gora.store.DataStoreFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.NullWritable;
+import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.mapreduce.InputFormat;
+import org.apache.hadoop.mapreduce.InputSplit;
+import org.apache.hadoop.mapreduce.Job;
+import org.apache.hadoop.mapreduce.JobContext;
+import org.apache.hadoop.mapreduce.Mapper;
+import org.apache.hadoop.mapreduce.RecordReader;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.apache.hadoop.mapreduce.lib.output.NullOutputFormat;
+import org.apache.hadoop.util.Tool;
+import org.apache.hadoop.util.ToolRunner;
+
+/**
+ * A Map only job that generates random linked list and stores them using Gora.
+ */
+public class Generator extends Configured implements Tool {
+
+ private static final Log LOG = LogFactory.getLog(Generator.class);
+
+ static final int WIDTH = 1000000;
+ static final int WRAP = WIDTH * 25;
+
+ static class GeneratorInputFormat extends InputFormat<LongWritable,NullWritable> {
+
+ static class GeneratorInputSplit extends InputSplit implements Writable {
+
+ @Override
+ public long getLength() throws IOException, InterruptedException {
+ return 1;
+ }
+
+ @Override
+ public String[] getLocations() throws IOException, InterruptedException {
+ return new String[0];
+ }
+
+ @Override
+ public void readFields(DataInput arg0) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void write(DataOutput arg0) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ static class GeneratorRecordReader extends RecordReader<LongWritable,NullWritable> {
+
+ private long numNodes;
+ private boolean hasNext = true;
+
+ @Override
+ public void close() throws IOException {
+
+ }
+
+ @Override
+ public LongWritable getCurrentKey() throws IOException, InterruptedException {
+ return new LongWritable(numNodes);
+ }
+
+ @Override
+ public NullWritable getCurrentValue() throws IOException, InterruptedException {
+ return NullWritable.get();
+ }
+
+ @Override
+ public float getProgress() throws IOException, InterruptedException {
+ return 0;
+ }
+
+ @Override
+ public void initialize(InputSplit arg0, TaskAttemptContext context) throws IOException, InterruptedException {
+ numNodes = context.getConfiguration().getLong("org.apache.gora.goraci.generator.nodes", 1000000);
+ }
+
+ @Override
+ public boolean nextKeyValue() throws IOException, InterruptedException {
+ boolean hasnext = this.hasNext;
+ this.hasNext = false;
+ return hasnext;
+ }
+
+ }
+
+ @Override
+ public RecordReader<LongWritable,NullWritable> createRecordReader(InputSplit split, TaskAttemptContext context) throws IOException, InterruptedException {
+ GeneratorRecordReader rr = new GeneratorRecordReader();
+ rr.initialize(split, context);
+ return rr;
+ }
+
+ @Override
+ public List<InputSplit> getSplits(JobContext job) throws IOException, InterruptedException {
+ int numMappers = job.getConfiguration().getInt("org.apache.gora.goraci.generator.mappers", 1);
+
+ ArrayList<InputSplit> splits = new ArrayList<InputSplit>(numMappers);
+
+ for (int i = 0; i < numMappers; i++) {
+ splits.add(new GeneratorInputSplit());
+ }
+
+ return splits;
+ }
+
+ }
+
+ /**
+ * Some ASCII art time:
+ * [ . . . ] represents one batch of random longs of length WIDTH
+ *
+ * _________________________
+ * | ______ |
+ * | | ||
+ * __+_________________+_____ ||
+ * v v v |||
+ * first = [ . . . . . . . . . . . ] |||
+ * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ |||
+ * | | | | | | | | | | | |||
+ * prev = [ . . . . . . . . . . . ] |||
+ * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ |||
+ * | | | | | | | | | | | |||
+ * current = [ . . . . . . . . . . . ] |||
+ * |||
+ * ... |||
+ * |||
+ * last = [ . . . . . . . . . . . ] |||
+ * | | | | | | | | | | |-----|||
+ * | |--------||
+ * |___________________________|
+ */
+
+ static class GeneratorMapper extends Mapper<LongWritable,NullWritable,NullWritable,NullWritable> {
+
+ private boolean concurrent;
+
+ @Override
+ protected void setup(Context context) throws IOException, InterruptedException {
+ super.setup(context);
+ concurrent = context.getConfiguration().getBoolean("org.apache.gora.goraci.generator.concurrent", false);
+ }
+
+ @Override
+ protected void map(LongWritable key, NullWritable value, Context output) throws IOException {
+ long num = key.get();
+ System.out.println("num" + num);
+
+ Utf8 id = new Utf8(UUID.randomUUID().toString());
+
+ Configuration conf = new Configuration();
+ DataStore<Long,CINode> store = DataStoreFactory.getDataStore(Long.class, CINode.class, conf);
+ DataStore<Utf8,Flushed> flushedTable = null;
+
+ if (concurrent) {
+ flushedTable = DataStoreFactory.getDataStore(Utf8.class, Flushed.class, conf);
+ flushedTable.createSchema();
+ }
+
+ store.createSchema();
+
+ Random rand = new Random();
+
+ long[] first = null;
+ long[] prev = null;
+ long[] current = new long[WIDTH];
+
+ long count = 0;
+ while (count < num) {
+ for (int i = 0; i < current.length; i++)
+ current[i] = Math.abs(rand.nextLong());
+
+ persist(output, store, count, prev, current, id);
+
+ if (first == null)
+ first = current;
+ prev = current;
+ current = new long[WIDTH];
+
+ count += current.length;
+ output.setStatus("Count " + count);
+
+ if (count % WRAP == 0) {
+ // this block of code turns the 1 million linked list of length 25 into one giant circular linked list of 25 million
+
+ circularLeftShift(first);
+
+ updatePrev(store, first, prev);
+
+ if (concurrent) {
+ // keep track of whats flushed in another table, verify can use this info to run concurrently
+ Flushed flushed = flushedTable.newPersistent();
+ flushed.setCount(count);
+ flushedTable.put(id, flushed);
+ flushedTable.flush();
+ }
+
+ first = null;
+ prev = null;
+ }
+
+ }
+
+ store.close();
+ if (concurrent)
+ flushedTable.close();
+
+ }
+
+ private static void circularLeftShift(long[] first) {
+ long ez = first[0];
+ for (int i = 0; i < first.length - 1; i++)
+ first[i] = first[i + 1];
+ first[first.length - 1] = ez;
+ }
+
+ private static void persist(Context output, DataStore<Long,CINode> store, long count, long[] prev, long[] current, Utf8 id) throws IOException {
+ for (int i = 0; i < current.length; i++) {
+ CINode node = store.newPersistent();
+ node.setCount(count + i);
+ if (prev != null)
+ node.setPrev(prev[i]);
+ else
+ node.setPrev((long) -1);
+ node.setClient(id);
+
+ store.put(current[i], node);
+ if (i % 1000 == 0) {
+ // Tickle progress every so often else maprunner will think us hung
+ output.progress();
+ }
+ }
+
+ store.flush();
+ }
+
+ private static void updatePrev(DataStore<Long,CINode> store, long[] first, long[] current) throws IOException {
+ for (int i = 0; i < current.length; i++) {
+ CINode node = store.newPersistent();
+ node.setPrev(current[i]);
+ store.put(first[i], node);
+ }
+
+ store.flush();
+ }
+ }
+
+
+ @Override
+ public int run(String[] args) throws Exception {
+ Options options = new Options();
+ options.addOption("c", "concurrent", false, "update secondary table with information that allows verification to run concurrently");
+
+ GnuParser parser = new GnuParser();
+ CommandLine cmd = null;
+ try {
+ cmd = parser.parse(options, args);
+ if (cmd.getArgs().length != 2) {
+ throw new ParseException("Did not see expected # of arguments, saw " + cmd.getArgs().length);
+ }
+ } catch (ParseException e) {
+ System.err.println("Failed to parse command line " + e.getMessage());
+ System.err.println();
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp(getClass().getSimpleName() + " <num mappers> <num nodes per map>", options);
+ System.exit(-1);
+ }
+
+ int numMappers = Integer.parseInt(cmd.getArgs()[0]);
+ long numNodes = Long.parseLong(cmd.getArgs()[1]);
+ return run(numMappers, numNodes, cmd.hasOption("c"));
+ }
+
+ public int run(int numMappers, long numNodes, boolean concurrent) throws Exception {
+ LOG.info("Running Generator with numMappers=" + numMappers +", numNodes=" + numNodes);
+
+ Job job = new Job(getConf());
+
+ job.setJobName("Link Generator");
+ job.setNumReduceTasks(0);
+ job.setJarByClass(getClass());
+
+ job.setInputFormatClass(GeneratorInputFormat.class);
+ job.setOutputKeyClass(NullWritable.class);
+ job.setOutputValueClass(NullWritable.class);
+
+ job.getConfiguration().setInt("org.apache.gora.goraci.generator.mappers", numMappers);
+ job.getConfiguration().setLong("org.apache.gora.goraci.generator.nodes", numNodes);
+ job.getConfiguration().setBoolean("org.apache.gora.goraci.generator.concurrent", concurrent);
+
+ job.setMapperClass(GeneratorMapper.class);
+
+ job.setOutputFormatClass(NullOutputFormat.class);
+
+ job.getConfiguration().setBoolean("mapred.map.tasks.speculative.execution", false);
+
+ boolean success = job.waitForCompletion(true);
+
+ return success ? 0 : 1;
+ }
+
+ public static void main(String[] args) throws Exception {
+ int ret = ToolRunner.run(new Generator(), args);
+ System.exit(ret);
+ }
+}
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/java/org/apache/gora/goraci/Loop.java
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/java/org/apache/gora/goraci/Loop.java b/gora-goraci/src/main/java/org/apache/gora/goraci/Loop.java
new file mode 100644
index 0000000..29c4812
--- /dev/null
+++ b/gora-goraci/src/main/java/org/apache/gora/goraci/Loop.java
@@ -0,0 +1,164 @@
+/**
+ * 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.gora.goraci;
+
+import java.util.Arrays;
+import java.util.UUID;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.util.Tool;
+import org.apache.hadoop.util.ToolRunner;
+
+/**
+ * Executes Generate and Verify in a loop. Data is not cleaned between runs, so each iteration
+ * adds more data.
+ */
+public class Loop extends Configured implements Tool {
+
+ private static final Log LOG = LogFactory.getLog(Loop.class);
+
+ protected void runGenerator(int numMappers, long numNodes, boolean concurrent) throws Exception {
+ Generator generator = new Generator();
+ generator.setConf(getConf());
+ int retCode = generator.run(numMappers, numNodes, concurrent);
+
+ if (retCode > 0) {
+ throw new RuntimeException("Generator failed with return code: " + retCode);
+ }
+ }
+
+ protected void runVerify(String outputDir, int numReducers, long expectedNumNodes) throws Exception {
+ Verify verify = startVerify(outputDir, numReducers, false);
+ verify.waitForCompletion();
+ checkSuccess(verify, expectedNumNodes);
+ }
+
+ private void checkSuccess(Verify verify, long expectedNumNodes) throws Exception {
+ if (!verify.isSuccessful()) {
+ throw new RuntimeException("Verify.isSuccessful() returned false");
+ }
+
+ boolean verifySuccess = verify.verify(expectedNumNodes);
+ if (!verifySuccess) {
+ throw new RuntimeException("Verify.verify failed");
+ }
+
+ LOG.info("Verify finished with succees. Total nodes=" + expectedNumNodes);
+ }
+
+ protected Verify startVerify(String outputDir, int numReducers, boolean concurrent) throws Exception {
+ Path outputPath = new Path(outputDir);
+ UUID uuid = UUID.randomUUID(); //create a random UUID.
+ Path iterationOutput = new Path(outputPath, uuid.toString());
+
+ Verify verify = new Verify();
+ verify.setConf(getConf());
+ verify.start(iterationOutput, numReducers, concurrent);
+ return verify;
+ }
+
+ @Override
+ public int run(String[] args) throws Exception {
+
+ Options options = new Options();
+ options.addOption("c", "concurrent", false, "run generation and verification and concurrently");
+
+ GnuParser parser = new GnuParser();
+ CommandLine cmd = null;
+ try {
+ cmd = parser.parse(options, args);
+ if (cmd.getArgs().length != 5) {
+ throw new ParseException("Did not see expected # of arguments, saw " + cmd.getArgs().length);
+ }
+ } catch (ParseException e) {
+ System.err.println("Failed to parse command line " + e.getMessage());
+ System.err.println();
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp(getClass().getSimpleName() + " <num iterations> <num mappers> <num nodes per mapper> <output dir> <num reducers>", options);
+ System.exit(-1);
+ }
+
+ LOG.info("Running Loop with args:" + Arrays.deepToString(cmd.getArgs()));
+
+ boolean concurrent = cmd.hasOption("c");
+ int numIterations = Integer.parseInt(cmd.getArgs()[0]);
+ int numMappers = Integer.parseInt(cmd.getArgs()[1]);
+ long numNodes = Long.parseLong(cmd.getArgs()[2]);
+ String outputDir = cmd.getArgs()[3];
+ int numReducers = Integer.parseInt(cmd.getArgs()[4]);
+
+ if (numNodes % Generator.WRAP != 0) {
+ throw new RuntimeException("Number of node per mapper is not a multiple of " + String.format("%,d", Generator.WRAP));
+ }
+
+ long expectedNumNodes = 0;
+
+ if (numIterations < 0) {
+ numIterations = Integer.MAX_VALUE; //run indefinitely (kind of)
+ }
+
+ Verify verify = null;
+ long verifyNodes = 0;
+
+ for (int i=0; i < numIterations; i++) {
+ LOG.info("Starting iteration = " + i);
+ runGenerator(numMappers, numNodes, concurrent);
+ expectedNumNodes += numMappers * numNodes;
+
+ if (concurrent) {
+ if (verify != null) {
+ if (verify.isComplete()) {
+ checkSuccess(verify, verifyNodes);
+ verify = startVerify(outputDir, numReducers, true);
+ verifyNodes = expectedNumNodes;
+ }
+ } else {
+ verify = startVerify(outputDir, numReducers, true);
+ verifyNodes = expectedNumNodes;
+ }
+ } else {
+ runVerify(outputDir, numReducers, expectedNumNodes);
+ }
+ }
+
+ if (verify != null) {
+ verify.waitForCompletion();
+ checkSuccess(verify, verifyNodes);
+
+ if (verifyNodes != expectedNumNodes)
+ runVerify(outputDir, numReducers, expectedNumNodes);
+ }
+
+ return 0;
+ }
+
+ public static void main(String[] args) throws Exception {
+ int ret = ToolRunner.run(new Loop(), args);
+ System.exit(ret);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/java/org/apache/gora/goraci/Print.java
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/java/org/apache/gora/goraci/Print.java b/gora-goraci/src/main/java/org/apache/gora/goraci/Print.java
new file mode 100644
index 0000000..cc940e3
--- /dev/null
+++ b/gora-goraci/src/main/java/org/apache/gora/goraci/Print.java
@@ -0,0 +1,95 @@
+/**
+ * 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.gora.goraci;
+
+import org.apache.gora.goraci.generated.CINode;
+
+import java.math.BigInteger;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.gora.query.Query;
+import org.apache.gora.query.Result;
+import org.apache.gora.store.DataStore;
+import org.apache.gora.store.DataStoreFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.util.Tool;
+import org.apache.hadoop.util.ToolRunner;
+
+/**
+ * A stand alone program that prints out portions of a list created by {@link Generator}
+ */
+public class Print extends Configured implements Tool {
+
+ public int run(String[] args) throws Exception {
+ Options options = new Options();
+ options.addOption("s", "start", true, "start key");
+ options.addOption("e", "end", true, "end key");
+ options.addOption("l", "limit", true, "number to print");
+
+ GnuParser parser = new GnuParser();
+ CommandLine cmd = null;
+ try {
+ cmd = parser.parse(options, args);
+ if (cmd.getArgs().length != 0) {
+ throw new ParseException("Command takes no arguments");
+ }
+ } catch (ParseException e) {
+ System.err.println("Failed to parse command line " + e.getMessage());
+ System.err.println();
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp(getClass().getSimpleName(), options);
+ System.exit(-1);
+ }
+
+ DataStore<Long,CINode> store = DataStoreFactory.getDataStore(Long.class, CINode.class, new Configuration());
+
+ Query<Long,CINode> query = store.newQuery();
+
+ if (cmd.hasOption("s"))
+ query.setStartKey(new BigInteger(cmd.getOptionValue("s"), 16).longValue());
+
+ if (cmd.hasOption("e"))
+ query.setEndKey(new BigInteger(cmd.getOptionValue("e"), 16).longValue());
+
+ if (cmd.hasOption("l"))
+ query.setLimit(Integer.parseInt(cmd.getOptionValue("l")));
+ else
+ query.setLimit(100);
+
+ Result<Long,CINode> rs = store.execute(query);
+
+ while (rs.next()) {
+ CINode node = rs.get();
+ System.out.printf("%016x:%016x:%012d:%s\n", rs.getKey(), node.getPrev(), node.getCount(), node.getClient());
+
+ }
+
+ store.close();
+
+ return 0;
+ }
+
+ public static void main(String[] args) throws Exception {
+ int ret = ToolRunner.run(new Print(), args);
+ System.exit(ret);
+ }
+}
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/java/org/apache/gora/goraci/Verify.java
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/java/org/apache/gora/goraci/Verify.java b/gora-goraci/src/main/java/org/apache/gora/goraci/Verify.java
new file mode 100644
index 0000000..7a449c6
--- /dev/null
+++ b/gora-goraci/src/main/java/org/apache/gora/goraci/Verify.java
@@ -0,0 +1,294 @@
+/**
+ * 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.gora.goraci;
+
+import org.apache.gora.goraci.generated.CINode;
+import org.apache.gora.goraci.generated.Flushed;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avro.util.Utf8;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.gora.mapreduce.GoraMapper;
+import org.apache.gora.query.Query;
+import org.apache.gora.query.Result;
+import org.apache.gora.store.DataStore;
+import org.apache.gora.store.DataStoreFactory;
+import org.apache.gora.util.GoraException;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.Text;
+import org.apache.hadoop.io.VLongWritable;
+import org.apache.hadoop.mapreduce.Counter;
+import org.apache.hadoop.mapreduce.Counters;
+import org.apache.hadoop.mapreduce.Job;
+import org.apache.hadoop.mapreduce.Reducer;
+import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
+import org.apache.hadoop.util.Tool;
+import org.apache.hadoop.util.ToolRunner;
+
+/**
+ * A Map Reduce job that verifies that the linked list generated by {@link org.apache.gora.goraci.Generator} do not have any holes.
+ */
+public class Verify extends Configured implements Tool {
+
+ private static final Log LOG = LogFactory.getLog(Verify.class);
+ private static final VLongWritable DEF = new VLongWritable(-1);
+
+ private Job job;
+
+
+ public static class VerifyMapper extends GoraMapper<Long,CINode,LongWritable,VLongWritable> {
+ private LongWritable row = new LongWritable();
+ private LongWritable ref = new LongWritable();
+ private VLongWritable vrow = new VLongWritable();
+ private Map<Utf8,Long> flushed = null;
+
+ @Override
+ protected void setup(Context context) throws IOException, InterruptedException {
+ super.setup(context);
+
+ String[] entries = context.getConfiguration().getStrings("org.apache.gora.goraci.verify.flushed");
+
+ if (entries != null && entries.length > 0) {
+ flushed = new HashMap<Utf8,Long>();
+ for (String entry : entries) {
+ String[] kv = entry.split(":");
+ flushed.put(new Utf8(kv[0]), Long.parseLong(kv[1]));
+ }
+ }
+ }
+
+ @Override
+ protected void map(Long key, CINode node, Context context) throws IOException, InterruptedException {
+ if (flushed != null) {
+ Long count = flushed.get(node.getClient());
+ if (count == null || node.getCount() >= count) {
+ context.getCounter(Counts.IGNORED).increment(1);
+ return;
+ }
+ }
+
+ row.set(key);
+ context.write(row, DEF);
+
+ if (node.getPrev() >= 0) {
+ ref.set(node.getPrev());
+ vrow.set(key);
+ context.write(ref, vrow);
+ }
+ }
+ }
+
+ public static enum Counts {
+ UNREFERENCED, UNDEFINED, REFERENCED, CORRUPT, IGNORED
+ }
+
+ public static class VerifyReducer extends Reducer<LongWritable,VLongWritable,Text,Text> {
+ private ArrayList<Long> refs = new ArrayList<Long>();
+
+ public void reduce(LongWritable key, Iterable<VLongWritable> values, Context context) throws IOException, InterruptedException {
+
+ int defCount = 0;
+
+ refs.clear();
+ for (VLongWritable type : values) {
+ if (type.get() == -1) {
+ defCount++;
+ } else {
+ refs.add(type.get());
+ }
+ }
+
+ // TODO check for more than one def, should not happen
+
+ if (defCount == 0 && refs.size() > 0) {
+ // this is bad, found a node that is referenced but not defined. It must have been lost, emit some info about this node for debugging purposes.
+
+ StringBuilder sb = new StringBuilder();
+ String comma = "";
+ for (Long ref : refs) {
+ sb.append(comma);
+ comma = ",";
+ sb.append(String.format("%016x", ref));
+ }
+
+ context.write(new Text(String.format("%016x", key.get())), new Text(sb.toString()));
+ context.getCounter(Counts.UNDEFINED).increment(1);
+
+ } else if (defCount > 0 && refs.size() == 0) {
+ // node is defined but not referenced
+ context.getCounter(Counts.UNREFERENCED).increment(1);
+ } else {
+ // node is defined and referenced
+ context.getCounter(Counts.REFERENCED).increment(1);
+ }
+
+ }
+ }
+
+ @Override
+ public int run(String[] args) throws Exception {
+
+ Options options = new Options();
+ options.addOption("c", "concurrent", false, "run concurrently with generation");
+
+ GnuParser parser = new GnuParser();
+ CommandLine cmd = null;
+ try {
+ cmd = parser.parse(options, args);
+ if (cmd.getArgs().length != 2) {
+ throw new ParseException("Did not see expected # of arguments, saw " + cmd.getArgs().length);
+ }
+ } catch (ParseException e) {
+ System.err.println("Failed to parse command line " + e.getMessage());
+ System.err.println();
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp(getClass().getSimpleName() + " <output dir> <num reducers>", options);
+ System.exit(-1);
+ }
+
+ String outputDir = cmd.getArgs()[0];
+ int numReducers = Integer.parseInt(cmd.getArgs()[1]);
+
+ return run(outputDir, numReducers, cmd.hasOption("c"));
+ }
+
+ public int run(String outputDir, int numReducers, boolean concurrent) throws Exception {
+ return run(new Path(outputDir), numReducers, concurrent);
+ }
+
+ public int run(Path outputDir, int numReducers, boolean concurrent) throws Exception {
+ start(outputDir, numReducers, concurrent);
+
+ boolean success = job.waitForCompletion(true);
+
+ return success ? 0 : 1;
+ }
+
+ public void start(Path outputDir, int numReducers, boolean concurrent) throws GoraException, IOException, Exception {
+ LOG.info("Running Verify with outputDir=" + outputDir +", numReducers=" + numReducers);
+
+ DataStore<Long,CINode> store = DataStoreFactory.getDataStore(Long.class, CINode.class, new Configuration());
+
+ job = new Job(getConf());
+
+ if (!job.getConfiguration().get("io.serializations").contains("org.apache.hadoop.io.serializer.JavaSerialization")) {
+ job.getConfiguration().set("io.serializations", job.getConfiguration().get("io.serializations") + ",org.apache.hadoop.io.serializer.JavaSerialization");
+ }
+
+ job.setJobName("Link Verifier");
+ job.setNumReduceTasks(numReducers);
+ job.setJarByClass(getClass());
+
+ Query<Long,CINode> query = store.newQuery();
+ if (!concurrent) {
+ // no concurrency filtering, only need prev field
+ query.setFields("prev");
+ } else {
+ readFlushed(job.getConfiguration());
+ }
+
+ GoraMapper.initMapperJob(job, query, store, LongWritable.class, VLongWritable.class, VerifyMapper.class, true);
+
+ job.getConfiguration().setBoolean("mapred.map.tasks.speculative.execution", false);
+
+ job.setReducerClass(VerifyReducer.class);
+ job.setOutputFormatClass(TextOutputFormat.class);
+ TextOutputFormat.setOutputPath(job, outputDir);
+
+ store.close();
+
+ job.submit();
+ }
+
+ public boolean isComplete() throws IOException {
+ return job.isComplete();
+ }
+
+ public boolean isSuccessful() throws IOException {
+ return job.isSuccessful();
+ }
+
+ public boolean waitForCompletion() throws IOException, InterruptedException, ClassNotFoundException {
+ return job.waitForCompletion(true);
+ }
+
+ private void readFlushed(Configuration conf) throws Exception {
+ DataStore<Utf8,Flushed> flushedTable = DataStoreFactory.getDataStore(Utf8.class, Flushed.class, conf);
+
+ Query<Utf8,Flushed> query = flushedTable.newQuery();
+ Result<Utf8,Flushed> result = flushedTable.execute(query);
+
+ ArrayList<String> flushedEntries = new ArrayList<String>();
+ while (result.next()) {
+ flushedEntries.add(result.getKey() + ":" + result.get().getCount());
+ }
+
+ conf.setStrings("org.apache.gora.goraci.verify.flushed", flushedEntries.toArray(new String[] {}));
+
+ flushedTable.close();
+ }
+
+ public boolean verify(long expectedReferenced) throws Exception {
+ if (job == null) {
+ throw new IllegalStateException("You should call run() first");
+ }
+
+ Counters counters = job.getCounters();
+
+ Counter referenced = counters.findCounter(Counts.REFERENCED);
+ Counter unreferenced = counters.findCounter(Counts.UNREFERENCED);
+ Counter undefined = counters.findCounter(Counts.UNDEFINED);
+
+ boolean success = true;
+ //assert
+ if (expectedReferenced != referenced.getValue()) {
+ LOG.error("Expected referenced count does not match with actual referenced count. " +
+ "expected referenced=" + expectedReferenced + " ,actual=" + referenced.getValue());
+ success = false;
+ }
+
+ if (unreferenced.getValue() > 0) {
+ LOG.error("Unreferenced nodes were not expected. Unreferenced count=" + unreferenced.getValue());
+ success = false;
+ }
+
+ if (undefined.getValue() > 0) {
+ LOG.error("Found an undefined node. Undefined count=" + undefined.getValue());
+ success = false;
+ }
+
+ return success;
+ }
+
+ public static void main(String[] args) throws Exception {
+ int ret = ToolRunner.run(new Verify(), args);
+ System.exit(ret);
+ }
+}
http://git-wip-us.apache.org/repos/asf/gora/blob/a60a3370/gora-goraci/src/main/java/org/apache/gora/goraci/Walker.java
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/java/org/apache/gora/goraci/Walker.java b/gora-goraci/src/main/java/org/apache/gora/goraci/Walker.java
new file mode 100644
index 0000000..d0e0165
--- /dev/null
+++ b/gora-goraci/src/main/java/org/apache/gora/goraci/Walker.java
@@ -0,0 +1,129 @@
+/**
+ * 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.gora.goraci;
+
+import org.apache.gora.goraci.generated.CINode;
+
+import java.io.IOException;
+import java.util.Random;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.gora.query.Query;
+import org.apache.gora.query.Result;
+import org.apache.gora.store.DataStore;
+import org.apache.gora.store.DataStoreFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.util.Tool;
+import org.apache.hadoop.util.ToolRunner;
+
+/**
+ * A stand alone program that follows a linked list created by {@link Generator} and prints timing info.
+ */
+public class Walker extends Configured implements Tool {
+
+ private static final String[] PREV_FIELD = new String[] {"prev"};
+
+ public int run(String[] args) throws IOException {
+ Options options = new Options();
+ options.addOption("n", "num", true, "number of queries");
+
+ GnuParser parser = new GnuParser();
+ CommandLine cmd = null;
+ try {
+ cmd = parser.parse(options, args);
+ if (cmd.getArgs().length != 0) {
+ throw new ParseException("Command takes no arguments");
+ }
+ } catch (ParseException e) {
+ System.err.println("Failed to parse command line " + e.getMessage());
+ System.err.println();
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp(getClass().getSimpleName(), options);
+ System.exit(-1);
+ }
+
+ long maxQueries = Long.MAX_VALUE;
+ if (cmd.hasOption('n')) {
+ maxQueries = Long.parseLong(cmd.getOptionValue("n"));
+ }
+
+ DataStore<Long,CINode> store = DataStoreFactory.getDataStore(Long.class, CINode.class, new Configuration());
+
+ Random rand = new Random();
+
+ long numQueries = 0;
+
+ while (numQueries < maxQueries) {
+ CINode node = findStartNode(rand, store);
+ numQueries++;
+ while (node != null && node.getPrev() >= 0 && numQueries < maxQueries) {
+ long prev = node.getPrev();
+
+ long t1 = System.currentTimeMillis();
+ node = store.get(prev, PREV_FIELD);
+ long t2 = System.currentTimeMillis();
+ System.out.printf("CQ %d %016x \n", t2 - t1, prev);
+ numQueries++;
+
+ t1 = System.currentTimeMillis();
+ node = store.get(prev, PREV_FIELD);
+ t2 = System.currentTimeMillis();
+ System.out.printf("HQ %d %016x \n", t2 - t1, prev);
+ numQueries++;
+
+ }
+ }
+
+ store.close();
+ return 0;
+ }
+
+ private static CINode findStartNode(Random rand, DataStore<Long,CINode> store) throws IOException {
+ Query<Long,CINode> query = store.newQuery();
+ query.setStartKey(rand.nextLong());
+ query.setLimit(1);
+ query.setFields(PREV_FIELD);
+
+ long t1 = System.currentTimeMillis();
+ Result<Long,CINode> rs = store.execute(query);
+ long t2 = System.currentTimeMillis();
+
+ try {
+ if (rs.next()) {
+ System.out.printf("FSR %d %016x\n", t2 - t1, rs.getKey());
+ return rs.get();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("FSR " + (t2 - t1));
+
+ return null;
+ }
+
+ public static void main(String[] args) throws Exception {
+ int ret = ToolRunner.run(new Walker(), args);
+ System.exit(ret);
+ }
+
+}
[3/4] git commit: Merge branch 'master' of
https://git-wip-us.apache.org/repos/asf/gora
Posted by le...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/gora
Project: http://git-wip-us.apache.org/repos/asf/gora/repo
Commit: http://git-wip-us.apache.org/repos/asf/gora/commit/8644c0b6
Tree: http://git-wip-us.apache.org/repos/asf/gora/tree/8644c0b6
Diff: http://git-wip-us.apache.org/repos/asf/gora/diff/8644c0b6
Branch: refs/heads/master
Commit: 8644c0b604d13f3701a03c13579566b6875c0361
Parents: a60a337 dd35192
Author: Lewis John McGibbney <le...@jpl.nasa.gov>
Authored: Sun Aug 31 17:45:50 2014 -0700
Committer: Lewis John McGibbney <le...@jpl.nasa.gov>
Committed: Sun Aug 31 17:45:50 2014 -0700
----------------------------------------------------------------------
.../main/java/org/apache/gora/hbase/store/HBaseStore.java | 10 ++++++++++
pom.xml | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/gora/blob/8644c0b6/pom.xml
----------------------------------------------------------------------
[4/4] git commit: Add Cassandra license header
Posted by le...@apache.org.
Add Cassandra license header
Project: http://git-wip-us.apache.org/repos/asf/gora/repo
Commit: http://git-wip-us.apache.org/repos/asf/gora/commit/90d1cc0a
Tree: http://git-wip-us.apache.org/repos/asf/gora/tree/90d1cc0a
Diff: http://git-wip-us.apache.org/repos/asf/gora/diff/90d1cc0a
Branch: refs/heads/master
Commit: 90d1cc0af6fc9b812036aa0e6db05bb508318a2e
Parents: 8644c0b
Author: Lewis John McGibbney <le...@jpl.nasa.gov>
Authored: Sun Aug 31 17:48:06 2014 -0700
Committer: Lewis John McGibbney <le...@jpl.nasa.gov>
Committed: Sun Aug 31 17:48:06 2014 -0700
----------------------------------------------------------------------
gora-goraci/src/main/resources/gora-cassandra-mapping.xml | 10 ++++++++++
1 file changed, 10 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/gora/blob/90d1cc0a/gora-goraci/src/main/resources/gora-cassandra-mapping.xml
----------------------------------------------------------------------
diff --git a/gora-goraci/src/main/resources/gora-cassandra-mapping.xml b/gora-goraci/src/main/resources/gora-cassandra-mapping.xml
index 27d89dc..08b243a 100644
--- a/gora-goraci/src/main/resources/gora-cassandra-mapping.xml
+++ b/gora-goraci/src/main/resources/gora-cassandra-mapping.xml
@@ -1,4 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
<gora-orm>
<keyspace name="CINode" host="localhost" cluster="GoraCI Test Cluster">
<family name="p"/>