001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.util.test; 019 020import java.io.IOException; 021import java.util.Random; 022import java.util.Set; 023import org.apache.hadoop.hbase.client.Get; 024import org.apache.hadoop.hbase.client.Mutation; 025import org.apache.hadoop.hbase.util.Bytes; 026import org.apache.hadoop.hbase.util.LoadTestKVGenerator; 027import org.apache.yetus.audience.InterfaceAudience; 028 029/** 030 * A generator of random data (keys/cfs/columns/values) for load testing. Contains 031 * LoadTestKVGenerator as a matter of convenience... 032 */ 033@InterfaceAudience.Private 034public abstract class LoadTestDataGenerator { 035 protected LoadTestKVGenerator kvGenerator; 036 037 // The mutate info column stores information 038 // about update done to this column family this row. 039 public final static byte[] MUTATE_INFO = Bytes.toBytes("mutate_info"); 040 041 // The increment column always has a long value, 042 // which can be incremented later on during updates. 043 public final static byte[] INCREMENT = Bytes.toBytes("increment"); 044 045 protected String[] args; 046 047 public LoadTestDataGenerator() { 048 049 } 050 051 /** 052 * Initializes the object. 053 * @param minValueSize minimum size of the value generated by 054 * {@link #generateValue(byte[], byte[], byte[])}. 055 * @param maxValueSize maximum size of the value generated by 056 * {@link #generateValue(byte[], byte[], byte[])}. 057 */ 058 public LoadTestDataGenerator(int minValueSize, int maxValueSize) { 059 this.kvGenerator = new LoadTestKVGenerator(minValueSize, maxValueSize); 060 } 061 062 public static byte[] generateData(final Random r, int length) { 063 byte[] b = new byte[length]; 064 int i = 0; 065 066 for (i = 0; i < (length - 8); i += 8) { 067 b[i] = (byte) (65 + r.nextInt(26)); 068 b[i + 1] = b[i]; 069 b[i + 2] = b[i]; 070 b[i + 3] = b[i]; 071 b[i + 4] = b[i]; 072 b[i + 5] = b[i]; 073 b[i + 6] = b[i]; 074 b[i + 7] = b[i]; 075 } 076 077 byte a = (byte) (65 + r.nextInt(26)); 078 for (; i < length; i++) { 079 b[i] = a; 080 } 081 return b; 082 } 083 084 /** 085 * initialize the LoadTestDataGenerator init args 086 */ 087 public void initialize(String[] args) { 088 this.args = args; 089 } 090 091 /** 092 * Generates a deterministic, unique hashed row key from a number. That way, the user can keep 093 * track of numbers, without messing with byte array and ensuring key distribution. 094 * @param keyBase Base number for a key, such as a loop counter. 095 */ 096 public abstract byte[] getDeterministicUniqueKey(long keyBase); 097 098 /** 099 * Gets column families for the load test table. 100 * @return The array of byte[]s representing column family names. 101 */ 102 public abstract byte[][] getColumnFamilies(); 103 104 /** 105 * Generates an applicable set of columns to be used for a particular key and family. 106 * @param rowKey The row key to generate for. 107 * @param cf The column family name to generate for. 108 * @return The array of byte[]s representing column names. 109 */ 110 public abstract byte[][] generateColumnsForCf(byte[] rowKey, byte[] cf); 111 112 /** 113 * Generates a value to be used for a particular row/cf/column. 114 * @param rowKey The row key to generate for. 115 * @param cf The column family name to generate for. 116 * @param column The column name to generate for. 117 * @return The value to use. 118 */ 119 public abstract byte[] generateValue(byte[] rowKey, byte[] cf, byte[] column); 120 121 /** 122 * Checks that columns for a rowKey and cf are valid if generated via 123 * {@link #generateColumnsForCf(byte[], byte[])} 124 * @param rowKey The row key to verify for. 125 * @param cf The column family name to verify for. 126 * @param columnSet The column set (for example, encountered by read). 127 * @return True iff valid. 128 */ 129 public abstract boolean verify(byte[] rowKey, byte[] cf, Set<byte[]> columnSet); 130 131 /** 132 * Checks that value for a rowKey/cf/column is valid if generated via 133 * {@link #generateValue(byte[], byte[], byte[])} 134 * @param rowKey The row key to verify for. 135 * @param cf The column family name to verify for. 136 * @param column The column name to verify for. 137 * @param value The value (for example, encountered by read). 138 * @return True iff valid. 139 */ 140 public abstract boolean verify(byte[] rowKey, byte[] cf, byte[] column, byte[] value); 141 142 /** 143 * Giving a chance for the LoadTestDataGenerator to change the Mutation load. 144 * @return updated Mutation 145 */ 146 public Mutation beforeMutate(long rowkeyBase, Mutation m) throws IOException { 147 return m; 148 } 149 150 /** 151 * Giving a chance for the LoadTestDataGenerator to change the Get load. 152 * @return updated Get 153 */ 154 public Get beforeGet(long rowkeyBase, Get get) throws IOException { 155 return get; 156 } 157 158 /** Returns the arguments passed to the generator as a list of objects. */ 159 public String[] getArgs() { 160 return this.args; 161 } 162}