All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.hbase.client.MultiPut Maven / Gradle / Ivy

Go to download

HBase is the &lt;a href="http://hadoop.apache.org"&rt;Hadoop</a&rt; database. Use it when you need random, realtime read/write access to your Big Data. This project's goal is the hosting of very large tables -- billions of rows X millions of columns -- atop clusters of commodity hardware.

The newest version!
/*
 * Copyright 2010 The Apache Software Foundation
 *
 * 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.hadoop.hbase.client;

import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HServerAddress;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.Writable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * @deprecated Use MultiAction instead
 * Data type class for putting multiple regions worth of puts in one RPC.
 */
public class MultiPut extends Operation implements Writable {
  public HServerAddress address; // client code ONLY

  // TODO make this configurable
  public static final int DEFAULT_MAX_PUT_OUTPUT = 10;

  // map of regions to lists of puts for that region.
  public Map > puts = new TreeMap>(Bytes.BYTES_COMPARATOR);

  /**
   * Writable constructor only.
   */
  public MultiPut() {}

  /**
   * MultiPut for putting multiple regions worth of puts in one RPC.
   * @param a address
   */
  public MultiPut(HServerAddress a) {
    address = a;
  }

  public int size() {
    int size = 0;
    for( List l : puts.values()) {
      size += l.size();
    }
    return size;
  }

  public void add(byte[] regionName, Put aPut) {
    List rsput = puts.get(regionName);
    if (rsput == null) {
      rsput = new ArrayList();
      puts.put(regionName, rsput);
    }
    rsput.add(aPut);
  }

  public Collection allPuts() {
    List res = new ArrayList();
    for ( List pp : puts.values() ) {
      res.addAll(pp);
    }
    return res;
  }

  /**
   * Compile the table and column family (i.e. schema) information 
   * into a String. Useful for parsing and aggregation by debugging,
   * logging, and administration tools.
   * @return Map
   */
  @Override
  public Map getFingerprint() {
    Map map = new HashMap();
    // for extensibility, we have a map of table information that we will
    // populate with only family information for each table
    Map tableInfo = 
      new HashMap();
    map.put("tables", tableInfo);
    for (Map.Entry> entry : puts.entrySet()) {
      // our fingerprint only concerns itself with which families are touched,
      // not how many Puts touch them, so we use this Set to do just that.
      Set familySet;
      try {
        // since the puts are stored by region, we may have already
        // recorded families for this region. if that is the case,
        // we want to add to the existing Set. if not, we make a new Set.
        String tableName = Bytes.toStringBinary(
            HRegionInfo.parseRegionName(entry.getKey())[0]);
        if (tableInfo.get(tableName) == null) {
          Map table = new HashMap();
          familySet = new TreeSet();
          table.put("families", familySet);
          tableInfo.put(tableName, table);
        } else {
          familySet = (Set) tableInfo.get(tableName).get("families");
        }
      } catch (IOException ioe) {
        // in the case of parse error, default to labeling by region
        Map table = new HashMap();
        familySet = new TreeSet();
        table.put("families", familySet);
        tableInfo.put(Bytes.toStringBinary(entry.getKey()), table);
      }   
      // we now iterate through each Put and keep track of which families 
      // are affected in this table.
      for (Put p : entry.getValue()) {
        for (byte[] fam : p.getFamilyMap().keySet()) {
          familySet.add(Bytes.toStringBinary(fam));
        }
      }
    }
    return map;
  }

  /**
   * Compile the details beyond the scope of getFingerprint (mostly 
   * toMap from the Puts) into a Map along with the fingerprinted 
   * information. Useful for debugging, logging, and administration tools.
   * @param maxCols a limit on the number of columns output prior to truncation
   * @return Map
   */
  @Override
  public Map toMap(int maxCols) {
    Map map = getFingerprint();
    Map tableInfo = (Map) map.get("tables");
    int putCount = 0;
    for (Map.Entry> entry : puts.entrySet()) {
      // If the limit has been hit for put output, just adjust our counter
      if (putCount >= DEFAULT_MAX_PUT_OUTPUT) {
        putCount += entry.getValue().size();
        continue;
      }
      List regionPuts = entry.getValue();
      List> putSummaries =
        new ArrayList>();
      // find out how many of this region's puts we can add without busting
      // the maximum
      int regionPutsToAdd = regionPuts.size();
      putCount += regionPutsToAdd;
      if (putCount > DEFAULT_MAX_PUT_OUTPUT) {
        regionPutsToAdd -= putCount - DEFAULT_MAX_PUT_OUTPUT;
      }
      for (Iterator iter = regionPuts.iterator(); regionPutsToAdd-- > 0;) {
        putSummaries.add(iter.next().toMap(maxCols));
      }
      // attempt to extract the table name from the region name
      String tableName = "";
      try {
        tableName = Bytes.toStringBinary(
            HRegionInfo.parseRegionName(entry.getKey())[0]);
      } catch (IOException ioe) {
        // in the case of parse error, default to labeling by region
        tableName = Bytes.toStringBinary(entry.getKey());
      }
      // since the puts are stored by region, we may have already 
      // recorded puts for this table. if that is the case, 
      // we want to add to the existing List. if not, we place a new list 
      // in the map
      Map table =
        (Map) tableInfo.get(tableName);
      if (table == null) {
        // in case the Put has changed since getFingerprint's map was built
        table = new HashMap();
        tableInfo.put(tableName, table);
        table.put("puts", putSummaries);
      } else if (table.get("puts") == null) {
        table.put("puts", putSummaries);
      } else {
        ((List>) table.get("puts")).addAll(putSummaries);
      }
    }
    map.put("totalPuts", putCount);
    return map;
  }

  @Override
  public void write(DataOutput out) throws IOException {
    out.writeInt(puts.size());
    for( Map.Entry> e : puts.entrySet()) {
      Bytes.writeByteArray(out, e.getKey());

      List ps = e.getValue();
      out.writeInt(ps.size());
      for( Put p : ps ) {
        p.write(out);
      }
    }
  }

  @Override
  public void readFields(DataInput in) throws IOException {
    puts.clear();

    int mapSize = in.readInt();

    for (int i = 0 ; i < mapSize; i++) {
      byte[] key = Bytes.readByteArray(in);

      int listSize = in.readInt();
      List ps = new ArrayList(listSize);
      for ( int j = 0 ; j < listSize; j++ ) {
        Put put = new Put();
        put.readFields(in);
        ps.add(put);
      }
      puts.put(key, ps);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy