Package org.apache.accumulo.core.util

Source Code of org.apache.accumulo.core.util.MetadataTable$DataFileValue

/*
* 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.core.util;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;

import org.apache.accumulo.core.Constants;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.Instance;
import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.impl.ScannerImpl;
import org.apache.accumulo.core.client.impl.Tables;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.KeyExtent;
import org.apache.accumulo.core.data.PartialKey;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.security.thrift.AuthInfo;
import org.apache.hadoop.io.Text;

public class MetadataTable {
  public static class DataFileValue {
    private long size;
    private long numEntries;
    private long time = -1;
   
    public DataFileValue(long size, long numEntries, long time) {
      this.size = size;
      this.numEntries = numEntries;
      this.time = time;
    }
   
    public DataFileValue(long size, long numEntries) {
      this.size = size;
      this.numEntries = numEntries;
      this.time = -1;
    }
   
    public DataFileValue(byte[] encodedDFV) {
      String[] ba = new String(encodedDFV).split(",");
     
      size = Long.parseLong(ba[0]);
      numEntries = Long.parseLong(ba[1]);
     
      if (ba.length == 3)
        time = Long.parseLong(ba[2]);
      else
        time = -1;
    }
   
    public long getSize() {
      return size;
    }
   
    public long getNumEntries() {
      return numEntries;
    }
   
    public boolean isTimeSet() {
      return time >= 0;
    }
   
    public long getTime() {
      return time;
    }
   
    public byte[] encode() {
      if (time >= 0)
        return ("" + size + "," + numEntries + "," + time).getBytes();
      return ("" + size + "," + numEntries).getBytes();
    }
   
    public boolean equals(Object o) {
      if (o instanceof DataFileValue) {
        DataFileValue odfv = (DataFileValue) o;
       
        return size == odfv.size && numEntries == odfv.numEntries;
      }
     
      return false;
    }
   
    public int hashCode() {
      return Long.valueOf(size + numEntries).hashCode();
    }
   
    public String toString() {
      return size + " " + numEntries;
    }
   
    public void setTime(long time) {
      if (time < 0)
        throw new IllegalArgumentException();
      this.time = time;
    }
  }
 
  public static SortedMap<KeyExtent,Text> getMetadataLocationEntries(SortedMap<Key,Value> entries) {
    Key key;
    Value val;
    Text location = null;
    Value prevRow = null;
    KeyExtent ke;
   
    SortedMap<KeyExtent,Text> results = new TreeMap<KeyExtent,Text>();
   
    Text lastRowFromKey = new Text();
   
    // text obj below is meant to be reused in loop for efficiency
    Text colf = new Text();
    Text colq = new Text();
   
    for (Entry<Key,Value> entry : entries.entrySet()) {
      key = entry.getKey();
      val = entry.getValue();
     
      if (key.compareRow(lastRowFromKey) != 0) {
        prevRow = null;
        location = null;
        key.getRow(lastRowFromKey);
      }
     
      colf = key.getColumnFamily(colf);
      colq = key.getColumnQualifier(colq);
     
      // interpret the row id as a key extent
      if (colf.equals(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY) || colf.equals(Constants.METADATA_FUTURE_LOCATION_COLUMN_FAMILY))
        location = new Text(val.toString());
      else if (Constants.METADATA_PREV_ROW_COLUMN.equals(colf, colq))
        prevRow = new Value(val);
     
      if (location != null && prevRow != null) {
        ke = new KeyExtent(key.getRow(), prevRow);
        results.put(ke, location);
       
        location = null;
        prevRow = null;
      }
    }
    return results;
  }
 
  public static SortedMap<Text,SortedMap<ColumnFQ,Value>> getTabletEntries(Instance instance, KeyExtent ke, List<ColumnFQ> columns, AuthInfo credentials) {
    TreeMap<Key,Value> tkv = new TreeMap<Key,Value>();
    getTabletAndPrevTabletKeyValues(instance, tkv, ke, columns, credentials);
    return getTabletEntries(tkv, columns);
  }
 
  public static SortedMap<Text,SortedMap<ColumnFQ,Value>> getTabletEntries(SortedMap<Key,Value> tabletKeyValues, List<ColumnFQ> columns) {
    TreeMap<Text,SortedMap<ColumnFQ,Value>> tabletEntries = new TreeMap<Text,SortedMap<ColumnFQ,Value>>();
   
    HashSet<ColumnFQ> colSet = null;
    if (columns != null) {
      colSet = new HashSet<ColumnFQ>(columns);
    }
   
    for (Entry<Key,Value> entry : tabletKeyValues.entrySet()) {
     
      if (columns != null && !colSet.contains(new ColumnFQ(entry.getKey()))) {
        continue;
      }
     
      Text row = entry.getKey().getRow();
     
      SortedMap<ColumnFQ,Value> colVals = tabletEntries.get(row);
      if (colVals == null) {
        colVals = new TreeMap<ColumnFQ,Value>();
        tabletEntries.put(row, colVals);
      }
     
      colVals.put(new ColumnFQ(entry.getKey()), entry.getValue());
    }
   
    return tabletEntries;
  }
 
  public static void getTabletAndPrevTabletKeyValues(Instance instance, SortedMap<Key,Value> tkv, KeyExtent ke, List<ColumnFQ> columns, AuthInfo credentials) {
    Text startRow;
    Text endRow = ke.getMetadataEntry();
   
    if (ke.getPrevEndRow() == null) {
      startRow = new Text(KeyExtent.getMetadataEntry(ke.getTableId(), new Text()));
    } else {
      startRow = new Text(KeyExtent.getMetadataEntry(ke.getTableId(), ke.getPrevEndRow()));
    }
   
    Scanner scanner = new ScannerImpl(instance, credentials, Constants.METADATA_TABLE_ID, Constants.NO_AUTHS);
   
    if (columns != null) {
      for (ColumnFQ column : columns)
        ColumnFQ.fetch(scanner, column);
    }
   
    scanner.setRange(new Range(new Key(startRow), true, new Key(endRow).followingKey(PartialKey.ROW), false));
   
    tkv.clear();
    boolean successful = false;
    try {
      for (Entry<Key,Value> entry : scanner) {
        tkv.put(entry.getKey(), entry.getValue());
      }
      successful = true;
    } finally {
      if (!successful) {
        tkv.clear();
      }
    }
  }
 
  public static void getEntries(Instance instance, AuthInfo credentials, String table, boolean isTid, Map<KeyExtent,String> locations,
      SortedSet<KeyExtent> tablets) throws AccumuloException, AccumuloSecurityException, TableNotFoundException {
    String tableId = isTid ? table : Tables.getNameToIdMap(instance).get(table);
   
    Scanner scanner = instance.getConnector(credentials.user, credentials.password).createScanner(Constants.METADATA_TABLE_NAME, Constants.NO_AUTHS);
   
    ColumnFQ.fetch(scanner, Constants.METADATA_PREV_ROW_COLUMN);
    scanner.fetchColumnFamily(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY);
   
    // position at first entry in metadata table for given table
    KeyExtent ke = new KeyExtent(new Text(tableId), new Text(), null);
    Key startKey = new Key(ke.getMetadataEntry());
    ke = new KeyExtent(new Text(tableId), null, null);
    Key endKey = new Key(ke.getMetadataEntry()).followingKey(PartialKey.ROW);
    scanner.setRange(new Range(startKey, endKey));
   
    Text colf = new Text();
    Text colq = new Text();
   
    KeyExtent currentKeyExtent = null;
    String location = null;
    Text row = null;
    // acquire this tables METADATA table entries
    boolean haveExtent = false;
    boolean haveLocation = false;
    for (Entry<Key,Value> entry : scanner) {
      if (row != null) {
        if (!row.equals(entry.getKey().getRow())) {
          currentKeyExtent = null;
          haveExtent = false;
          haveLocation = false;
          row = entry.getKey().getRow();
        }
      } else
        row = entry.getKey().getRow();
     
      colf = entry.getKey().getColumnFamily(colf);
      colq = entry.getKey().getColumnQualifier(colq);
     
      // stop scanning metadata table when another table is reached
      if (!(new KeyExtent(entry.getKey().getRow(), (Text) null)).getTableId().toString().equals(tableId))
        break;
     
      if (Constants.METADATA_PREV_ROW_COLUMN.equals(colf, colq)) {
        currentKeyExtent = new KeyExtent(entry.getKey().getRow(), entry.getValue());
        tablets.add(currentKeyExtent);
        haveExtent = true;
      } else if (colf.equals(Constants.METADATA_CURRENT_LOCATION_COLUMN_FAMILY)) {
        location = entry.getValue().toString();
        haveLocation = true;
      }
     
      if (haveExtent && haveLocation) {
        locations.put(currentKeyExtent, location);
        haveExtent = false;
        haveLocation = false;
        currentKeyExtent = null;
      }
    }
   
    validateEntries(tableId, tablets);
  }
 
  public static void validateEntries(String tableId, SortedSet<KeyExtent> tablets) throws AccumuloException {
    // sanity check of metadata table entries
    // make sure tablets has no holes, and that it starts and ends w/ null
    if (tablets.size() == 0)
      throw new AccumuloException("No entries found in metadata table for table " + tableId);
   
    if (tablets.first().getPrevEndRow() != null)
      throw new AccumuloException("Problem with metadata table, first entry for table " + tableId + "- " + tablets.first() + " - has non null prev end row");
   
    if (tablets.last().getEndRow() != null)
      throw new AccumuloException("Problem with metadata table, last entry for table " + tableId + "- " + tablets.first() + " - has non null end row");
   
    Iterator<KeyExtent> tabIter = tablets.iterator();
    Text lastEndRow = tabIter.next().getEndRow();
    while (tabIter.hasNext()) {
      KeyExtent tabke = tabIter.next();
     
      if (tabke.getPrevEndRow() == null)
        throw new AccumuloException("Problem with metadata table, it has null prev end row in middle of table " + tabke);
     
      if (!tabke.getPrevEndRow().equals(lastEndRow))
        throw new AccumuloException("Problem with metadata table, it has a hole " + tabke.getPrevEndRow() + " != " + lastEndRow);
     
      lastEndRow = tabke.getEndRow();
    }
   
    // end METADATA table sanity check
  }
 
  public static boolean isContiguousRange(KeyExtent ke, SortedSet<KeyExtent> children) {
    if (children.size() == 0)
      return false;
   
    if (children.size() == 1)
      return children.first().equals(ke);
   
    Text per = children.first().getPrevEndRow();
    Text er = children.last().getEndRow();
   
    boolean perEqual = (per == ke.getPrevEndRow() || per != null && ke.getPrevEndRow() != null && ke.getPrevEndRow().compareTo(per) == 0);
   
    boolean erEqual = (er == ke.getEndRow() || er != null && ke.getEndRow() != null && ke.getEndRow().compareTo(er) == 0);
   
    if (!perEqual || !erEqual)
      return false;
   
    Iterator<KeyExtent> iter = children.iterator();
   
    Text lastEndRow = iter.next().getEndRow();
   
    while (iter.hasNext()) {
      KeyExtent cke = iter.next();
     
      per = cke.getPrevEndRow();
     
      // something in the middle should not be null
     
      if (per == null || lastEndRow == null)
        return false;
     
      if (per.compareTo(lastEndRow) != 0)
        return false;
     
      lastEndRow = cke.getEndRow();
    }
   
    return true;
  }
 
}
TOP

Related Classes of org.apache.accumulo.core.util.MetadataTable$DataFileValue

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.