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.io.hfile; 019 020import java.util.Random; 021import org.apache.hadoop.hbase.KeyValue; 022 023/** 024 * These helper methods generate random byte[]'s data for KeyValues 025 */ 026public class RandomKeyValueUtil { 027 public static final String COLUMN_FAMILY_NAME = "_-myColumnFamily-_"; 028 private static final int MIN_ROW_OR_QUALIFIER_LENGTH = 64; 029 private static final int MAX_ROW_OR_QUALIFIER_LENGTH = 128; 030 031 public static final char randomReadableChar(Random rand) { 032 int i = rand.nextInt(26 * 2 + 10 + 1); 033 if (i < 26) return (char) ('A' + i); 034 i -= 26; 035 036 if (i < 26) return (char) ('a' + i); 037 i -= 26; 038 039 if (i < 10) return (char) ('0' + i); 040 i -= 10; 041 042 assert i == 0; 043 return '_'; 044 } 045 046 public static KeyValue randomKeyValue(Random rand) { 047 return new KeyValue(randomRowOrQualifier(rand), COLUMN_FAMILY_NAME.getBytes(), 048 randomRowOrQualifier(rand), randomValue(rand)); 049 } 050 051 public static byte[] randomRowOrQualifier(Random rand) { 052 StringBuilder field = new StringBuilder(); 053 int fieldLen = MIN_ROW_OR_QUALIFIER_LENGTH 054 + rand.nextInt(MAX_ROW_OR_QUALIFIER_LENGTH - MIN_ROW_OR_QUALIFIER_LENGTH + 1); 055 for (int i = 0; i < fieldLen; ++i) 056 field.append(randomReadableChar(rand)); 057 return field.toString().getBytes(); 058 } 059 060 public static byte[] randomValue(Random rand) { 061 StringBuilder v = new StringBuilder(); 062 for (int j = 0; j < 1 + rand.nextInt(2000); ++j) { 063 v.append((char) (32 + rand.nextInt(95))); 064 } 065 066 byte[] valueBytes = v.toString().getBytes(); 067 return valueBytes; 068 } 069 070 /** 071 * Generates a random key that is guaranteed to increase as the given index i increases. The 072 * result consists of a prefix, which is a deterministic increasing function of i, and a random 073 * suffix. 074 * @param rand random number generator to use 075 * @return the random key 076 */ 077 public static byte[] randomOrderedKey(Random rand, int i) { 078 StringBuilder k = new StringBuilder(); 079 080 // The fixed-length lexicographically increasing part of the key. 081 for (int bitIndex = 31; bitIndex >= 0; --bitIndex) { 082 if ((i & (1 << bitIndex)) == 0) k.append("a"); 083 else k.append("b"); 084 } 085 086 // A random-length random suffix of the key. 087 for (int j = 0; j < rand.nextInt(50); ++j) 088 k.append(randomReadableChar(rand)); 089 090 byte[] keyBytes = k.toString().getBytes(); 091 return keyBytes; 092 } 093 094 public static byte[] randomOrderedFixedLengthKey(Random rand, int i, int suffixLength) { 095 StringBuilder k = new StringBuilder(); 096 097 // The fixed-length lexicographically increasing part of the key. 098 for (int bitIndex = 31; bitIndex >= 0; --bitIndex) { 099 if ((i & (1 << bitIndex)) == 0) k.append("a"); 100 else k.append("b"); 101 } 102 103 // A random suffix of the key. 104 for (int j = 0; j < suffixLength; ++j) 105 k.append(randomReadableChar(rand)); 106 107 byte[] keyBytes = k.toString().getBytes(); 108 return keyBytes; 109 } 110 111 public static byte[] randomFixedLengthValue(Random rand, int valueLength) { 112 StringBuilder v = new StringBuilder(); 113 for (int j = 0; j < valueLength; ++j) { 114 v.append((char) (32 + rand.nextInt(95))); 115 } 116 117 byte[] valueBytes = v.toString().getBytes(); 118 return valueBytes; 119 } 120}