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

org.hbase.async.AtomicIncrementRequest Maven / Gradle / Ivy

Go to download

An alternative HBase client library for applications requiring fully asynchronous, non-blocking and thread-safe HBase connectivity.

There is a newer version: 1.8.2
Show newest version
/*
 * Copyright (C) 2010-2012  The Async HBase Authors.  All rights reserved.
 * This file is part of Async HBase.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   - Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   - Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *   - Neither the name of the StumbleUpon nor the names of its contributors
 *     may be used to endorse or promote products derived from this software
 *     without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package org.hbase.async;

import java.util.ArrayList;

import org.jboss.netty.buffer.ChannelBuffer;

import org.hbase.async.generated.ClientPB.MutateRequest;
import org.hbase.async.generated.ClientPB.MutateResponse;
import org.hbase.async.generated.ClientPB.MutationProto;

/**
 * Atomically increments a value in HBase.
 *
 * 

A note on passing {@code byte} arrays in argument

* None of the method that receive a {@code byte[]} in argument will copy it. * For more info, please refer to the documentation of {@link HBaseRpc}. *

A note on passing {@code String}s in argument

* All strings are assumed to use the platform's default charset. */ public final class AtomicIncrementRequest extends HBaseRpc implements HBaseRpc.HasTable, HBaseRpc.HasKey, HBaseRpc.HasFamily, HBaseRpc.HasQualifier, HBaseRpc.IsEdit { private static final byte[] INCREMENT_COLUMN_VALUE = new byte[] { 'i', 'n', 'c', 'r', 'e', 'm', 'e', 'n', 't', 'C', 'o', 'l', 'u', 'm', 'n', 'V', 'a', 'l', 'u', 'e' }; private final byte[] family; private final byte[] qualifier; private long amount; private boolean durable = true; /** * Constructor. * These byte arrays will NOT be copied. * @param table The non-empty name of the table to use. * @param key The row key of the value to increment. * @param family The column family of the value to increment. * @param qualifier The column qualifier of the value to increment. * @param amount Amount by which to increment the value in HBase. * If negative, the value in HBase will be decremented. */ public AtomicIncrementRequest(final byte[] table, final byte[] key, final byte[] family, final byte[] qualifier, final long amount) { super(table, key); KeyValue.checkFamily(family); KeyValue.checkQualifier(qualifier); this.family = family; this.qualifier = qualifier; this.amount = amount; } /** * Constructor. This is equivalent to: * {@link #AtomicIncrementRequest(byte[], byte[], byte[], byte[], long) * AtomicIncrementRequest}{@code (table, key, family, qualifier, 1)} *

* These byte arrays will NOT be copied. * @param table The non-empty name of the table to use. * @param key The row key of the value to increment. * @param family The column family of the value to increment. * @param qualifier The column qualifier of the value to increment. */ public AtomicIncrementRequest(final byte[] table, final byte[] key, final byte[] family, final byte[] qualifier) { this(table, key, family, qualifier, 1); } /** * Constructor. * All strings are assumed to use the platform's default charset. * @param table The non-empty name of the table to use. * @param key The row key of the value to increment. * @param family The column family of the value to increment. * @param qualifier The column qualifier of the value to increment. * @param amount Amount by which to increment the value in HBase. * If negative, the value in HBase will be decremented. */ public AtomicIncrementRequest(final String table, final String key, final String family, final String qualifier, final long amount) { this(table.getBytes(), key.getBytes(), family.getBytes(), qualifier.getBytes(), amount); } /** * Constructor. This is equivalent to: * All strings are assumed to use the platform's default charset. * {@link #AtomicIncrementRequest(String, String, String, String, long) * AtomicIncrementRequest}{@code (table, key, family, qualifier, 1)} * @param table The non-empty name of the table to use. * @param key The row key of the value to increment. * @param family The column family of the value to increment. * @param qualifier The column qualifier of the value to increment. */ public AtomicIncrementRequest(final String table, final String key, final String family, final String qualifier) { this(table.getBytes(), key.getBytes(), family.getBytes(), qualifier.getBytes(), 1); } /** * Returns the amount by which the value is going to be incremented. */ public long getAmount() { return amount; } /** * Changes the amount by which the value is going to be incremented. * @param amount The new amount. If negative, the value will be decremented. */ public void setAmount(final long amount) { this.amount = amount; } @Override byte[] method(final byte server_version) { return (server_version >= RegionClient.SERVER_VERSION_095_OR_ABOVE ? MUTATE : INCREMENT_COLUMN_VALUE); } @Override public byte[] table() { return table; } @Override public byte[] key() { return key; } @Override public byte[] family() { return family; } @Override public byte[] qualifier() { return qualifier; } public String toString() { return super.toStringWithQualifier("AtomicIncrementRequest", family, qualifier, ", amount=" + amount); } // ---------------------- // // Package private stuff. // // ---------------------- // /** * Changes whether or not this atomic increment should use the WAL. * @param durable {@code true} to use the WAL, {@code false} otherwise. */ void setDurable(final boolean durable) { this.durable = durable; } private int predictSerializedSize() { int size = 0; size += 4; // int: Number of parameters. size += 1; // byte: Type of the 1st parameter. size += 3; // vint: region name length (3 bytes => max length = 32768). size += region.name().length; // The region name. size += 1; // byte: Type of the 2nd parameter. size += 3; // vint: row key length (3 bytes => max length = 32768). size += key.length; // The row key. size += 1; // byte: Type of the 3rd parameter. size += 1; // vint: Family length (guaranteed on 1 byte). size += family.length; // The family. size += 1; // byte: Type of the 4th parameter. size += 3; // vint: Qualifier length. size += qualifier.length; // The qualifier. size += 1; // byte: Type of the 5th parameter. size += 8; // long: Amount. size += 1; // byte: Type of the 6th parameter. size += 1; // bool: Whether or not to write to the WAL. return size; } /** Serializes this request. */ ChannelBuffer serialize(final byte server_version) { if (server_version < RegionClient.SERVER_VERSION_095_OR_ABOVE) { return serializeOld(server_version); } final MutationProto.ColumnValue.QualifierValue qualifier = MutationProto.ColumnValue.QualifierValue.newBuilder() .setQualifier(Bytes.wrap(this.qualifier)) .setValue(Bytes.wrap(Bytes.fromLong(amount))) .build(); final MutationProto.ColumnValue column = MutationProto.ColumnValue.newBuilder() .setFamily(Bytes.wrap(family)) .addQualifierValue(qualifier) .build(); final MutationProto.Builder incr = MutationProto.newBuilder() .setRow(Bytes.wrap(key)) .setMutateType(MutationProto.MutationType.INCREMENT) .addColumnValue(column); if (!durable) { incr.setDurability(MutationProto.Durability.SKIP_WAL); } final MutateRequest req = MutateRequest.newBuilder() .setRegion(region.toProtobuf()) .setMutation(incr.build()) .build(); return toChannelBuffer(MUTATE, req); } /** Serializes this request for HBase 0.94 and before. */ private ChannelBuffer serializeOld(final byte server_version) { final ChannelBuffer buf = newBuffer(server_version, predictSerializedSize()); buf.writeInt(6); // Number of parameters. writeHBaseByteArray(buf, region.name()); writeHBaseByteArray(buf, key); writeHBaseByteArray(buf, family); writeHBaseByteArray(buf, qualifier); writeHBaseLong(buf, amount); writeHBaseBool(buf, durable); return buf; } @Override Object deserialize(final ChannelBuffer buf, int cell_size) { final MutateResponse resp = readProtobuf(buf, MutateResponse.PARSER); // An increment must always produce a result, so we shouldn't need to // check whether the `result' field is set here. final ArrayList kvs = GetRequest.convertResult(resp.getResult(), buf, cell_size); if (kvs.size() != 1) { throw new InvalidResponseException("Atomic increment returned " + kvs.size() + " KeyValue(s), but we expected exactly one. kvs=" + kvs, resp); } return Bytes.getLong(kvs.get(0).value()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy