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; 019 020import java.io.IOException; 021import java.util.Arrays; 022import java.util.Collections; 023import java.util.HashSet; 024import java.util.Set; 025import org.apache.hadoop.hbase.client.Durability; 026import org.apache.hadoop.hbase.client.Put; 027import org.apache.hadoop.hbase.client.Table; 028import org.apache.hadoop.hbase.regionserver.Region; 029import org.apache.hadoop.hbase.regionserver.RegionAsTable; 030import org.apache.hadoop.hbase.util.Bytes; 031 032/** 033 * Similar to {@link HConstants} but for tests. Also provides some simple static utility functions 034 * to generate test data. 035 */ 036public class HTestConst { 037 038 private HTestConst() { 039 } 040 041 public static final String DEFAULT_TABLE_STR = "MyTestTable"; 042 public static final byte[] DEFAULT_TABLE_BYTES = Bytes.toBytes(DEFAULT_TABLE_STR); 043 public static final TableName DEFAULT_TABLE = TableName.valueOf(DEFAULT_TABLE_BYTES); 044 045 public static final String DEFAULT_CF_STR = "MyDefaultCF"; 046 public static final byte[] DEFAULT_CF_BYTES = Bytes.toBytes(DEFAULT_CF_STR); 047 048 public static final Set<String> DEFAULT_CF_STR_SET = 049 Collections.unmodifiableSet(new HashSet<>(Arrays.asList(new String[] { DEFAULT_CF_STR }))); 050 051 public static final String DEFAULT_ROW_STR = "MyTestRow"; 052 public static final byte[] DEFAULT_ROW_BYTES = Bytes.toBytes(DEFAULT_ROW_STR); 053 054 public static final String DEFAULT_QUALIFIER_STR = "MyColumnQualifier"; 055 public static final byte[] DEFAULT_QUALIFIER_BYTES = Bytes.toBytes(DEFAULT_QUALIFIER_STR); 056 057 public static String DEFAULT_VALUE_STR = "MyTestValue"; 058 public static byte[] DEFAULT_VALUE_BYTES = Bytes.toBytes(DEFAULT_VALUE_STR); 059 060 private static final char FIRST_CHAR = 'a'; 061 private static final char LAST_CHAR = 'z'; 062 private static final byte[] START_KEY_BYTES = { FIRST_CHAR, FIRST_CHAR, FIRST_CHAR }; 063 064 /** 065 * Generate the given number of unique byte sequences by appending numeric suffixes (ASCII 066 * representations of decimal numbers). 067 */ 068 public static byte[][] makeNAscii(byte[] base, int n) { 069 byte[][] ret = new byte[n][]; 070 for (int i = 0; i < n; i++) { 071 byte[] tail = Bytes.toBytes(Integer.toString(i)); 072 ret[i] = Bytes.add(base, tail); 073 } 074 return ret; 075 } 076 077 /** 078 * Add content to region <code>r</code> on the passed column <code>column</code>. Adds data of the 079 * from 'aaa', 'aab', etc where key and value are the same. 080 * @return count of what we added. 081 */ 082 public static long addContent(final Region r, final byte[] columnFamily, final byte[] column) 083 throws IOException { 084 byte[] startKey = r.getRegionInfo().getStartKey(); 085 byte[] endKey = r.getRegionInfo().getEndKey(); 086 byte[] startKeyBytes = startKey; 087 if (startKeyBytes == null || startKeyBytes.length == 0) { 088 startKeyBytes = START_KEY_BYTES; 089 } 090 return addContent(new RegionAsTable(r), Bytes.toString(columnFamily), Bytes.toString(column), 091 startKeyBytes, endKey, -1); 092 } 093 094 public static long addContent(final Region r, final byte[] columnFamily) throws IOException { 095 return addContent(r, columnFamily, null); 096 } 097 098 /** 099 * Add content to region <code>r</code> on the passed column <code>column</code>. Adds data of the 100 * from 'aaa', 'aab', etc where key and value are the same. 101 * @return count of what we added. 102 */ 103 public static long addContent(Table updater, String columnFamily) throws IOException { 104 return addContent(updater, columnFamily, START_KEY_BYTES, null); 105 } 106 107 public static long addContent(Table updater, String family, String column) throws IOException { 108 return addContent(updater, family, column, START_KEY_BYTES, null); 109 } 110 111 /** 112 * Add content to region <code>r</code> on the passed column <code>column</code>. Adds data of the 113 * from 'aaa', 'aab', etc where key and value are the same. 114 * @return count of what we added. 115 */ 116 public static long addContent(Table updater, String columnFamily, byte[] startKeyBytes, 117 byte[] endKey) throws IOException { 118 return addContent(updater, columnFamily, null, startKeyBytes, endKey, -1); 119 } 120 121 public static long addContent(Table updater, String family, String column, byte[] startKeyBytes, 122 byte[] endKey) throws IOException { 123 return addContent(updater, family, column, startKeyBytes, endKey, -1); 124 } 125 126 /** 127 * Add content to region <code>r</code> on the passed column <code>column</code>. Adds data of the 128 * from 'aaa', 'aab', etc where key and value are the same. 129 * @return count of what we added. 130 */ 131 public static long addContent(Table updater, String columnFamily, String column, 132 byte[] startKeyBytes, byte[] endKey, long ts) throws IOException { 133 long count = 0; 134 // Add rows of three characters. The first character starts with the 135 // 'a' character and runs up to 'z'. Per first character, we run the 136 // second character over same range. And same for the third so rows 137 // (and values) look like this: 'aaa', 'aab', 'aac', etc. 138 char secondCharStart = (char) startKeyBytes[1]; 139 char thirdCharStart = (char) startKeyBytes[2]; 140 EXIT: for (char c = (char) startKeyBytes[0]; c <= LAST_CHAR; c++) { 141 for (char d = secondCharStart; d <= LAST_CHAR; d++) { 142 for (char e = thirdCharStart; e <= LAST_CHAR; e++) { 143 byte[] t = new byte[] { (byte) c, (byte) d, (byte) e }; 144 if (endKey != null && endKey.length > 0 && Bytes.compareTo(endKey, t) <= 0) { 145 break EXIT; 146 } 147 Put put; 148 if (ts != -1) { 149 put = new Put(t, ts); 150 } else { 151 put = new Put(t); 152 } 153 StringBuilder sb = new StringBuilder(); 154 if (column != null && column.contains(":")) { 155 sb.append(column); 156 } else { 157 if (columnFamily != null) { 158 sb.append(columnFamily); 159 if (!columnFamily.endsWith(":")) { 160 sb.append(":"); 161 } 162 if (column != null) { 163 sb.append(column); 164 } 165 } 166 } 167 byte[][] split = CellUtil.parseColumn(Bytes.toBytes(sb.toString())); 168 if (split.length == 1) { 169 byte[] qualifier = new byte[0]; 170 put.addColumn(split[0], qualifier, t); 171 } else { 172 put.addColumn(split[0], split[1], t); 173 } 174 put.setDurability(Durability.SKIP_WAL); 175 updater.put(put); 176 count++; 177 } 178 // Set start character back to FIRST_CHAR after we've done first loop. 179 thirdCharStart = FIRST_CHAR; 180 } 181 secondCharStart = FIRST_CHAR; 182 } 183 return count; 184 } 185}