001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with this 004 * work for additional information regarding copyright ownership. The ASF 005 * licenses this file to you under the Apache License, Version 2.0 (the 006 * "License"); you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017package org.apache.hadoop.hbase.util.test; 018 019import java.io.IOException; 020import java.util.Random; 021import java.util.Set; 022 023import org.apache.hadoop.hbase.util.Bytes; 024import org.apache.hadoop.hbase.client.Get; 025import org.apache.hadoop.hbase.client.Mutation; 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. 031 * Contains 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 086 * 087 * @param args 088 * init args 089 */ 090 public void initialize(String[] args) { 091 this.args = args; 092 } 093 094 /** 095 * Generates a deterministic, unique hashed row key from a number. That way, the user can 096 * keep track of numbers, without messing with byte array and ensuring key distribution. 097 * @param keyBase Base number for a key, such as a loop counter. 098 */ 099 public abstract byte[] getDeterministicUniqueKey(long keyBase); 100 101 /** 102 * Gets column families for the load test table. 103 * @return The array of byte[]s representing column family names. 104 */ 105 public abstract byte[][] getColumnFamilies(); 106 107 /** 108 * Generates an applicable set of columns to be used for a particular key and family. 109 * @param rowKey The row key to generate for. 110 * @param cf The column family name to generate for. 111 * @return The array of byte[]s representing column names. 112 */ 113 public abstract byte[][] generateColumnsForCf(byte[] rowKey, byte[] cf); 114 115 /** 116 * Generates a value to be used for a particular row/cf/column. 117 * @param rowKey The row key to generate for. 118 * @param cf The column family name to generate for. 119 * @param column The column name to generate for. 120 * @return The value to use. 121 */ 122 public abstract byte[] generateValue(byte[] rowKey, byte[] cf, byte[] column); 123 124 /** 125 * Checks that columns for a rowKey and cf are valid if generated via 126 * {@link #generateColumnsForCf(byte[], byte[])} 127 * @param rowKey The row key to verify for. 128 * @param cf The column family name to verify for. 129 * @param columnSet The column set (for example, encountered by read). 130 * @return True iff valid. 131 */ 132 public abstract boolean verify(byte[] rowKey, byte[] cf, Set<byte[]> columnSet); 133 134 /** 135 * Checks that value for a rowKey/cf/column is valid if generated via 136 * {@link #generateValue(byte[], byte[], byte[])} 137 * @param rowKey The row key to verify for. 138 * @param cf The column family name to verify for. 139 * @param column The column name to verify for. 140 * @param value The value (for example, encountered by read). 141 * @return True iff valid. 142 */ 143 public abstract boolean verify(byte[] rowKey, byte[] cf, byte[] column, byte[] value); 144 145 /** 146 * Giving a chance for the LoadTestDataGenerator to change the Mutation load. 147 * @param rowkeyBase 148 * @param m 149 * @return updated Mutation 150 * @throws IOException 151 */ 152 public Mutation beforeMutate(long rowkeyBase, Mutation m) throws IOException { 153 return m; 154 } 155 156 /** 157 * Giving a chance for the LoadTestDataGenerator to change the Get load. 158 * @param rowkeyBase 159 * @param get 160 * @return updated Get 161 * @throws IOException 162 */ 163 public Get beforeGet(long rowkeyBase, Get get) throws IOException { 164 return get; 165 } 166 167 /** 168 * @return the arguments passed to the generator as a list of objects. 169 */ 170 public String[] getArgs() { 171 return this.args; 172 } 173}