You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ec...@apache.org on 2013/12/17 20:04:01 UTC

[01/14] git commit: ACCUMULO-2015 clean up role files for standalone

Updated Branches:
  refs/heads/1.4.5-SNAPSHOT f56e9c6bd -> 59932f6d2
  refs/heads/1.5.1-SNAPSHOT a78246d37 -> 3458bfaec
  refs/heads/1.6.0-SNAPSHOT f37342bab -> 44a916636
  refs/heads/master b9b15961d -> 6e641f43e


ACCUMULO-2015 clean up role files for standalone

Add checks for gc and tracers file existance in start-* scripts, since
these files are recommended but not required for cluster operation


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/f56e9c6b
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/f56e9c6b
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/f56e9c6b

Branch: refs/heads/1.6.0-SNAPSHOT
Commit: f56e9c6bdc1cc021f8073bd2b27bd59b0f159ebc
Parents: 335f693
Author: Mike Drob <md...@cloudera.com>
Authored: Tue Dec 17 09:15:33 2013 -0800
Committer: Mike Drob <md...@cloudera.com>
Committed: Tue Dec 17 09:15:33 2013 -0800

----------------------------------------------------------------------
 bin/config.sh     | 10 ++--------
 bin/start-all.sh  | 14 +++++++++++--
 bin/start-here.sh | 54 +++++++++++++++++++++++++++++++++++---------------
 3 files changed, 52 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/f56e9c6b/bin/config.sh
----------------------------------------------------------------------
diff --git a/bin/config.sh b/bin/config.sh
index 89685fb..8d0672c 100755
--- a/bin/config.sh
+++ b/bin/config.sh
@@ -114,6 +114,8 @@ if [ -z "${ACCUMULO_VERIFY_ONLY}" ] ; then
           echo `hostname` > "$ACCUMULO_CONF_DIR/masters"
           echo "STANDALONE: echo "`hostname`" > $ACCUMULO_CONF_DIR/slaves"
           echo `hostname` > "$ACCUMULO_CONF_DIR/slaves"
+          echo "STANDALONE: echo "`hostname`" > $ACCUMULO_CONF_DIR/monitor"
+          echo `hostname` > "$ACCUMULO_CONF_DIR/monitor"
           fgrep -s logger.dir.walog "$ACCUMULO_CONF_DIR/accumulo-site.xml" > /dev/null
           WALOG_CONFIGURED=$?
           if [ $WALOG_CONFIGURED -ne 0 -a ! -e "$ACCUMULO_HOME/walogs" ]
@@ -145,14 +147,6 @@ if [ -z "${MONITOR}" ] ; then
     exit 1
   fi
 fi
-if [ ! -f "$ACCUMULO_CONF_DIR/tracers" -a -z "${ACCUMULO_VERIFY_ONLY}" ]; then
-  if [ -z "${MASTER1}" ] ; then
-    echo "Could not find a master node to use as a default for the tracer role. Either set up \"${ACCUMULO_CONF_DIR}/tracers\" or make sure \"${ACCUMULO_CONF_DIR}/masters\" is non-empty."
-    exit 1
-  else
-    echo "$MASTER1" > "$ACCUMULO_CONF_DIR/tracers"
-  fi
-fi
 
 SSH='ssh -qnf -o ConnectTimeout=2'
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/f56e9c6b/bin/start-all.sh
----------------------------------------------------------------------
diff --git a/bin/start-all.sh b/bin/start-all.sh
index e0d4b36..60cf9c3 100755
--- a/bin/start-all.sh
+++ b/bin/start-all.sh
@@ -62,14 +62,24 @@ do
     ${bin}/start-server.sh $master master
 done
 
-for gc in `grep -v '^#' "$ACCUMULO_CONF_DIR/gc"`
+if [[ -r $ACCUMULO_CONF_DIR/gc ]]; then
+    GC=`grep -v '^#' "$ACCUMULO_CONF_DIR/gc"`
+else
+    GC=$MASTER1
+fi
+for gc in "$GC"
 do
     ${bin}/start-server.sh $gc gc "garbage collector"
 done
 
 ${bin}/start-server.sh $MONITOR monitor 
 
-for tracer in `grep -v '^#' "$ACCUMULO_CONF_DIR/tracers"`
+if [[ -r $ACCUMULO_CONF_DIR/tracers ]]; then
+    TRACERS=`grep -v '^#' "$ACCUMULO_CONF_DIR/tracers"`
+else
+    TRACERS=$MASTER1
+fi
+for tracer in "$TRACERS"
 do
    ${bin}/start-server.sh $tracer tracer
 done

http://git-wip-us.apache.org/repos/asf/accumulo/blob/f56e9c6b/bin/start-here.sh
----------------------------------------------------------------------
diff --git a/bin/start-here.sh b/bin/start-here.sh
index 990fb1c..e571b8c 100755
--- a/bin/start-here.sh
+++ b/bin/start-here.sh
@@ -45,14 +45,25 @@ do
     fi
 done
 
-for host in $HOSTS
-do
-    if grep -q "^${host}\$" $ACCUMULO_CONF_DIR/gc
-    then
-	${bin}/start-server.sh $host gc "garbage collector"
-	break
-    fi
-done
+if [[ -r $ACCUMULO_CONF_DIR/gc ]]; then
+    for host in $HOSTS
+    do
+        if grep -q "^${host}\$" $ACCUMULO_CONF_DIR/gc
+        then
+            ${bin}/start-server.sh $host gc "garbage collector"
+            break
+        fi
+    done
+else
+    for host in $HOSTS
+    do
+        if [[ "$host" == "$MASTER1" ]]
+        then
+            ${bin}/start-server.sh $host gc "garbage collector"
+            break
+        fi
+    done
+fi
 
 for host in $HOSTS
 do
@@ -63,11 +74,22 @@ do
     fi
 done
 
-for host in $HOSTS
-do
-    if grep -q "^${host}\$" $ACCUMULO_CONF_DIR/tracers
-    then
-	${bin}/start-server.sh $host tracer 
-	break
-    fi
-done
+if [[ -r $ACCUMULO_CONF_DIR/tracers ]]; then
+    for host in $HOSTS
+    do
+        if grep -q "^${host}\$" $ACCUMULO_CONF_DIR/tracers
+        then
+            ${bin}/start-server.sh $host tracer
+            break
+        fi
+    done
+else
+    for host in $HOSTS
+    do
+        if [[ "$host" == "$MASTER1" ]]
+        then
+            ${bin}/start-server.sh $host tracer
+            break
+        fi
+    done
+fi


[08/14] git commit: ACCUMULO-2037 master is not fetching last location from the metadata table

Posted by ec...@apache.org.
ACCUMULO-2037 master is not fetching last location from the metadata table


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/59932f6d
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/59932f6d
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/59932f6d

Branch: refs/heads/master
Commit: 59932f6d273067faaf9639ef4b632f67587bf5ad
Parents: f56e9c6
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:02:05 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:02:05 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/59932f6d/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
----------------------------------------------------------------------
diff --git a/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java b/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
index dd28cb6..e10b1b3 100644
--- a/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
+++ b/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
@@ -68,6 +68,7 @@ public class MetaDataTableScanner implements Iterator<TabletLocationState> {
     ColumnFQ.fetch(scanner, Constants.METADATA_PREV_ROW_COLUMN);
     scanner.fetchColumnFamily(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY);
+    scanner.fetchColumnFamily(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_LOG_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_CHOPPED_COLUMN_FAMILY);
     scanner.addScanIterator(new IteratorSetting(1000, "wholeRows", WholeRowIterator.class));


[07/14] git commit: ACCUMULO-2037 master is not fetching last location from the metadata table

Posted by ec...@apache.org.
ACCUMULO-2037 master is not fetching last location from the metadata table


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/59932f6d
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/59932f6d
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/59932f6d

Branch: refs/heads/1.4.5-SNAPSHOT
Commit: 59932f6d273067faaf9639ef4b632f67587bf5ad
Parents: f56e9c6
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:02:05 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:02:05 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/59932f6d/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
----------------------------------------------------------------------
diff --git a/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java b/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
index dd28cb6..e10b1b3 100644
--- a/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
+++ b/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
@@ -68,6 +68,7 @@ public class MetaDataTableScanner implements Iterator<TabletLocationState> {
     ColumnFQ.fetch(scanner, Constants.METADATA_PREV_ROW_COLUMN);
     scanner.fetchColumnFamily(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY);
+    scanner.fetchColumnFamily(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_LOG_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_CHOPPED_COLUMN_FAMILY);
     scanner.addScanIterator(new IteratorSetting(1000, "wholeRows", WholeRowIterator.class));


[14/14] git commit: Merge branch '1.6.0-SNAPSHOT'

Posted by ec...@apache.org.
Merge branch '1.6.0-SNAPSHOT'


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/6e641f43
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/6e641f43
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/6e641f43

Branch: refs/heads/master
Commit: 6e641f43e5ecbdf10ca6d147dbc384d2a06bef82
Parents: b9b1596 44a9166
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:04:08 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:04:08 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------



[03/14] git commit: Merge branch 1.4.5-SNAP into 1.5.1-SNAP (-sours)

Posted by ec...@apache.org.
Merge branch 1.4.5-SNAP into 1.5.1-SNAP (-sours)


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/a78246d3
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/a78246d3
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/a78246d3

Branch: refs/heads/master
Commit: a78246d37e3501501daf2d2b36524b1ff795bb43
Parents: c84acfc f56e9c6
Author: Mike Drob <md...@cloudera.com>
Authored: Tue Dec 17 09:17:36 2013 -0800
Committer: Mike Drob <md...@cloudera.com>
Committed: Tue Dec 17 09:17:36 2013 -0800

----------------------------------------------------------------------

----------------------------------------------------------------------



[02/14] git commit: ACCUMULO-2015 clean up role files for standalone

Posted by ec...@apache.org.
ACCUMULO-2015 clean up role files for standalone

Add checks for gc and tracers file existance in start-* scripts, since
these files are recommended but not required for cluster operation


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/f56e9c6b
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/f56e9c6b
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/f56e9c6b

Branch: refs/heads/master
Commit: f56e9c6bdc1cc021f8073bd2b27bd59b0f159ebc
Parents: 335f693
Author: Mike Drob <md...@cloudera.com>
Authored: Tue Dec 17 09:15:33 2013 -0800
Committer: Mike Drob <md...@cloudera.com>
Committed: Tue Dec 17 09:15:33 2013 -0800

----------------------------------------------------------------------
 bin/config.sh     | 10 ++--------
 bin/start-all.sh  | 14 +++++++++++--
 bin/start-here.sh | 54 +++++++++++++++++++++++++++++++++++---------------
 3 files changed, 52 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/f56e9c6b/bin/config.sh
----------------------------------------------------------------------
diff --git a/bin/config.sh b/bin/config.sh
index 89685fb..8d0672c 100755
--- a/bin/config.sh
+++ b/bin/config.sh
@@ -114,6 +114,8 @@ if [ -z "${ACCUMULO_VERIFY_ONLY}" ] ; then
           echo `hostname` > "$ACCUMULO_CONF_DIR/masters"
           echo "STANDALONE: echo "`hostname`" > $ACCUMULO_CONF_DIR/slaves"
           echo `hostname` > "$ACCUMULO_CONF_DIR/slaves"
+          echo "STANDALONE: echo "`hostname`" > $ACCUMULO_CONF_DIR/monitor"
+          echo `hostname` > "$ACCUMULO_CONF_DIR/monitor"
           fgrep -s logger.dir.walog "$ACCUMULO_CONF_DIR/accumulo-site.xml" > /dev/null
           WALOG_CONFIGURED=$?
           if [ $WALOG_CONFIGURED -ne 0 -a ! -e "$ACCUMULO_HOME/walogs" ]
@@ -145,14 +147,6 @@ if [ -z "${MONITOR}" ] ; then
     exit 1
   fi
 fi
-if [ ! -f "$ACCUMULO_CONF_DIR/tracers" -a -z "${ACCUMULO_VERIFY_ONLY}" ]; then
-  if [ -z "${MASTER1}" ] ; then
-    echo "Could not find a master node to use as a default for the tracer role. Either set up \"${ACCUMULO_CONF_DIR}/tracers\" or make sure \"${ACCUMULO_CONF_DIR}/masters\" is non-empty."
-    exit 1
-  else
-    echo "$MASTER1" > "$ACCUMULO_CONF_DIR/tracers"
-  fi
-fi
 
 SSH='ssh -qnf -o ConnectTimeout=2'
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/f56e9c6b/bin/start-all.sh
----------------------------------------------------------------------
diff --git a/bin/start-all.sh b/bin/start-all.sh
index e0d4b36..60cf9c3 100755
--- a/bin/start-all.sh
+++ b/bin/start-all.sh
@@ -62,14 +62,24 @@ do
     ${bin}/start-server.sh $master master
 done
 
-for gc in `grep -v '^#' "$ACCUMULO_CONF_DIR/gc"`
+if [[ -r $ACCUMULO_CONF_DIR/gc ]]; then
+    GC=`grep -v '^#' "$ACCUMULO_CONF_DIR/gc"`
+else
+    GC=$MASTER1
+fi
+for gc in "$GC"
 do
     ${bin}/start-server.sh $gc gc "garbage collector"
 done
 
 ${bin}/start-server.sh $MONITOR monitor 
 
-for tracer in `grep -v '^#' "$ACCUMULO_CONF_DIR/tracers"`
+if [[ -r $ACCUMULO_CONF_DIR/tracers ]]; then
+    TRACERS=`grep -v '^#' "$ACCUMULO_CONF_DIR/tracers"`
+else
+    TRACERS=$MASTER1
+fi
+for tracer in "$TRACERS"
 do
    ${bin}/start-server.sh $tracer tracer
 done

http://git-wip-us.apache.org/repos/asf/accumulo/blob/f56e9c6b/bin/start-here.sh
----------------------------------------------------------------------
diff --git a/bin/start-here.sh b/bin/start-here.sh
index 990fb1c..e571b8c 100755
--- a/bin/start-here.sh
+++ b/bin/start-here.sh
@@ -45,14 +45,25 @@ do
     fi
 done
 
-for host in $HOSTS
-do
-    if grep -q "^${host}\$" $ACCUMULO_CONF_DIR/gc
-    then
-	${bin}/start-server.sh $host gc "garbage collector"
-	break
-    fi
-done
+if [[ -r $ACCUMULO_CONF_DIR/gc ]]; then
+    for host in $HOSTS
+    do
+        if grep -q "^${host}\$" $ACCUMULO_CONF_DIR/gc
+        then
+            ${bin}/start-server.sh $host gc "garbage collector"
+            break
+        fi
+    done
+else
+    for host in $HOSTS
+    do
+        if [[ "$host" == "$MASTER1" ]]
+        then
+            ${bin}/start-server.sh $host gc "garbage collector"
+            break
+        fi
+    done
+fi
 
 for host in $HOSTS
 do
@@ -63,11 +74,22 @@ do
     fi
 done
 
-for host in $HOSTS
-do
-    if grep -q "^${host}\$" $ACCUMULO_CONF_DIR/tracers
-    then
-	${bin}/start-server.sh $host tracer 
-	break
-    fi
-done
+if [[ -r $ACCUMULO_CONF_DIR/tracers ]]; then
+    for host in $HOSTS
+    do
+        if grep -q "^${host}\$" $ACCUMULO_CONF_DIR/tracers
+        then
+            ${bin}/start-server.sh $host tracer
+            break
+        fi
+    done
+else
+    for host in $HOSTS
+    do
+        if [[ "$host" == "$MASTER1" ]]
+        then
+            ${bin}/start-server.sh $host tracer
+            break
+        fi
+    done
+fi


[12/14] git commit: ACCUMULO-2037 master is not fetching last location from the metadata table

Posted by ec...@apache.org.
ACCUMULO-2037 master is not fetching last location from the metadata table


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/44a91663
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/44a91663
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/44a91663

Branch: refs/heads/master
Commit: 44a91663652e96f35de6b5e6c73090d4c6c29d35
Parents: f37342b 3458bfa
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:03:42 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:03:42 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/44a91663/server/base/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
----------------------------------------------------------------------
diff --cc server/base/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
index f1c934a,0000000..0d8f572
mode 100644,000000..100644
--- a/server/base/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
@@@ -1,199 -1,0 +1,200 @@@
 +/*
 + * 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.accumulo.server.master.state;
 +
 +import java.io.IOException;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map.Entry;
 +import java.util.SortedMap;
 +
 +import org.apache.accumulo.core.client.BatchScanner;
 +import org.apache.accumulo.core.client.Connector;
 +import org.apache.accumulo.core.client.Instance;
 +import org.apache.accumulo.core.client.IteratorSetting;
 +import org.apache.accumulo.core.client.ScannerBase;
 +import org.apache.accumulo.core.data.Key;
 +import org.apache.accumulo.core.data.KeyExtent;
 +import org.apache.accumulo.core.data.Range;
 +import org.apache.accumulo.core.data.Value;
 +import org.apache.accumulo.core.iterators.user.WholeRowIterator;
 +import org.apache.accumulo.core.metadata.MetadataTable;
 +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection;
 +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ChoppedColumnFamily;
 +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.LogColumnFamily;
 +import org.apache.accumulo.core.security.Authorizations;
 +import org.apache.accumulo.core.security.Credentials;
 +import org.apache.accumulo.server.master.state.TabletLocationState.BadLocationStateException;
 +import org.apache.hadoop.io.Text;
 +import org.apache.log4j.Logger;
 +
 +public class MetaDataTableScanner implements Iterator<TabletLocationState> {
 +  private static final Logger log = Logger.getLogger(MetaDataTableScanner.class);
 +  
 +  BatchScanner mdScanner = null;
 +  Iterator<Entry<Key,Value>> iter = null;
 +  
 +  public MetaDataTableScanner(Instance instance, Credentials credentials, Range range, CurrentState state) {
 +    this(instance, credentials, range, state, MetadataTable.NAME);
 +  }
 +  
 +  MetaDataTableScanner(Instance instance, Credentials credentials, Range range, CurrentState state, String tableName) {
 +    // scan over metadata table, looking for tablets in the wrong state based on the live servers and online tables
 +    try {
 +      Connector connector = instance.getConnector(credentials.getPrincipal(), credentials.getToken());
 +      mdScanner = connector.createBatchScanner(tableName, Authorizations.EMPTY, 8);
 +      configureScanner(mdScanner, state);
 +      mdScanner.setRanges(Collections.singletonList(range));
 +      iter = mdScanner.iterator();
 +    } catch (Exception ex) {
 +      if (mdScanner != null)
 +        mdScanner.close();
 +      iter = null;
 +      mdScanner = null;
 +      throw new RuntimeException(ex);
 +    }
 +  }
 +  
 +  static public void configureScanner(ScannerBase scanner, CurrentState state) {
 +    TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
 +    scanner.fetchColumnFamily(TabletsSection.CurrentLocationColumnFamily.NAME);
 +    scanner.fetchColumnFamily(TabletsSection.FutureLocationColumnFamily.NAME);
++    scanner.fetchColumnFamily(TabletsSection.LastLocationColumnFamily.NAME);
 +    scanner.fetchColumnFamily(LogColumnFamily.NAME);
 +    scanner.fetchColumnFamily(ChoppedColumnFamily.NAME);
 +    scanner.addScanIterator(new IteratorSetting(1000, "wholeRows", WholeRowIterator.class));
 +    IteratorSetting tabletChange = new IteratorSetting(1001, "tabletChange", TabletStateChangeIterator.class);
 +    if (state != null) {
 +      TabletStateChangeIterator.setCurrentServers(tabletChange, state.onlineTabletServers());
 +      TabletStateChangeIterator.setOnlineTables(tabletChange, state.onlineTables());
 +      TabletStateChangeIterator.setMerges(tabletChange, state.merges());
 +    }
 +    scanner.addScanIterator(tabletChange);
 +  }
 +  
 +  public MetaDataTableScanner(Instance instance, Credentials credentials, Range range) {
 +    this(instance, credentials, range, MetadataTable.NAME);
 +  }
 +  
 +  public MetaDataTableScanner(Instance instance, Credentials credentials, Range range, String tableName) {
 +    this(instance, credentials, range, null, tableName);
 +  }
 +  
 +  public void close() {
 +    if (iter != null) {
 +      mdScanner.close();
 +      iter = null;
 +    }
 +  }
 +  
 +  @Override
 +  public void finalize() {
 +    close();
 +  }
 +  
 +  @Override
 +  public boolean hasNext() {
 +    if (iter == null)
 +      return false;
 +    boolean result = iter.hasNext();
 +    if (!result) {
 +      close();
 +    }
 +    return result;
 +  }
 +  
 +  @Override
 +  public TabletLocationState next() {
 +    try {
 +      return fetch();
 +    } catch (RuntimeException ex) {
 +      // something is wrong with the metadata records, just skip over it
 +      log.error(ex, ex);
 +      mdScanner.close();
 +      return null;
 +    }
 +  }
 +  
 +  public static TabletLocationState createTabletLocationState(Key k, Value v) throws IOException, BadLocationStateException {
 +    final SortedMap<Key,Value> decodedRow = WholeRowIterator.decodeRow(k, v);
 +    KeyExtent extent = null;
 +    TServerInstance future = null;
 +    TServerInstance current = null;
 +    TServerInstance last = null;
 +    List<Collection<String>> walogs = new ArrayList<Collection<String>>();
 +    boolean chopped = false;
 +    
 +    for (Entry<Key,Value> entry : decodedRow.entrySet()) {
 +      Key key = entry.getKey();
 +      Text row = key.getRow();
 +      Text cf = key.getColumnFamily();
 +      Text cq = key.getColumnQualifier();
 +      
 +      if (cf.compareTo(TabletsSection.FutureLocationColumnFamily.NAME) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (future != null) {
 +          throw new BadLocationStateException("found two assignments for the same extent " + key.getRow() + ": " + future + " and " + location);
 +        }
 +        future = location;
 +      } else if (cf.compareTo(TabletsSection.CurrentLocationColumnFamily.NAME) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (current != null) {
 +          throw new BadLocationStateException("found two locations for the same extent " + key.getRow() + ": " + current + " and " + location);
 +        }
 +        current = location;
 +      } else if (cf.compareTo(LogColumnFamily.NAME) == 0) {
 +        String[] split = entry.getValue().toString().split("\\|")[0].split(";");
 +        walogs.add(Arrays.asList(split));
 +      } else if (cf.compareTo(TabletsSection.LastLocationColumnFamily.NAME) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (last != null) {
 +          throw new BadLocationStateException("found two last locations for the same extent " + key.getRow() + ": " + last + " and " + location);
 +        }
 +        last = new TServerInstance(entry.getValue(), cq);
 +      } else if (cf.compareTo(ChoppedColumnFamily.NAME) == 0) {
 +        chopped = true;
 +      } else if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.equals(cf, cq)) {
 +        extent = new KeyExtent(row, entry.getValue());
 +      }
 +    }
 +    if (extent == null) {
 +      log.warn("No prev-row for key extent: " + decodedRow);
 +      return null;
 +    }
 +    return new TabletLocationState(extent, future, current, last, walogs, chopped);
 +  }
 +  
 +  private TabletLocationState fetch() {
 +    try {
 +      Entry<Key,Value> e = iter.next();
 +      return createTabletLocationState(e.getKey(), e.getValue());
 +    } catch (IOException ex) {
 +      throw new RuntimeException(ex);
 +    } catch (BadLocationStateException ex) {
 +      throw new RuntimeException(ex);
 +    }
 +  }
 +  
 +  @Override
 +  public void remove() {
 +    throw new RuntimeException("Unimplemented");
 +  }
 +}


[09/14] git commit: Merge branch '1.4.5-SNAPSHOT' into 1.5.1-SNAPSHOT

Posted by ec...@apache.org.
Merge branch '1.4.5-SNAPSHOT' into 1.5.1-SNAPSHOT


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/3458bfae
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/3458bfae
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/3458bfae

Branch: refs/heads/master
Commit: 3458bfaec1ada8a164e596ac132939e370e52f86
Parents: a78246d 59932f6
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:02:33 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:02:33 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/3458bfae/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
----------------------------------------------------------------------
diff --cc server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
index 7570908,0000000..bf1da22
mode 100644,000000..100644
--- a/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
+++ b/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
@@@ -1,184 -1,0 +1,185 @@@
 +/*
 + * 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.accumulo.server.master.state;
 +
 +import java.io.IOException;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map.Entry;
 +import java.util.SortedMap;
 +
 +import org.apache.accumulo.core.Constants;
 +import org.apache.accumulo.core.client.BatchScanner;
 +import org.apache.accumulo.core.client.Connector;
 +import org.apache.accumulo.core.client.Instance;
 +import org.apache.accumulo.core.client.IteratorSetting;
 +import org.apache.accumulo.core.client.ScannerBase;
 +import org.apache.accumulo.core.data.Key;
 +import org.apache.accumulo.core.data.KeyExtent;
 +import org.apache.accumulo.core.data.Range;
 +import org.apache.accumulo.core.data.Value;
 +import org.apache.accumulo.core.iterators.user.WholeRowIterator;
 +import org.apache.accumulo.core.security.CredentialHelper;
 +import org.apache.accumulo.core.security.thrift.TCredentials;
 +import org.apache.accumulo.server.master.state.TabletLocationState.BadLocationStateException;
 +import org.apache.hadoop.io.Text;
 +import org.apache.log4j.Logger;
 +
 +public class MetaDataTableScanner implements Iterator<TabletLocationState> {
 +  private static final Logger log = Logger.getLogger(MetaDataTableScanner.class);
 +  
 +  BatchScanner mdScanner;
 +  Iterator<Entry<Key,Value>> iter;
 +  
 +  public MetaDataTableScanner(Instance instance, TCredentials auths, Range range, CurrentState state) {
 +    // scan over metadata table, looking for tablets in the wrong state based on the live servers and online tables
 +    try {
 +      Connector connector = instance.getConnector(auths.getPrincipal(), CredentialHelper.extractToken(auths));
 +      mdScanner = connector.createBatchScanner(Constants.METADATA_TABLE_NAME, Constants.NO_AUTHS, 8);
 +      configureScanner(mdScanner, state);
 +      mdScanner.setRanges(Collections.singletonList(range));
 +      iter = mdScanner.iterator();
 +    } catch (Exception ex) {
 +      mdScanner.close();
 +      throw new RuntimeException(ex);
 +    }
 +  }
 +
 +  static public void configureScanner(ScannerBase scanner, CurrentState state) {
 +    Constants.METADATA_PREV_ROW_COLUMN.fetch(scanner);
 +    scanner.fetchColumnFamily(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY);
 +    scanner.fetchColumnFamily(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY);
++    scanner.fetchColumnFamily(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY);
 +    scanner.fetchColumnFamily(Constants.METADATA_LOG_COLUMN_FAMILY);
 +    scanner.fetchColumnFamily(Constants.METADATA_CHOPPED_COLUMN_FAMILY);
 +    scanner.addScanIterator(new IteratorSetting(1000, "wholeRows", WholeRowIterator.class));
 +    IteratorSetting tabletChange = new IteratorSetting(1001, "tabletChange", TabletStateChangeIterator.class);
 +    if (state != null) {
 +      TabletStateChangeIterator.setCurrentServers(tabletChange, state.onlineTabletServers());
 +      TabletStateChangeIterator.setOnlineTables(tabletChange, state.onlineTables());
 +      TabletStateChangeIterator.setMerges(tabletChange, state.merges());
 +    }
 +    scanner.addScanIterator(tabletChange);
 +  }
 +  
 +  public MetaDataTableScanner(Instance instance, TCredentials auths, Range range) {
 +    this(instance, auths, range, null);
 +  }
 +  
 +  public void close() {
 +    if (iter != null) {
 +      mdScanner.close();
 +      iter = null;
 +    }
 +  }
 +  
 +  public void finalize() {
 +    close();
 +  }
 +  
 +  @Override
 +  public boolean hasNext() {
 +    if (iter == null)
 +      return false;
 +    boolean result = iter.hasNext();
 +    if (!result) {
 +      close();
 +    }
 +    return result;
 +  }
 +  
 +  @Override
 +  public TabletLocationState next() {
 +    try {
 +      return fetch();
 +    } catch (RuntimeException ex) {
 +      // something is wrong with the records in the !METADATA table, just skip over it
 +      log.error(ex, ex);
 +      mdScanner.close();
 +      return null;
 +    } 
 +  }
 +  
 +  public static TabletLocationState createTabletLocationState(Key k, Value v) throws IOException, BadLocationStateException {
 +    final SortedMap<Key,Value> decodedRow = WholeRowIterator.decodeRow(k, v);
 +    KeyExtent extent = null;
 +    TServerInstance future = null;
 +    TServerInstance current = null;
 +    TServerInstance last = null;
 +    List<Collection<String>> walogs = new ArrayList<Collection<String>>();
 +    boolean chopped = false;
 +    
 +    for (Entry<Key,Value> entry : decodedRow.entrySet()) {
 +      Key key = entry.getKey();
 +      Text row = key.getRow();
 +      Text cf = key.getColumnFamily();
 +      Text cq = key.getColumnQualifier();
 +      
 +      if (cf.compareTo(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (future != null) {
 +          throw new BadLocationStateException("found two assignments for the same extent " + key.getRow() + ": " + future + " and " + location);
 +        }
 +        future = location;
 +      } else if (cf.compareTo(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (current != null) {
 +          throw new BadLocationStateException("found two locations for the same extent " + key.getRow() + ": " + current + " and " + location);
 +        }
 +        current = location;
 +      } else if (cf.compareTo(Constants.METADATA_LOG_COLUMN_FAMILY) == 0) {
 +        String[] split = entry.getValue().toString().split("\\|")[0].split(";");
 +        walogs.add(Arrays.asList(split));
 +      } else if (cf.compareTo(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (last != null) {
 +          throw new BadLocationStateException("found two last locations for the same extent " + key.getRow() + ": " + last + " and " + location);
 +        }
 +        last = new TServerInstance(entry.getValue(), cq);
 +      } else if (cf.compareTo(Constants.METADATA_CHOPPED_COLUMN_FAMILY) == 0) {
 +        chopped = true;
 +      } else if (Constants.METADATA_PREV_ROW_COLUMN.equals(cf, cq)) {
 +        extent = new KeyExtent(row, entry.getValue());
 +      }
 +    }
 +    if (extent == null) {
 +      log.warn("No prev-row for key extent: " + decodedRow);
 +      return null;
 +    }
 +    return new TabletLocationState(extent, future, current, last, walogs, chopped);
 +  }
 +  
 +  private TabletLocationState fetch() {
 +    try {
 +      Entry<Key,Value> e = iter.next();
 +      return createTabletLocationState(e.getKey(), e.getValue());
 +    } catch (IOException ex) {
 +      throw new RuntimeException(ex);
 +    } catch (BadLocationStateException ex) {
 +      throw new RuntimeException(ex);
 +    } 
 +  }
 +  
 +  @Override
 +  public void remove() {
 +    throw new RuntimeException("Unimplemented");
 +  }
 +}


[04/14] git commit: Merge branch 1.4.5-SNAP into 1.5.1-SNAP (-sours)

Posted by ec...@apache.org.
Merge branch 1.4.5-SNAP into 1.5.1-SNAP (-sours)


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/a78246d3
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/a78246d3
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/a78246d3

Branch: refs/heads/1.6.0-SNAPSHOT
Commit: a78246d37e3501501daf2d2b36524b1ff795bb43
Parents: c84acfc f56e9c6
Author: Mike Drob <md...@cloudera.com>
Authored: Tue Dec 17 09:17:36 2013 -0800
Committer: Mike Drob <md...@cloudera.com>
Committed: Tue Dec 17 09:17:36 2013 -0800

----------------------------------------------------------------------

----------------------------------------------------------------------



[10/14] git commit: Merge branch '1.4.5-SNAPSHOT' into 1.5.1-SNAPSHOT

Posted by ec...@apache.org.
Merge branch '1.4.5-SNAPSHOT' into 1.5.1-SNAPSHOT


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/3458bfae
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/3458bfae
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/3458bfae

Branch: refs/heads/1.6.0-SNAPSHOT
Commit: 3458bfaec1ada8a164e596ac132939e370e52f86
Parents: a78246d 59932f6
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:02:33 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:02:33 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/3458bfae/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
----------------------------------------------------------------------
diff --cc server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
index 7570908,0000000..bf1da22
mode 100644,000000..100644
--- a/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
+++ b/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
@@@ -1,184 -1,0 +1,185 @@@
 +/*
 + * 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.accumulo.server.master.state;
 +
 +import java.io.IOException;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map.Entry;
 +import java.util.SortedMap;
 +
 +import org.apache.accumulo.core.Constants;
 +import org.apache.accumulo.core.client.BatchScanner;
 +import org.apache.accumulo.core.client.Connector;
 +import org.apache.accumulo.core.client.Instance;
 +import org.apache.accumulo.core.client.IteratorSetting;
 +import org.apache.accumulo.core.client.ScannerBase;
 +import org.apache.accumulo.core.data.Key;
 +import org.apache.accumulo.core.data.KeyExtent;
 +import org.apache.accumulo.core.data.Range;
 +import org.apache.accumulo.core.data.Value;
 +import org.apache.accumulo.core.iterators.user.WholeRowIterator;
 +import org.apache.accumulo.core.security.CredentialHelper;
 +import org.apache.accumulo.core.security.thrift.TCredentials;
 +import org.apache.accumulo.server.master.state.TabletLocationState.BadLocationStateException;
 +import org.apache.hadoop.io.Text;
 +import org.apache.log4j.Logger;
 +
 +public class MetaDataTableScanner implements Iterator<TabletLocationState> {
 +  private static final Logger log = Logger.getLogger(MetaDataTableScanner.class);
 +  
 +  BatchScanner mdScanner;
 +  Iterator<Entry<Key,Value>> iter;
 +  
 +  public MetaDataTableScanner(Instance instance, TCredentials auths, Range range, CurrentState state) {
 +    // scan over metadata table, looking for tablets in the wrong state based on the live servers and online tables
 +    try {
 +      Connector connector = instance.getConnector(auths.getPrincipal(), CredentialHelper.extractToken(auths));
 +      mdScanner = connector.createBatchScanner(Constants.METADATA_TABLE_NAME, Constants.NO_AUTHS, 8);
 +      configureScanner(mdScanner, state);
 +      mdScanner.setRanges(Collections.singletonList(range));
 +      iter = mdScanner.iterator();
 +    } catch (Exception ex) {
 +      mdScanner.close();
 +      throw new RuntimeException(ex);
 +    }
 +  }
 +
 +  static public void configureScanner(ScannerBase scanner, CurrentState state) {
 +    Constants.METADATA_PREV_ROW_COLUMN.fetch(scanner);
 +    scanner.fetchColumnFamily(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY);
 +    scanner.fetchColumnFamily(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY);
++    scanner.fetchColumnFamily(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY);
 +    scanner.fetchColumnFamily(Constants.METADATA_LOG_COLUMN_FAMILY);
 +    scanner.fetchColumnFamily(Constants.METADATA_CHOPPED_COLUMN_FAMILY);
 +    scanner.addScanIterator(new IteratorSetting(1000, "wholeRows", WholeRowIterator.class));
 +    IteratorSetting tabletChange = new IteratorSetting(1001, "tabletChange", TabletStateChangeIterator.class);
 +    if (state != null) {
 +      TabletStateChangeIterator.setCurrentServers(tabletChange, state.onlineTabletServers());
 +      TabletStateChangeIterator.setOnlineTables(tabletChange, state.onlineTables());
 +      TabletStateChangeIterator.setMerges(tabletChange, state.merges());
 +    }
 +    scanner.addScanIterator(tabletChange);
 +  }
 +  
 +  public MetaDataTableScanner(Instance instance, TCredentials auths, Range range) {
 +    this(instance, auths, range, null);
 +  }
 +  
 +  public void close() {
 +    if (iter != null) {
 +      mdScanner.close();
 +      iter = null;
 +    }
 +  }
 +  
 +  public void finalize() {
 +    close();
 +  }
 +  
 +  @Override
 +  public boolean hasNext() {
 +    if (iter == null)
 +      return false;
 +    boolean result = iter.hasNext();
 +    if (!result) {
 +      close();
 +    }
 +    return result;
 +  }
 +  
 +  @Override
 +  public TabletLocationState next() {
 +    try {
 +      return fetch();
 +    } catch (RuntimeException ex) {
 +      // something is wrong with the records in the !METADATA table, just skip over it
 +      log.error(ex, ex);
 +      mdScanner.close();
 +      return null;
 +    } 
 +  }
 +  
 +  public static TabletLocationState createTabletLocationState(Key k, Value v) throws IOException, BadLocationStateException {
 +    final SortedMap<Key,Value> decodedRow = WholeRowIterator.decodeRow(k, v);
 +    KeyExtent extent = null;
 +    TServerInstance future = null;
 +    TServerInstance current = null;
 +    TServerInstance last = null;
 +    List<Collection<String>> walogs = new ArrayList<Collection<String>>();
 +    boolean chopped = false;
 +    
 +    for (Entry<Key,Value> entry : decodedRow.entrySet()) {
 +      Key key = entry.getKey();
 +      Text row = key.getRow();
 +      Text cf = key.getColumnFamily();
 +      Text cq = key.getColumnQualifier();
 +      
 +      if (cf.compareTo(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (future != null) {
 +          throw new BadLocationStateException("found two assignments for the same extent " + key.getRow() + ": " + future + " and " + location);
 +        }
 +        future = location;
 +      } else if (cf.compareTo(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (current != null) {
 +          throw new BadLocationStateException("found two locations for the same extent " + key.getRow() + ": " + current + " and " + location);
 +        }
 +        current = location;
 +      } else if (cf.compareTo(Constants.METADATA_LOG_COLUMN_FAMILY) == 0) {
 +        String[] split = entry.getValue().toString().split("\\|")[0].split(";");
 +        walogs.add(Arrays.asList(split));
 +      } else if (cf.compareTo(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (last != null) {
 +          throw new BadLocationStateException("found two last locations for the same extent " + key.getRow() + ": " + last + " and " + location);
 +        }
 +        last = new TServerInstance(entry.getValue(), cq);
 +      } else if (cf.compareTo(Constants.METADATA_CHOPPED_COLUMN_FAMILY) == 0) {
 +        chopped = true;
 +      } else if (Constants.METADATA_PREV_ROW_COLUMN.equals(cf, cq)) {
 +        extent = new KeyExtent(row, entry.getValue());
 +      }
 +    }
 +    if (extent == null) {
 +      log.warn("No prev-row for key extent: " + decodedRow);
 +      return null;
 +    }
 +    return new TabletLocationState(extent, future, current, last, walogs, chopped);
 +  }
 +  
 +  private TabletLocationState fetch() {
 +    try {
 +      Entry<Key,Value> e = iter.next();
 +      return createTabletLocationState(e.getKey(), e.getValue());
 +    } catch (IOException ex) {
 +      throw new RuntimeException(ex);
 +    } catch (BadLocationStateException ex) {
 +      throw new RuntimeException(ex);
 +    } 
 +  }
 +  
 +  @Override
 +  public void remove() {
 +    throw new RuntimeException("Unimplemented");
 +  }
 +}


[05/14] git commit: ACCUMULO-2037 master is not fetching last location from the metadata table

Posted by ec...@apache.org.
ACCUMULO-2037 master is not fetching last location from the metadata table


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/59932f6d
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/59932f6d
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/59932f6d

Branch: refs/heads/1.5.1-SNAPSHOT
Commit: 59932f6d273067faaf9639ef4b632f67587bf5ad
Parents: f56e9c6
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:02:05 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:02:05 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/59932f6d/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
----------------------------------------------------------------------
diff --git a/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java b/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
index dd28cb6..e10b1b3 100644
--- a/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
+++ b/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
@@ -68,6 +68,7 @@ public class MetaDataTableScanner implements Iterator<TabletLocationState> {
     ColumnFQ.fetch(scanner, Constants.METADATA_PREV_ROW_COLUMN);
     scanner.fetchColumnFamily(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY);
+    scanner.fetchColumnFamily(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_LOG_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_CHOPPED_COLUMN_FAMILY);
     scanner.addScanIterator(new IteratorSetting(1000, "wholeRows", WholeRowIterator.class));


[06/14] git commit: ACCUMULO-2037 master is not fetching last location from the metadata table

Posted by ec...@apache.org.
ACCUMULO-2037 master is not fetching last location from the metadata table


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/59932f6d
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/59932f6d
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/59932f6d

Branch: refs/heads/1.6.0-SNAPSHOT
Commit: 59932f6d273067faaf9639ef4b632f67587bf5ad
Parents: f56e9c6
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:02:05 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:02:05 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/59932f6d/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
----------------------------------------------------------------------
diff --git a/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java b/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
index dd28cb6..e10b1b3 100644
--- a/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
+++ b/src/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
@@ -68,6 +68,7 @@ public class MetaDataTableScanner implements Iterator<TabletLocationState> {
     ColumnFQ.fetch(scanner, Constants.METADATA_PREV_ROW_COLUMN);
     scanner.fetchColumnFamily(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY);
+    scanner.fetchColumnFamily(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_LOG_COLUMN_FAMILY);
     scanner.fetchColumnFamily(Constants.METADATA_CHOPPED_COLUMN_FAMILY);
     scanner.addScanIterator(new IteratorSetting(1000, "wholeRows", WholeRowIterator.class));


[13/14] git commit: ACCUMULO-2037 master is not fetching last location from the metadata table

Posted by ec...@apache.org.
ACCUMULO-2037 master is not fetching last location from the metadata table


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/44a91663
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/44a91663
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/44a91663

Branch: refs/heads/1.6.0-SNAPSHOT
Commit: 44a91663652e96f35de6b5e6c73090d4c6c29d35
Parents: f37342b 3458bfa
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:03:42 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:03:42 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/44a91663/server/base/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
----------------------------------------------------------------------
diff --cc server/base/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
index f1c934a,0000000..0d8f572
mode 100644,000000..100644
--- a/server/base/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
@@@ -1,199 -1,0 +1,200 @@@
 +/*
 + * 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.accumulo.server.master.state;
 +
 +import java.io.IOException;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map.Entry;
 +import java.util.SortedMap;
 +
 +import org.apache.accumulo.core.client.BatchScanner;
 +import org.apache.accumulo.core.client.Connector;
 +import org.apache.accumulo.core.client.Instance;
 +import org.apache.accumulo.core.client.IteratorSetting;
 +import org.apache.accumulo.core.client.ScannerBase;
 +import org.apache.accumulo.core.data.Key;
 +import org.apache.accumulo.core.data.KeyExtent;
 +import org.apache.accumulo.core.data.Range;
 +import org.apache.accumulo.core.data.Value;
 +import org.apache.accumulo.core.iterators.user.WholeRowIterator;
 +import org.apache.accumulo.core.metadata.MetadataTable;
 +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection;
 +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ChoppedColumnFamily;
 +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.LogColumnFamily;
 +import org.apache.accumulo.core.security.Authorizations;
 +import org.apache.accumulo.core.security.Credentials;
 +import org.apache.accumulo.server.master.state.TabletLocationState.BadLocationStateException;
 +import org.apache.hadoop.io.Text;
 +import org.apache.log4j.Logger;
 +
 +public class MetaDataTableScanner implements Iterator<TabletLocationState> {
 +  private static final Logger log = Logger.getLogger(MetaDataTableScanner.class);
 +  
 +  BatchScanner mdScanner = null;
 +  Iterator<Entry<Key,Value>> iter = null;
 +  
 +  public MetaDataTableScanner(Instance instance, Credentials credentials, Range range, CurrentState state) {
 +    this(instance, credentials, range, state, MetadataTable.NAME);
 +  }
 +  
 +  MetaDataTableScanner(Instance instance, Credentials credentials, Range range, CurrentState state, String tableName) {
 +    // scan over metadata table, looking for tablets in the wrong state based on the live servers and online tables
 +    try {
 +      Connector connector = instance.getConnector(credentials.getPrincipal(), credentials.getToken());
 +      mdScanner = connector.createBatchScanner(tableName, Authorizations.EMPTY, 8);
 +      configureScanner(mdScanner, state);
 +      mdScanner.setRanges(Collections.singletonList(range));
 +      iter = mdScanner.iterator();
 +    } catch (Exception ex) {
 +      if (mdScanner != null)
 +        mdScanner.close();
 +      iter = null;
 +      mdScanner = null;
 +      throw new RuntimeException(ex);
 +    }
 +  }
 +  
 +  static public void configureScanner(ScannerBase scanner, CurrentState state) {
 +    TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.fetch(scanner);
 +    scanner.fetchColumnFamily(TabletsSection.CurrentLocationColumnFamily.NAME);
 +    scanner.fetchColumnFamily(TabletsSection.FutureLocationColumnFamily.NAME);
++    scanner.fetchColumnFamily(TabletsSection.LastLocationColumnFamily.NAME);
 +    scanner.fetchColumnFamily(LogColumnFamily.NAME);
 +    scanner.fetchColumnFamily(ChoppedColumnFamily.NAME);
 +    scanner.addScanIterator(new IteratorSetting(1000, "wholeRows", WholeRowIterator.class));
 +    IteratorSetting tabletChange = new IteratorSetting(1001, "tabletChange", TabletStateChangeIterator.class);
 +    if (state != null) {
 +      TabletStateChangeIterator.setCurrentServers(tabletChange, state.onlineTabletServers());
 +      TabletStateChangeIterator.setOnlineTables(tabletChange, state.onlineTables());
 +      TabletStateChangeIterator.setMerges(tabletChange, state.merges());
 +    }
 +    scanner.addScanIterator(tabletChange);
 +  }
 +  
 +  public MetaDataTableScanner(Instance instance, Credentials credentials, Range range) {
 +    this(instance, credentials, range, MetadataTable.NAME);
 +  }
 +  
 +  public MetaDataTableScanner(Instance instance, Credentials credentials, Range range, String tableName) {
 +    this(instance, credentials, range, null, tableName);
 +  }
 +  
 +  public void close() {
 +    if (iter != null) {
 +      mdScanner.close();
 +      iter = null;
 +    }
 +  }
 +  
 +  @Override
 +  public void finalize() {
 +    close();
 +  }
 +  
 +  @Override
 +  public boolean hasNext() {
 +    if (iter == null)
 +      return false;
 +    boolean result = iter.hasNext();
 +    if (!result) {
 +      close();
 +    }
 +    return result;
 +  }
 +  
 +  @Override
 +  public TabletLocationState next() {
 +    try {
 +      return fetch();
 +    } catch (RuntimeException ex) {
 +      // something is wrong with the metadata records, just skip over it
 +      log.error(ex, ex);
 +      mdScanner.close();
 +      return null;
 +    }
 +  }
 +  
 +  public static TabletLocationState createTabletLocationState(Key k, Value v) throws IOException, BadLocationStateException {
 +    final SortedMap<Key,Value> decodedRow = WholeRowIterator.decodeRow(k, v);
 +    KeyExtent extent = null;
 +    TServerInstance future = null;
 +    TServerInstance current = null;
 +    TServerInstance last = null;
 +    List<Collection<String>> walogs = new ArrayList<Collection<String>>();
 +    boolean chopped = false;
 +    
 +    for (Entry<Key,Value> entry : decodedRow.entrySet()) {
 +      Key key = entry.getKey();
 +      Text row = key.getRow();
 +      Text cf = key.getColumnFamily();
 +      Text cq = key.getColumnQualifier();
 +      
 +      if (cf.compareTo(TabletsSection.FutureLocationColumnFamily.NAME) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (future != null) {
 +          throw new BadLocationStateException("found two assignments for the same extent " + key.getRow() + ": " + future + " and " + location);
 +        }
 +        future = location;
 +      } else if (cf.compareTo(TabletsSection.CurrentLocationColumnFamily.NAME) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (current != null) {
 +          throw new BadLocationStateException("found two locations for the same extent " + key.getRow() + ": " + current + " and " + location);
 +        }
 +        current = location;
 +      } else if (cf.compareTo(LogColumnFamily.NAME) == 0) {
 +        String[] split = entry.getValue().toString().split("\\|")[0].split(";");
 +        walogs.add(Arrays.asList(split));
 +      } else if (cf.compareTo(TabletsSection.LastLocationColumnFamily.NAME) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (last != null) {
 +          throw new BadLocationStateException("found two last locations for the same extent " + key.getRow() + ": " + last + " and " + location);
 +        }
 +        last = new TServerInstance(entry.getValue(), cq);
 +      } else if (cf.compareTo(ChoppedColumnFamily.NAME) == 0) {
 +        chopped = true;
 +      } else if (TabletsSection.TabletColumnFamily.PREV_ROW_COLUMN.equals(cf, cq)) {
 +        extent = new KeyExtent(row, entry.getValue());
 +      }
 +    }
 +    if (extent == null) {
 +      log.warn("No prev-row for key extent: " + decodedRow);
 +      return null;
 +    }
 +    return new TabletLocationState(extent, future, current, last, walogs, chopped);
 +  }
 +  
 +  private TabletLocationState fetch() {
 +    try {
 +      Entry<Key,Value> e = iter.next();
 +      return createTabletLocationState(e.getKey(), e.getValue());
 +    } catch (IOException ex) {
 +      throw new RuntimeException(ex);
 +    } catch (BadLocationStateException ex) {
 +      throw new RuntimeException(ex);
 +    }
 +  }
 +  
 +  @Override
 +  public void remove() {
 +    throw new RuntimeException("Unimplemented");
 +  }
 +}


[11/14] git commit: Merge branch '1.4.5-SNAPSHOT' into 1.5.1-SNAPSHOT

Posted by ec...@apache.org.
Merge branch '1.4.5-SNAPSHOT' into 1.5.1-SNAPSHOT


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/3458bfae
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/3458bfae
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/3458bfae

Branch: refs/heads/1.5.1-SNAPSHOT
Commit: 3458bfaec1ada8a164e596ac132939e370e52f86
Parents: a78246d 59932f6
Author: Eric Newton <er...@gmail.com>
Authored: Tue Dec 17 14:02:33 2013 -0500
Committer: Eric Newton <er...@gmail.com>
Committed: Tue Dec 17 14:02:33 2013 -0500

----------------------------------------------------------------------
 .../apache/accumulo/server/master/state/MetaDataTableScanner.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/3458bfae/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
----------------------------------------------------------------------
diff --cc server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
index 7570908,0000000..bf1da22
mode 100644,000000..100644
--- a/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
+++ b/server/src/main/java/org/apache/accumulo/server/master/state/MetaDataTableScanner.java
@@@ -1,184 -1,0 +1,185 @@@
 +/*
 + * 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.accumulo.server.master.state;
 +
 +import java.io.IOException;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map.Entry;
 +import java.util.SortedMap;
 +
 +import org.apache.accumulo.core.Constants;
 +import org.apache.accumulo.core.client.BatchScanner;
 +import org.apache.accumulo.core.client.Connector;
 +import org.apache.accumulo.core.client.Instance;
 +import org.apache.accumulo.core.client.IteratorSetting;
 +import org.apache.accumulo.core.client.ScannerBase;
 +import org.apache.accumulo.core.data.Key;
 +import org.apache.accumulo.core.data.KeyExtent;
 +import org.apache.accumulo.core.data.Range;
 +import org.apache.accumulo.core.data.Value;
 +import org.apache.accumulo.core.iterators.user.WholeRowIterator;
 +import org.apache.accumulo.core.security.CredentialHelper;
 +import org.apache.accumulo.core.security.thrift.TCredentials;
 +import org.apache.accumulo.server.master.state.TabletLocationState.BadLocationStateException;
 +import org.apache.hadoop.io.Text;
 +import org.apache.log4j.Logger;
 +
 +public class MetaDataTableScanner implements Iterator<TabletLocationState> {
 +  private static final Logger log = Logger.getLogger(MetaDataTableScanner.class);
 +  
 +  BatchScanner mdScanner;
 +  Iterator<Entry<Key,Value>> iter;
 +  
 +  public MetaDataTableScanner(Instance instance, TCredentials auths, Range range, CurrentState state) {
 +    // scan over metadata table, looking for tablets in the wrong state based on the live servers and online tables
 +    try {
 +      Connector connector = instance.getConnector(auths.getPrincipal(), CredentialHelper.extractToken(auths));
 +      mdScanner = connector.createBatchScanner(Constants.METADATA_TABLE_NAME, Constants.NO_AUTHS, 8);
 +      configureScanner(mdScanner, state);
 +      mdScanner.setRanges(Collections.singletonList(range));
 +      iter = mdScanner.iterator();
 +    } catch (Exception ex) {
 +      mdScanner.close();
 +      throw new RuntimeException(ex);
 +    }
 +  }
 +
 +  static public void configureScanner(ScannerBase scanner, CurrentState state) {
 +    Constants.METADATA_PREV_ROW_COLUMN.fetch(scanner);
 +    scanner.fetchColumnFamily(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY);
 +    scanner.fetchColumnFamily(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY);
++    scanner.fetchColumnFamily(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY);
 +    scanner.fetchColumnFamily(Constants.METADATA_LOG_COLUMN_FAMILY);
 +    scanner.fetchColumnFamily(Constants.METADATA_CHOPPED_COLUMN_FAMILY);
 +    scanner.addScanIterator(new IteratorSetting(1000, "wholeRows", WholeRowIterator.class));
 +    IteratorSetting tabletChange = new IteratorSetting(1001, "tabletChange", TabletStateChangeIterator.class);
 +    if (state != null) {
 +      TabletStateChangeIterator.setCurrentServers(tabletChange, state.onlineTabletServers());
 +      TabletStateChangeIterator.setOnlineTables(tabletChange, state.onlineTables());
 +      TabletStateChangeIterator.setMerges(tabletChange, state.merges());
 +    }
 +    scanner.addScanIterator(tabletChange);
 +  }
 +  
 +  public MetaDataTableScanner(Instance instance, TCredentials auths, Range range) {
 +    this(instance, auths, range, null);
 +  }
 +  
 +  public void close() {
 +    if (iter != null) {
 +      mdScanner.close();
 +      iter = null;
 +    }
 +  }
 +  
 +  public void finalize() {
 +    close();
 +  }
 +  
 +  @Override
 +  public boolean hasNext() {
 +    if (iter == null)
 +      return false;
 +    boolean result = iter.hasNext();
 +    if (!result) {
 +      close();
 +    }
 +    return result;
 +  }
 +  
 +  @Override
 +  public TabletLocationState next() {
 +    try {
 +      return fetch();
 +    } catch (RuntimeException ex) {
 +      // something is wrong with the records in the !METADATA table, just skip over it
 +      log.error(ex, ex);
 +      mdScanner.close();
 +      return null;
 +    } 
 +  }
 +  
 +  public static TabletLocationState createTabletLocationState(Key k, Value v) throws IOException, BadLocationStateException {
 +    final SortedMap<Key,Value> decodedRow = WholeRowIterator.decodeRow(k, v);
 +    KeyExtent extent = null;
 +    TServerInstance future = null;
 +    TServerInstance current = null;
 +    TServerInstance last = null;
 +    List<Collection<String>> walogs = new ArrayList<Collection<String>>();
 +    boolean chopped = false;
 +    
 +    for (Entry<Key,Value> entry : decodedRow.entrySet()) {
 +      Key key = entry.getKey();
 +      Text row = key.getRow();
 +      Text cf = key.getColumnFamily();
 +      Text cq = key.getColumnQualifier();
 +      
 +      if (cf.compareTo(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (future != null) {
 +          throw new BadLocationStateException("found two assignments for the same extent " + key.getRow() + ": " + future + " and " + location);
 +        }
 +        future = location;
 +      } else if (cf.compareTo(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (current != null) {
 +          throw new BadLocationStateException("found two locations for the same extent " + key.getRow() + ": " + current + " and " + location);
 +        }
 +        current = location;
 +      } else if (cf.compareTo(Constants.METADATA_LOG_COLUMN_FAMILY) == 0) {
 +        String[] split = entry.getValue().toString().split("\\|")[0].split(";");
 +        walogs.add(Arrays.asList(split));
 +      } else if (cf.compareTo(Constants.METADATA_LAST_LOCATION_COLUMN_FAMILY) == 0) {
 +        TServerInstance location = new TServerInstance(entry.getValue(), cq);
 +        if (last != null) {
 +          throw new BadLocationStateException("found two last locations for the same extent " + key.getRow() + ": " + last + " and " + location);
 +        }
 +        last = new TServerInstance(entry.getValue(), cq);
 +      } else if (cf.compareTo(Constants.METADATA_CHOPPED_COLUMN_FAMILY) == 0) {
 +        chopped = true;
 +      } else if (Constants.METADATA_PREV_ROW_COLUMN.equals(cf, cq)) {
 +        extent = new KeyExtent(row, entry.getValue());
 +      }
 +    }
 +    if (extent == null) {
 +      log.warn("No prev-row for key extent: " + decodedRow);
 +      return null;
 +    }
 +    return new TabletLocationState(extent, future, current, last, walogs, chopped);
 +  }
 +  
 +  private TabletLocationState fetch() {
 +    try {
 +      Entry<Key,Value> e = iter.next();
 +      return createTabletLocationState(e.getKey(), e.getValue());
 +    } catch (IOException ex) {
 +      throw new RuntimeException(ex);
 +    } catch (BadLocationStateException ex) {
 +      throw new RuntimeException(ex);
 +    } 
 +  }
 +  
 +  @Override
 +  public void remove() {
 +    throw new RuntimeException("Unimplemented");
 +  }
 +}