1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.mapreduce;
19
20 import java.io.IOException;
21 import java.io.UnsupportedEncodingException;
22 import java.net.InetSocketAddress;
23 import java.net.URLDecoder;
24 import java.net.URLEncoder;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.TreeMap;
30 import java.util.TreeSet;
31 import java.util.UUID;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.hadoop.hbase.classification.InterfaceAudience;
36 import org.apache.hadoop.hbase.classification.InterfaceStability;
37 import org.apache.hadoop.conf.Configuration;
38 import org.apache.hadoop.fs.FileSystem;
39 import org.apache.hadoop.fs.Path;
40 import org.apache.hadoop.hbase.Cell;
41 import org.apache.hadoop.hbase.CellUtil;
42 import org.apache.hadoop.hbase.HColumnDescriptor;
43 import org.apache.hadoop.hbase.HConstants;
44 import org.apache.hadoop.hbase.HRegionLocation;
45 import org.apache.hadoop.hbase.HTableDescriptor;
46 import org.apache.hadoop.hbase.KeyValue;
47 import org.apache.hadoop.hbase.KeyValueUtil;
48 import org.apache.hadoop.hbase.TableName;
49 import org.apache.hadoop.hbase.client.Connection;
50 import org.apache.hadoop.hbase.client.ConnectionFactory;
51 import org.apache.hadoop.hbase.client.HTable;
52 import org.apache.hadoop.hbase.client.Put;
53 import org.apache.hadoop.hbase.client.RegionLocator;
54 import org.apache.hadoop.hbase.client.Table;
55 import org.apache.hadoop.hbase.fs.HFileSystem;
56 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
57 import org.apache.hadoop.hbase.io.compress.Compression;
58 import org.apache.hadoop.hbase.io.compress.Compression.Algorithm;
59 import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
60 import org.apache.hadoop.hbase.io.hfile.AbstractHFileWriter;
61 import org.apache.hadoop.hbase.io.hfile.CacheConfig;
62 import org.apache.hadoop.hbase.io.hfile.HFile;
63 import org.apache.hadoop.hbase.io.hfile.HFileContext;
64 import org.apache.hadoop.hbase.io.hfile.HFileContextBuilder;
65 import org.apache.hadoop.hbase.regionserver.BloomType;
66 import org.apache.hadoop.hbase.regionserver.HStore;
67 import org.apache.hadoop.hbase.regionserver.StoreFile;
68 import org.apache.hadoop.hbase.util.Bytes;
69 import org.apache.hadoop.io.NullWritable;
70 import org.apache.hadoop.io.SequenceFile;
71 import org.apache.hadoop.io.Text;
72 import org.apache.hadoop.mapreduce.Job;
73 import org.apache.hadoop.mapreduce.OutputFormat;
74 import org.apache.hadoop.mapreduce.RecordWriter;
75 import org.apache.hadoop.mapreduce.TaskAttemptContext;
76 import org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter;
77 import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
78 import org.apache.hadoop.mapreduce.lib.partition.TotalOrderPartitioner;
79
80 import com.google.common.annotations.VisibleForTesting;
81
82
83
84
85
86
87
88
89
90
91 @InterfaceAudience.Public
92 @InterfaceStability.Evolving
93 public class HFileOutputFormat2
94 extends FileOutputFormat<ImmutableBytesWritable, Cell> {
95 private static final Log LOG = LogFactory.getLog(HFileOutputFormat2.class);
96
97
98
99
100
101 private static final String COMPRESSION_FAMILIES_CONF_KEY =
102 "hbase.hfileoutputformat.families.compression";
103 private static final String BLOOM_TYPE_FAMILIES_CONF_KEY =
104 "hbase.hfileoutputformat.families.bloomtype";
105 private static final String BLOCK_SIZE_FAMILIES_CONF_KEY =
106 "hbase.mapreduce.hfileoutputformat.blocksize";
107 private static final String DATABLOCK_ENCODING_FAMILIES_CONF_KEY =
108 "hbase.mapreduce.hfileoutputformat.families.datablock.encoding";
109
110
111
112
113
114 public static final String DATABLOCK_ENCODING_OVERRIDE_CONF_KEY =
115 "hbase.mapreduce.hfileoutputformat.datablock.encoding";
116
117
118
119
120 public static final String LOCALITY_SENSITIVE_CONF_KEY =
121 "hbase.bulkload.locality.sensitive.enabled";
122 private static final boolean DEFAULT_LOCALITY_SENSITIVE = true;
123 private static final String OUTPUT_TABLE_NAME_CONF_KEY =
124 "hbase.mapreduce.hfileoutputformat.table.name";
125
126 @Override
127 public RecordWriter<ImmutableBytesWritable, Cell> getRecordWriter(
128 final TaskAttemptContext context) throws IOException, InterruptedException {
129 return createRecordWriter(context);
130 }
131
132 static <V extends Cell> RecordWriter<ImmutableBytesWritable, V>
133 createRecordWriter(final TaskAttemptContext context)
134 throws IOException {
135
136
137 final Path outputPath = FileOutputFormat.getOutputPath(context);
138 final Path outputdir = new FileOutputCommitter(outputPath, context).getWorkPath();
139 final Configuration conf = context.getConfiguration();
140 final FileSystem fs = outputdir.getFileSystem(conf);
141
142 final long maxsize = conf.getLong(HConstants.HREGION_MAX_FILESIZE,
143 HConstants.DEFAULT_MAX_FILE_SIZE);
144
145 final String defaultCompressionStr = conf.get("hfile.compression",
146 Compression.Algorithm.NONE.getName());
147 final Algorithm defaultCompression = AbstractHFileWriter
148 .compressionByName(defaultCompressionStr);
149 final boolean compactionExclude = conf.getBoolean(
150 "hbase.mapreduce.hfileoutputformat.compaction.exclude", false);
151
152
153 final Map<byte[], Algorithm> compressionMap = createFamilyCompressionMap(conf);
154 final Map<byte[], BloomType> bloomTypeMap = createFamilyBloomTypeMap(conf);
155 final Map<byte[], Integer> blockSizeMap = createFamilyBlockSizeMap(conf);
156
157 String dataBlockEncodingStr = conf.get(DATABLOCK_ENCODING_OVERRIDE_CONF_KEY);
158 final Map<byte[], DataBlockEncoding> datablockEncodingMap
159 = createFamilyDataBlockEncodingMap(conf);
160 final DataBlockEncoding overriddenEncoding;
161 if (dataBlockEncodingStr != null) {
162 overriddenEncoding = DataBlockEncoding.valueOf(dataBlockEncodingStr);
163 } else {
164 overriddenEncoding = null;
165 }
166
167 return new RecordWriter<ImmutableBytesWritable, V>() {
168
169 private final Map<byte [], WriterLength> writers =
170 new TreeMap<byte [], WriterLength>(Bytes.BYTES_COMPARATOR);
171 private byte [] previousRow = HConstants.EMPTY_BYTE_ARRAY;
172 private final byte [] now = Bytes.toBytes(System.currentTimeMillis());
173 private boolean rollRequested = false;
174
175 @Override
176 public void write(ImmutableBytesWritable row, V cell)
177 throws IOException {
178 KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
179
180
181 if (row == null && kv == null) {
182 rollWriters();
183 return;
184 }
185
186 byte [] rowKey = CellUtil.cloneRow(kv);
187 long length = kv.getLength();
188 byte [] family = CellUtil.cloneFamily(kv);
189 WriterLength wl = this.writers.get(family);
190
191
192 if (wl == null) {
193 fs.mkdirs(new Path(outputdir, Bytes.toString(family)));
194 }
195
196
197
198 if (wl != null && wl.written + length >= maxsize) {
199 this.rollRequested = true;
200 }
201
202
203 if (rollRequested && Bytes.compareTo(this.previousRow, rowKey) != 0) {
204 rollWriters();
205 }
206
207
208 if (wl == null || wl.writer == null) {
209 if (conf.getBoolean(LOCALITY_SENSITIVE_CONF_KEY, DEFAULT_LOCALITY_SENSITIVE)) {
210 HRegionLocation loc = null;
211 String tableName = conf.get(OUTPUT_TABLE_NAME_CONF_KEY);
212 if (tableName != null) {
213 try (Connection connection = ConnectionFactory.createConnection(conf);
214 RegionLocator locator =
215 connection.getRegionLocator(TableName.valueOf(tableName))) {
216 loc = locator.getRegionLocation(rowKey);
217 } catch (Throwable e) {
218 LOG.warn("there's something wrong when locating rowkey: " +
219 Bytes.toString(rowKey), e);
220 loc = null;
221 }
222 }
223
224 if (null == loc) {
225 if (LOG.isTraceEnabled()) {
226 LOG.trace("failed to get region location, so use default writer: "
227 + Bytes.toString(rowKey));
228 }
229 wl = getNewWriter(family, conf, null);
230 } else {
231 if (LOG.isDebugEnabled()) {
232 LOG.debug("first rowkey: [" + Bytes.toString(rowKey) + "]");
233 }
234 InetSocketAddress initialIsa =
235 new InetSocketAddress(loc.getHostname(), loc.getPort());
236 if (initialIsa.isUnresolved()) {
237 if (LOG.isTraceEnabled()) {
238 LOG.trace("failed to resolve bind address: " + loc.getHostname() + ":"
239 + loc.getPort() + ", so use default writer");
240 }
241 wl = getNewWriter(family, conf, null);
242 } else {
243 if (LOG.isDebugEnabled()) {
244 LOG.debug("use favored nodes writer: " + initialIsa.getHostString());
245 }
246 wl = getNewWriter(family, conf, new InetSocketAddress[] { initialIsa });
247 }
248 }
249 } else {
250 wl = getNewWriter(family, conf, null);
251 }
252 }
253
254
255 kv.updateLatestStamp(this.now);
256 wl.writer.append(kv);
257 wl.written += length;
258
259
260 this.previousRow = rowKey;
261 }
262
263 private void rollWriters() throws IOException {
264 for (WriterLength wl : this.writers.values()) {
265 if (wl.writer != null) {
266 LOG.info("Writer=" + wl.writer.getPath() +
267 ((wl.written == 0)? "": ", wrote=" + wl.written));
268 close(wl.writer);
269 }
270 wl.writer = null;
271 wl.written = 0;
272 }
273 this.rollRequested = false;
274 }
275
276
277
278
279
280
281 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="BX_UNBOXING_IMMEDIATELY_REBOXED",
282 justification="Not important")
283 private WriterLength getNewWriter(byte[] family, Configuration conf,
284 InetSocketAddress[] favoredNodes)
285 throws IOException {
286 WriterLength wl = new WriterLength();
287 Path familydir = new Path(outputdir, Bytes.toString(family));
288 Algorithm compression = compressionMap.get(family);
289 compression = compression == null ? defaultCompression : compression;
290 BloomType bloomType = bloomTypeMap.get(family);
291 bloomType = bloomType == null ? BloomType.NONE : bloomType;
292 Integer blockSize = blockSizeMap.get(family);
293 blockSize = blockSize == null ? HConstants.DEFAULT_BLOCKSIZE : blockSize;
294 DataBlockEncoding encoding = overriddenEncoding;
295 encoding = encoding == null ? datablockEncodingMap.get(family) : encoding;
296 encoding = encoding == null ? DataBlockEncoding.NONE : encoding;
297 Configuration tempConf = new Configuration(conf);
298 tempConf.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0.0f);
299 HFileContextBuilder contextBuilder = new HFileContextBuilder()
300 .withCompression(compression)
301 .withChecksumType(HStore.getChecksumType(conf))
302 .withBytesPerCheckSum(HStore.getBytesPerChecksum(conf))
303 .withBlockSize(blockSize);
304
305 if (HFile.getFormatVersion(conf) >= HFile.MIN_FORMAT_VERSION_WITH_TAGS) {
306 contextBuilder.withIncludesTags(true);
307 }
308
309 contextBuilder.withDataBlockEncoding(encoding);
310 HFileContext hFileContext = contextBuilder.build();
311
312 if (null == favoredNodes) {
313 wl.writer =
314 new StoreFile.WriterBuilder(conf, new CacheConfig(tempConf), fs)
315 .withOutputDir(familydir).withBloomType(bloomType)
316 .withComparator(KeyValue.COMPARATOR).withFileContext(hFileContext).build();
317 } else {
318 wl.writer =
319 new StoreFile.WriterBuilder(conf, new CacheConfig(tempConf), new HFileSystem(fs))
320 .withOutputDir(familydir).withBloomType(bloomType)
321 .withComparator(KeyValue.COMPARATOR).withFileContext(hFileContext)
322 .withFavoredNodes(favoredNodes).build();
323 }
324
325 this.writers.put(family, wl);
326 return wl;
327 }
328
329 private void close(final StoreFile.Writer w) throws IOException {
330 if (w != null) {
331 w.appendFileInfo(StoreFile.BULKLOAD_TIME_KEY,
332 Bytes.toBytes(System.currentTimeMillis()));
333 w.appendFileInfo(StoreFile.BULKLOAD_TASK_KEY,
334 Bytes.toBytes(context.getTaskAttemptID().toString()));
335 w.appendFileInfo(StoreFile.MAJOR_COMPACTION_KEY,
336 Bytes.toBytes(true));
337 w.appendFileInfo(StoreFile.EXCLUDE_FROM_MINOR_COMPACTION_KEY,
338 Bytes.toBytes(compactionExclude));
339 w.appendTrackedTimestampsToMetadata();
340 w.close();
341 }
342 }
343
344 @Override
345 public void close(TaskAttemptContext c)
346 throws IOException, InterruptedException {
347 for (WriterLength wl: this.writers.values()) {
348 close(wl.writer);
349 }
350 }
351 };
352 }
353
354
355
356
357 static class WriterLength {
358 long written = 0;
359 StoreFile.Writer writer = null;
360 }
361
362
363
364
365
366 private static List<ImmutableBytesWritable> getRegionStartKeys(RegionLocator table)
367 throws IOException {
368 byte[][] byteKeys = table.getStartKeys();
369 ArrayList<ImmutableBytesWritable> ret =
370 new ArrayList<ImmutableBytesWritable>(byteKeys.length);
371 for (byte[] byteKey : byteKeys) {
372 ret.add(new ImmutableBytesWritable(byteKey));
373 }
374 return ret;
375 }
376
377
378
379
380
381 @SuppressWarnings("deprecation")
382 private static void writePartitions(Configuration conf, Path partitionsPath,
383 List<ImmutableBytesWritable> startKeys) throws IOException {
384 LOG.info("Writing partition information to " + partitionsPath);
385 if (startKeys.isEmpty()) {
386 throw new IllegalArgumentException("No regions passed");
387 }
388
389
390
391
392
393 TreeSet<ImmutableBytesWritable> sorted =
394 new TreeSet<ImmutableBytesWritable>(startKeys);
395
396 ImmutableBytesWritable first = sorted.first();
397 if (!first.equals(HConstants.EMPTY_BYTE_ARRAY)) {
398 throw new IllegalArgumentException(
399 "First region of table should have empty start key. Instead has: "
400 + Bytes.toStringBinary(first.get()));
401 }
402 sorted.remove(first);
403
404
405 FileSystem fs = partitionsPath.getFileSystem(conf);
406 SequenceFile.Writer writer = SequenceFile.createWriter(
407 fs, conf, partitionsPath, ImmutableBytesWritable.class,
408 NullWritable.class);
409
410 try {
411 for (ImmutableBytesWritable startKey : sorted) {
412 writer.append(startKey, NullWritable.get());
413 }
414 } finally {
415 writer.close();
416 }
417 }
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435 @Deprecated
436 public static void configureIncrementalLoad(Job job, HTable table)
437 throws IOException {
438 configureIncrementalLoad(job, table.getTableDescriptor(), table.getRegionLocator());
439 }
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455 public static void configureIncrementalLoad(Job job, Table table, RegionLocator regionLocator)
456 throws IOException {
457 configureIncrementalLoad(job, table.getTableDescriptor(), regionLocator);
458 }
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474 public static void configureIncrementalLoad(Job job, HTableDescriptor tableDescriptor,
475 RegionLocator regionLocator) throws IOException {
476 configureIncrementalLoad(job, tableDescriptor, regionLocator, HFileOutputFormat2.class);
477 }
478
479 static void configureIncrementalLoad(Job job, HTableDescriptor tableDescriptor,
480 RegionLocator regionLocator, Class<? extends OutputFormat<?, ?>> cls) throws IOException,
481 UnsupportedEncodingException {
482 Configuration conf = job.getConfiguration();
483 job.setOutputKeyClass(ImmutableBytesWritable.class);
484 job.setOutputValueClass(KeyValue.class);
485 job.setOutputFormatClass(cls);
486
487
488
489
490 if (KeyValue.class.equals(job.getMapOutputValueClass())) {
491 job.setReducerClass(KeyValueSortReducer.class);
492 } else if (Put.class.equals(job.getMapOutputValueClass())) {
493 job.setReducerClass(PutSortReducer.class);
494 } else if (Text.class.equals(job.getMapOutputValueClass())) {
495 job.setReducerClass(TextSortReducer.class);
496 } else {
497 LOG.warn("Unknown map output value type:" + job.getMapOutputValueClass());
498 }
499
500 conf.setStrings("io.serializations", conf.get("io.serializations"),
501 MutationSerialization.class.getName(), ResultSerialization.class.getName(),
502 KeyValueSerialization.class.getName());
503
504 if (conf.getBoolean(LOCALITY_SENSITIVE_CONF_KEY, DEFAULT_LOCALITY_SENSITIVE)) {
505
506 LOG.info("bulkload locality sensitive enabled");
507 conf.set(OUTPUT_TABLE_NAME_CONF_KEY, regionLocator.getName().getNameAsString());
508 }
509
510
511 LOG.info("Looking up current regions for table " + tableDescriptor.getTableName());
512 List<ImmutableBytesWritable> startKeys = getRegionStartKeys(regionLocator);
513 LOG.info("Configuring " + startKeys.size() + " reduce partitions " +
514 "to match current region count");
515 job.setNumReduceTasks(startKeys.size());
516
517 configurePartitioner(job, startKeys);
518
519 configureCompression(conf, tableDescriptor);
520 configureBloomType(tableDescriptor, conf);
521 configureBlockSize(tableDescriptor, conf);
522 configureDataBlockEncoding(tableDescriptor, conf);
523
524 TableMapReduceUtil.addDependencyJars(job);
525 TableMapReduceUtil.initCredentials(job);
526 LOG.info("Incremental table " + regionLocator.getName() + " output configured.");
527 }
528
529 public static void configureIncrementalLoadMap(Job job, Table table) throws IOException {
530 Configuration conf = job.getConfiguration();
531
532 job.setOutputKeyClass(ImmutableBytesWritable.class);
533 job.setOutputValueClass(KeyValue.class);
534 job.setOutputFormatClass(HFileOutputFormat2.class);
535
536
537 configureCompression(conf, table.getTableDescriptor());
538 configureBloomType(table.getTableDescriptor(), conf);
539 configureBlockSize(table.getTableDescriptor(), conf);
540 HTableDescriptor tableDescriptor = table.getTableDescriptor();
541 configureDataBlockEncoding(tableDescriptor, conf);
542
543 TableMapReduceUtil.addDependencyJars(job);
544 TableMapReduceUtil.initCredentials(job);
545 LOG.info("Incremental table " + table.getName() + " output configured.");
546 }
547
548
549
550
551
552
553
554
555 @VisibleForTesting
556 static Map<byte[], Algorithm> createFamilyCompressionMap(Configuration
557 conf) {
558 Map<byte[], String> stringMap = createFamilyConfValueMap(conf,
559 COMPRESSION_FAMILIES_CONF_KEY);
560 Map<byte[], Algorithm> compressionMap = new TreeMap<byte[],
561 Algorithm>(Bytes.BYTES_COMPARATOR);
562 for (Map.Entry<byte[], String> e : stringMap.entrySet()) {
563 Algorithm algorithm = AbstractHFileWriter.compressionByName
564 (e.getValue());
565 compressionMap.put(e.getKey(), algorithm);
566 }
567 return compressionMap;
568 }
569
570
571
572
573
574
575
576
577 @VisibleForTesting
578 static Map<byte[], BloomType> createFamilyBloomTypeMap(Configuration conf) {
579 Map<byte[], String> stringMap = createFamilyConfValueMap(conf,
580 BLOOM_TYPE_FAMILIES_CONF_KEY);
581 Map<byte[], BloomType> bloomTypeMap = new TreeMap<byte[],
582 BloomType>(Bytes.BYTES_COMPARATOR);
583 for (Map.Entry<byte[], String> e : stringMap.entrySet()) {
584 BloomType bloomType = BloomType.valueOf(e.getValue());
585 bloomTypeMap.put(e.getKey(), bloomType);
586 }
587 return bloomTypeMap;
588 }
589
590
591
592
593
594
595
596
597 @VisibleForTesting
598 static Map<byte[], Integer> createFamilyBlockSizeMap(Configuration conf) {
599 Map<byte[], String> stringMap = createFamilyConfValueMap(conf,
600 BLOCK_SIZE_FAMILIES_CONF_KEY);
601 Map<byte[], Integer> blockSizeMap = new TreeMap<byte[],
602 Integer>(Bytes.BYTES_COMPARATOR);
603 for (Map.Entry<byte[], String> e : stringMap.entrySet()) {
604 Integer blockSize = Integer.parseInt(e.getValue());
605 blockSizeMap.put(e.getKey(), blockSize);
606 }
607 return blockSizeMap;
608 }
609
610
611
612
613
614
615
616
617
618 @VisibleForTesting
619 static Map<byte[], DataBlockEncoding> createFamilyDataBlockEncodingMap(
620 Configuration conf) {
621 Map<byte[], String> stringMap = createFamilyConfValueMap(conf,
622 DATABLOCK_ENCODING_FAMILIES_CONF_KEY);
623 Map<byte[], DataBlockEncoding> encoderMap = new TreeMap<byte[],
624 DataBlockEncoding>(Bytes.BYTES_COMPARATOR);
625 for (Map.Entry<byte[], String> e : stringMap.entrySet()) {
626 encoderMap.put(e.getKey(), DataBlockEncoding.valueOf((e.getValue())));
627 }
628 return encoderMap;
629 }
630
631
632
633
634
635
636
637
638
639 private static Map<byte[], String> createFamilyConfValueMap(
640 Configuration conf, String confName) {
641 Map<byte[], String> confValMap = new TreeMap<byte[], String>(Bytes.BYTES_COMPARATOR);
642 String confVal = conf.get(confName, "");
643 for (String familyConf : confVal.split("&")) {
644 String[] familySplit = familyConf.split("=");
645 if (familySplit.length != 2) {
646 continue;
647 }
648 try {
649 confValMap.put(URLDecoder.decode(familySplit[0], "UTF-8").getBytes(),
650 URLDecoder.decode(familySplit[1], "UTF-8"));
651 } catch (UnsupportedEncodingException e) {
652
653 throw new AssertionError(e);
654 }
655 }
656 return confValMap;
657 }
658
659
660
661
662
663 static void configurePartitioner(Job job, List<ImmutableBytesWritable> splitPoints)
664 throws IOException {
665 Configuration conf = job.getConfiguration();
666
667 FileSystem fs = FileSystem.get(conf);
668 String hbaseTmpFsDir =
669 conf.get(HConstants.TEMPORARY_FS_DIRECTORY_KEY,
670 HConstants.DEFAULT_TEMPORARY_HDFS_DIRECTORY);
671 Path partitionsPath = new Path(hbaseTmpFsDir, "partitions_" + UUID.randomUUID());
672 fs.makeQualified(partitionsPath);
673 writePartitions(conf, partitionsPath, splitPoints);
674 fs.deleteOnExit(partitionsPath);
675
676
677 job.setPartitionerClass(TotalOrderPartitioner.class);
678 TotalOrderPartitioner.setPartitionFile(conf, partitionsPath);
679 }
680
681
682
683
684
685
686
687
688
689
690 @edu.umd.cs.findbugs.annotations.SuppressWarnings(
691 value="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE")
692 @VisibleForTesting
693 static void configureCompression(Configuration conf, HTableDescriptor tableDescriptor)
694 throws UnsupportedEncodingException {
695 StringBuilder compressionConfigValue = new StringBuilder();
696 if(tableDescriptor == null){
697
698 return;
699 }
700 Collection<HColumnDescriptor> families = tableDescriptor.getFamilies();
701 int i = 0;
702 for (HColumnDescriptor familyDescriptor : families) {
703 if (i++ > 0) {
704 compressionConfigValue.append('&');
705 }
706 compressionConfigValue.append(URLEncoder.encode(
707 familyDescriptor.getNameAsString(), "UTF-8"));
708 compressionConfigValue.append('=');
709 compressionConfigValue.append(URLEncoder.encode(
710 familyDescriptor.getCompression().getName(), "UTF-8"));
711 }
712
713 conf.set(COMPRESSION_FAMILIES_CONF_KEY, compressionConfigValue.toString());
714 }
715
716
717
718
719
720
721
722
723
724
725 @VisibleForTesting
726 static void configureBlockSize(HTableDescriptor tableDescriptor, Configuration conf)
727 throws UnsupportedEncodingException {
728 StringBuilder blockSizeConfigValue = new StringBuilder();
729 if (tableDescriptor == null) {
730
731 return;
732 }
733 Collection<HColumnDescriptor> families = tableDescriptor.getFamilies();
734 int i = 0;
735 for (HColumnDescriptor familyDescriptor : families) {
736 if (i++ > 0) {
737 blockSizeConfigValue.append('&');
738 }
739 blockSizeConfigValue.append(URLEncoder.encode(
740 familyDescriptor.getNameAsString(), "UTF-8"));
741 blockSizeConfigValue.append('=');
742 blockSizeConfigValue.append(URLEncoder.encode(
743 String.valueOf(familyDescriptor.getBlocksize()), "UTF-8"));
744 }
745
746 conf.set(BLOCK_SIZE_FAMILIES_CONF_KEY, blockSizeConfigValue.toString());
747 }
748
749
750
751
752
753
754
755
756
757
758 @VisibleForTesting
759 static void configureBloomType(HTableDescriptor tableDescriptor, Configuration conf)
760 throws UnsupportedEncodingException {
761 if (tableDescriptor == null) {
762
763 return;
764 }
765 StringBuilder bloomTypeConfigValue = new StringBuilder();
766 Collection<HColumnDescriptor> families = tableDescriptor.getFamilies();
767 int i = 0;
768 for (HColumnDescriptor familyDescriptor : families) {
769 if (i++ > 0) {
770 bloomTypeConfigValue.append('&');
771 }
772 bloomTypeConfigValue.append(URLEncoder.encode(
773 familyDescriptor.getNameAsString(), "UTF-8"));
774 bloomTypeConfigValue.append('=');
775 String bloomType = familyDescriptor.getBloomFilterType().toString();
776 if (bloomType == null) {
777 bloomType = HColumnDescriptor.DEFAULT_BLOOMFILTER;
778 }
779 bloomTypeConfigValue.append(URLEncoder.encode(bloomType, "UTF-8"));
780 }
781 conf.set(BLOOM_TYPE_FAMILIES_CONF_KEY, bloomTypeConfigValue.toString());
782 }
783
784
785
786
787
788
789
790
791
792
793 @VisibleForTesting
794 static void configureDataBlockEncoding(HTableDescriptor tableDescriptor,
795 Configuration conf) throws UnsupportedEncodingException {
796 if (tableDescriptor == null) {
797
798 return;
799 }
800 StringBuilder dataBlockEncodingConfigValue = new StringBuilder();
801 Collection<HColumnDescriptor> families = tableDescriptor.getFamilies();
802 int i = 0;
803 for (HColumnDescriptor familyDescriptor : families) {
804 if (i++ > 0) {
805 dataBlockEncodingConfigValue.append('&');
806 }
807 dataBlockEncodingConfigValue.append(
808 URLEncoder.encode(familyDescriptor.getNameAsString(), "UTF-8"));
809 dataBlockEncodingConfigValue.append('=');
810 DataBlockEncoding encoding = familyDescriptor.getDataBlockEncoding();
811 if (encoding == null) {
812 encoding = DataBlockEncoding.NONE;
813 }
814 dataBlockEncodingConfigValue.append(URLEncoder.encode(encoding.toString(),
815 "UTF-8"));
816 }
817 conf.set(DATABLOCK_ENCODING_FAMILIES_CONF_KEY,
818 dataBlockEncodingConfigValue.toString());
819 }
820 }