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.regionserver; 019 020import java.io.FileNotFoundException; 021import java.io.IOException; 022import java.util.concurrent.atomic.AtomicInteger; 023import java.util.regex.Matcher; 024import java.util.regex.Pattern; 025import org.apache.hadoop.conf.Configurable; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.fs.FileStatus; 028import org.apache.hadoop.fs.FileSystem; 029import org.apache.hadoop.fs.Path; 030import org.apache.hadoop.hbase.HDFSBlocksDistribution; 031import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper; 032import org.apache.hadoop.hbase.io.HFileLink; 033import org.apache.hadoop.hbase.io.HalfStoreFileReader; 034import org.apache.hadoop.hbase.io.Reference; 035import org.apache.hadoop.hbase.io.hfile.CacheConfig; 036import org.apache.hadoop.hbase.io.hfile.HFileInfo; 037import org.apache.hadoop.hbase.io.hfile.ReaderContext; 038import org.apache.hadoop.hbase.io.hfile.ReaderContext.ReaderType; 039import org.apache.hadoop.hbase.io.hfile.ReaderContextBuilder; 040import org.apache.hadoop.hbase.mob.MobUtils; 041import org.apache.hadoop.hbase.util.FSUtils; 042import org.apache.hadoop.hbase.util.Pair; 043import org.apache.yetus.audience.InterfaceAudience; 044import org.slf4j.Logger; 045import org.slf4j.LoggerFactory; 046 047/** 048 * Describe a StoreFile (hfile, reference, link) 049 */ 050@InterfaceAudience.Private 051public class StoreFileInfo implements Configurable { 052 private static final Logger LOG = LoggerFactory.getLogger(StoreFileInfo.class); 053 054 /** 055 * A non-capture group, for hfiles, so that this can be embedded. HFiles are uuid ([0-9a-z]+). 056 * Bulk loaded hfiles has (_SeqId_[0-9]+_) has suffix. The mob del file has (_del) as suffix. 057 */ 058 public static final String HFILE_NAME_REGEX = "[0-9a-f]+(?:(?:_SeqId_[0-9]+_)|(?:_del))?"; 059 060 /** Regex that will work for hfiles */ 061 private static final Pattern HFILE_NAME_PATTERN = Pattern.compile("^(" + HFILE_NAME_REGEX + ")"); 062 063 /** 064 * Regex that will work for straight reference names ({@code <hfile>.<parentEncRegion>}) and 065 * hfilelink reference names ({@code 066 * 067 <table> 068 * =<region>-<hfile>.<parentEncRegion>}) If reference, then the regex has more than just one 069 * group. Group 1, hfile/hfilelink pattern, is this file's id. Group 2 '(.+)' is the reference's 070 * parent region name. 071 */ 072 private static final Pattern REF_NAME_PATTERN = 073 Pattern.compile(String.format("^(%s|%s)\\.(.+)$", HFILE_NAME_REGEX, HFileLink.LINK_NAME_REGEX)); 074 075 public static final String STORE_FILE_READER_NO_READAHEAD = "hbase.store.reader.no-readahead"; 076 public static final boolean DEFAULT_STORE_FILE_READER_NO_READAHEAD = false; 077 078 // Configuration 079 private Configuration conf; 080 081 // FileSystem handle 082 private final FileSystem fs; 083 084 // HDFS blocks distribution information 085 private HDFSBlocksDistribution hdfsBlocksDistribution = null; 086 087 private HFileInfo hfileInfo; 088 089 // If this storefile references another, this is the reference instance. 090 private final Reference reference; 091 092 // If this storefile is a link to another, this is the link instance. 093 private final HFileLink link; 094 095 private final Path initialPath; 096 097 private RegionCoprocessorHost coprocessorHost; 098 099 // timestamp on when the file was created, is 0 and ignored for reference or link files 100 private long createdTimestamp; 101 102 private long size; 103 104 private final boolean primaryReplica; 105 106 private final boolean noReadahead; 107 108 // Counter that is incremented every time a scanner is created on the 109 // store file. It is decremented when the scan on the store file is 110 // done. 111 final AtomicInteger refCount = new AtomicInteger(0); 112 113 /** 114 * Create a Store File Info 115 * @param conf the {@link Configuration} to use 116 * @param fs The current file system to use. 117 * @param initialPath The {@link Path} of the file 118 * @param primaryReplica true if this is a store file for primary replica, otherwise false. 119 */ 120 public StoreFileInfo(final Configuration conf, final FileSystem fs, final Path initialPath, 121 final boolean primaryReplica) throws IOException { 122 this(conf, fs, null, initialPath, primaryReplica); 123 } 124 125 private StoreFileInfo(final Configuration conf, final FileSystem fs, final FileStatus fileStatus, 126 final Path initialPath, final boolean primaryReplica) throws IOException { 127 assert fs != null; 128 assert initialPath != null; 129 assert conf != null; 130 131 this.fs = fs; 132 this.conf = conf; 133 this.initialPath = fs.makeQualified(initialPath); 134 this.primaryReplica = primaryReplica; 135 this.noReadahead = 136 this.conf.getBoolean(STORE_FILE_READER_NO_READAHEAD, DEFAULT_STORE_FILE_READER_NO_READAHEAD); 137 Path p = initialPath; 138 if (HFileLink.isHFileLink(p)) { 139 // HFileLink 140 this.reference = null; 141 this.link = HFileLink.buildFromHFileLinkPattern(conf, p); 142 LOG.trace("{} is a link", p); 143 } else if (isReference(p)) { 144 this.reference = Reference.read(fs, p); 145 Path referencePath = getReferredToFile(p); 146 if (HFileLink.isHFileLink(referencePath)) { 147 // HFileLink Reference 148 this.link = HFileLink.buildFromHFileLinkPattern(conf, referencePath); 149 } else { 150 // Reference 151 this.link = null; 152 } 153 LOG.trace("{} is a {} reference to {}", p, reference.getFileRegion(), referencePath); 154 } else if (isHFile(p) || isMobFile(p) || isMobRefFile(p)) { 155 // HFile 156 if (fileStatus != null) { 157 this.createdTimestamp = fileStatus.getModificationTime(); 158 this.size = fileStatus.getLen(); 159 } else { 160 FileStatus fStatus = fs.getFileStatus(initialPath); 161 this.createdTimestamp = fStatus.getModificationTime(); 162 this.size = fStatus.getLen(); 163 } 164 this.reference = null; 165 this.link = null; 166 } else { 167 throw new IOException("path=" + p + " doesn't look like a valid StoreFile"); 168 } 169 } 170 171 /** 172 * Create a Store File Info 173 * @param conf the {@link Configuration} to use 174 * @param fs The current file system to use. 175 * @param fileStatus The {@link FileStatus} of the file 176 */ 177 public StoreFileInfo(final Configuration conf, final FileSystem fs, final FileStatus fileStatus) 178 throws IOException { 179 this(conf, fs, fileStatus, fileStatus.getPath(), true); 180 } 181 182 /** 183 * Create a Store File Info from an HFileLink 184 * @param conf The {@link Configuration} to use 185 * @param fs The current file system to use 186 * @param fileStatus The {@link FileStatus} of the file 187 */ 188 public StoreFileInfo(final Configuration conf, final FileSystem fs, final FileStatus fileStatus, 189 final HFileLink link) { 190 this(conf, fs, fileStatus, null, link); 191 } 192 193 /** 194 * Create a Store File Info from an HFileLink 195 * @param conf The {@link Configuration} to use 196 * @param fs The current file system to use 197 * @param fileStatus The {@link FileStatus} of the file 198 * @param reference The reference instance 199 */ 200 public StoreFileInfo(final Configuration conf, final FileSystem fs, final FileStatus fileStatus, 201 final Reference reference) { 202 this(conf, fs, fileStatus, reference, null); 203 } 204 205 /** 206 * Create a Store File Info from an HFileLink and a Reference 207 * @param conf The {@link Configuration} to use 208 * @param fs The current file system to use 209 * @param fileStatus The {@link FileStatus} of the file 210 * @param reference The reference instance 211 * @param link The link instance 212 */ 213 public StoreFileInfo(final Configuration conf, final FileSystem fs, final FileStatus fileStatus, 214 final Reference reference, final HFileLink link) { 215 this.fs = fs; 216 this.conf = conf; 217 this.primaryReplica = false; 218 this.initialPath = (fileStatus == null) ? null : fileStatus.getPath(); 219 this.createdTimestamp = (fileStatus == null) ? 0 : fileStatus.getModificationTime(); 220 this.reference = reference; 221 this.link = link; 222 this.noReadahead = 223 this.conf.getBoolean(STORE_FILE_READER_NO_READAHEAD, DEFAULT_STORE_FILE_READER_NO_READAHEAD); 224 } 225 226 @Override 227 public Configuration getConf() { 228 return conf; 229 } 230 231 @Override 232 public void setConf(Configuration conf) { 233 this.conf = conf; 234 } 235 236 /** 237 * Size of the Hfile n 238 */ 239 public long getSize() { 240 return size; 241 } 242 243 /** 244 * Sets the region coprocessor env. n 245 */ 246 public void setRegionCoprocessorHost(RegionCoprocessorHost coprocessorHost) { 247 this.coprocessorHost = coprocessorHost; 248 } 249 250 /** 251 * @return the Reference object associated to this StoreFileInfo. null if the StoreFile is not a 252 * reference. 253 */ 254 public Reference getReference() { 255 return this.reference; 256 } 257 258 /** Returns True if the store file is a Reference */ 259 public boolean isReference() { 260 return this.reference != null; 261 } 262 263 /** Returns True if the store file is a top Reference */ 264 public boolean isTopReference() { 265 return this.reference != null && Reference.isTopFileRegion(this.reference.getFileRegion()); 266 } 267 268 /** Returns True if the store file is a link */ 269 public boolean isLink() { 270 return this.link != null && this.reference == null; 271 } 272 273 /** Returns the HDFS block distribution */ 274 public HDFSBlocksDistribution getHDFSBlockDistribution() { 275 return this.hdfsBlocksDistribution; 276 } 277 278 StoreFileReader createReader(ReaderContext context, CacheConfig cacheConf) throws IOException { 279 StoreFileReader reader = null; 280 if (this.reference != null) { 281 reader = new HalfStoreFileReader(context, hfileInfo, cacheConf, reference, refCount, conf); 282 } else { 283 reader = new StoreFileReader(context, hfileInfo, cacheConf, refCount, conf); 284 } 285 return reader; 286 } 287 288 ReaderContext createReaderContext(boolean doDropBehind, long readahead, ReaderType type) 289 throws IOException { 290 FSDataInputStreamWrapper in; 291 FileStatus status; 292 if (this.link != null) { 293 // HFileLink 294 in = new FSDataInputStreamWrapper(fs, this.link, doDropBehind, readahead); 295 status = this.link.getFileStatus(fs); 296 } else if (this.reference != null) { 297 // HFile Reference 298 Path referencePath = getReferredToFile(this.getPath()); 299 try { 300 in = new FSDataInputStreamWrapper(fs, referencePath, doDropBehind, readahead); 301 } catch (FileNotFoundException fnfe) { 302 // Intercept the exception so can insert more info about the Reference; otherwise 303 // exception just complains about some random file -- operator doesn't realize it 304 // other end of a Reference 305 FileNotFoundException newFnfe = new FileNotFoundException(toString()); 306 newFnfe.initCause(fnfe); 307 throw newFnfe; 308 } 309 status = fs.getFileStatus(referencePath); 310 } else { 311 in = new FSDataInputStreamWrapper(fs, this.getPath(), doDropBehind, readahead); 312 status = fs.getFileStatus(initialPath); 313 } 314 long length = status.getLen(); 315 ReaderContextBuilder contextBuilder = 316 new ReaderContextBuilder().withInputStreamWrapper(in).withFileSize(length) 317 .withPrimaryReplicaReader(this.primaryReplica).withReaderType(type).withFileSystem(fs); 318 if (this.reference != null) { 319 contextBuilder.withFilePath(this.getPath()); 320 } else { 321 contextBuilder.withFilePath(status.getPath()); 322 } 323 return contextBuilder.build(); 324 } 325 326 /** 327 * Compute the HDFS Block Distribution for this StoreFile 328 */ 329 public HDFSBlocksDistribution computeHDFSBlocksDistribution(final FileSystem fs) 330 throws IOException { 331 // guard against the case where we get the FileStatus from link, but by the time we 332 // call compute the file is moved again 333 if (this.link != null) { 334 FileNotFoundException exToThrow = null; 335 for (int i = 0; i < this.link.getLocations().length; i++) { 336 try { 337 return computeHDFSBlocksDistributionInternal(fs); 338 } catch (FileNotFoundException ex) { 339 // try the other location 340 exToThrow = ex; 341 } 342 } 343 throw exToThrow; 344 } else { 345 return computeHDFSBlocksDistributionInternal(fs); 346 } 347 } 348 349 private HDFSBlocksDistribution computeHDFSBlocksDistributionInternal(final FileSystem fs) 350 throws IOException { 351 FileStatus status = getReferencedFileStatus(fs); 352 if (this.reference != null) { 353 return computeRefFileHDFSBlockDistribution(fs, reference, status); 354 } else { 355 return FSUtils.computeHDFSBlocksDistribution(fs, status, 0, status.getLen()); 356 } 357 } 358 359 /** 360 * Get the {@link FileStatus} of the file referenced by this StoreFileInfo 361 * @param fs The current file system to use. 362 * @return The {@link FileStatus} of the file referenced by this StoreFileInfo 363 */ 364 public FileStatus getReferencedFileStatus(final FileSystem fs) throws IOException { 365 FileStatus status; 366 if (this.reference != null) { 367 if (this.link != null) { 368 FileNotFoundException exToThrow = null; 369 for (int i = 0; i < this.link.getLocations().length; i++) { 370 // HFileLink Reference 371 try { 372 return link.getFileStatus(fs); 373 } catch (FileNotFoundException ex) { 374 // try the other location 375 exToThrow = ex; 376 } 377 } 378 throw exToThrow; 379 } else { 380 // HFile Reference 381 Path referencePath = getReferredToFile(this.getPath()); 382 status = fs.getFileStatus(referencePath); 383 } 384 } else { 385 if (this.link != null) { 386 FileNotFoundException exToThrow = null; 387 for (int i = 0; i < this.link.getLocations().length; i++) { 388 // HFileLink 389 try { 390 return link.getFileStatus(fs); 391 } catch (FileNotFoundException ex) { 392 // try the other location 393 exToThrow = ex; 394 } 395 } 396 throw exToThrow; 397 } else { 398 status = fs.getFileStatus(initialPath); 399 } 400 } 401 return status; 402 } 403 404 /** Returns The {@link Path} of the file */ 405 public Path getPath() { 406 return initialPath; 407 } 408 409 /** Returns The {@link FileStatus} of the file */ 410 public FileStatus getFileStatus() throws IOException { 411 return getReferencedFileStatus(fs); 412 } 413 414 /** Returns Get the modification time of the file. */ 415 public long getModificationTime() throws IOException { 416 return getFileStatus().getModificationTime(); 417 } 418 419 @Override 420 public String toString() { 421 return this.getPath() 422 + (isReference() ? "->" + getReferredToFile(this.getPath()) + "-" + reference : ""); 423 } 424 425 /** 426 * @param path Path to check. 427 * @return True if the path has format of a HFile. 428 */ 429 public static boolean isHFile(final Path path) { 430 return isHFile(path.getName()); 431 } 432 433 public static boolean isHFile(final String fileName) { 434 Matcher m = HFILE_NAME_PATTERN.matcher(fileName); 435 return m.matches() && m.groupCount() > 0; 436 } 437 438 /** 439 * Checks if the file is a MOB file 440 * @param path path to a file 441 * @return true, if - yes, false otherwise 442 */ 443 public static boolean isMobFile(final Path path) { 444 String fileName = path.getName(); 445 String[] parts = fileName.split(MobUtils.SEP); 446 if (parts.length != 2) { 447 return false; 448 } 449 Matcher m = HFILE_NAME_PATTERN.matcher(parts[0]); 450 Matcher mm = HFILE_NAME_PATTERN.matcher(parts[1]); 451 return m.matches() && mm.matches(); 452 } 453 454 /** 455 * Checks if the file is a MOB reference file, created by snapshot 456 * @param path path to a file 457 * @return true, if - yes, false otherwise 458 */ 459 public static boolean isMobRefFile(final Path path) { 460 String fileName = path.getName(); 461 int lastIndex = fileName.lastIndexOf(MobUtils.SEP); 462 if (lastIndex < 0) { 463 return false; 464 } 465 String[] parts = new String[2]; 466 parts[0] = fileName.substring(0, lastIndex); 467 parts[1] = fileName.substring(lastIndex + 1); 468 String name = parts[0] + "." + parts[1]; 469 Matcher m = REF_NAME_PATTERN.matcher(name); 470 return m.matches() && m.groupCount() > 1; 471 } 472 473 /** 474 * @param path Path to check. 475 * @return True if the path has format of a HStoreFile reference. 476 */ 477 public static boolean isReference(final Path path) { 478 return isReference(path.getName()); 479 } 480 481 /** 482 * @param name file name to check. 483 * @return True if the path has format of a HStoreFile reference. 484 */ 485 public static boolean isReference(final String name) { 486 Matcher m = REF_NAME_PATTERN.matcher(name); 487 return m.matches() && m.groupCount() > 1; 488 } 489 490 /** Returns timestamp when this file was created (as returned by filesystem) */ 491 public long getCreatedTimestamp() { 492 return createdTimestamp; 493 } 494 495 /* 496 * Return path to the file referred to by a Reference. Presumes a directory hierarchy of 497 * <code>${hbase.rootdir}/data/${namespace}/tablename/regionname/familyname</code>. 498 * @param p Path to a Reference file. 499 * @return Calculated path to parent region file. 500 * @throws IllegalArgumentException when path regex fails to match. 501 */ 502 public static Path getReferredToFile(final Path p) { 503 Matcher m = REF_NAME_PATTERN.matcher(p.getName()); 504 if (m == null || !m.matches()) { 505 LOG.warn("Failed match of store file name {}", p.toString()); 506 throw new IllegalArgumentException("Failed match of store file name " + p.toString()); 507 } 508 509 // Other region name is suffix on the passed Reference file name 510 String otherRegion = m.group(2); 511 // Tabledir is up two directories from where Reference was written. 512 Path tableDir = p.getParent().getParent().getParent(); 513 String nameStrippedOfSuffix = m.group(1); 514 LOG.trace("reference {} to region={} hfile={}", p, otherRegion, nameStrippedOfSuffix); 515 516 // Build up new path with the referenced region in place of our current 517 // region in the reference path. Also strip regionname suffix from name. 518 return new Path(new Path(new Path(tableDir, otherRegion), p.getParent().getName()), 519 nameStrippedOfSuffix); 520 } 521 522 /* 523 * Return region and file name referred to by a Reference. 524 * @param referenceFile HFile name which is a Reference. 525 * @return Calculated referenced region and file name. 526 * @throws IllegalArgumentException when referenceFile regex fails to match. 527 */ 528 public static Pair<String, String> getReferredToRegionAndFile(final String referenceFile) { 529 Matcher m = REF_NAME_PATTERN.matcher(referenceFile); 530 if (m == null || !m.matches()) { 531 LOG.warn("Failed match of store file name {}", referenceFile); 532 throw new IllegalArgumentException("Failed match of store file name " + referenceFile); 533 } 534 String referencedRegion = m.group(2); 535 String referencedFile = m.group(1); 536 LOG.trace("reference {} to region={} file={}", referenceFile, referencedRegion, referencedFile); 537 return new Pair<>(referencedRegion, referencedFile); 538 } 539 540 /** 541 * Validate the store file name. 542 * @param fileName name of the file to validate 543 * @return <tt>true</tt> if the file could be a valid store file, <tt>false</tt> otherwise 544 */ 545 public static boolean validateStoreFileName(final String fileName) { 546 if (HFileLink.isHFileLink(fileName) || isReference(fileName)) { 547 return true; 548 } 549 return !fileName.contains("-"); 550 } 551 552 /** 553 * Return if the specified file is a valid store file or not. 554 * @param fileStatus The {@link FileStatus} of the file 555 * @return <tt>true</tt> if the file is valid 556 */ 557 public static boolean isValid(final FileStatus fileStatus) throws IOException { 558 final Path p = fileStatus.getPath(); 559 560 if (fileStatus.isDirectory()) { 561 return false; 562 } 563 564 // Check for empty hfile. Should never be the case but can happen 565 // after data loss in hdfs for whatever reason (upgrade, etc.): HBASE-646 566 // NOTE: that the HFileLink is just a name, so it's an empty file. 567 if (!HFileLink.isHFileLink(p) && fileStatus.getLen() <= 0) { 568 LOG.warn("Skipping {} because it is empty. HBASE-646 DATA LOSS?", p); 569 return false; 570 } 571 572 return validateStoreFileName(p.getName()); 573 } 574 575 /** 576 * helper function to compute HDFS blocks distribution of a given reference file.For reference 577 * file, we don't compute the exact value. We use some estimate instead given it might be good 578 * enough. we assume bottom part takes the first half of reference file, top part takes the second 579 * half of the reference file. This is just estimate, given midkey ofregion != midkey of HFile, 580 * also the number and size of keys vary. If this estimate isn't good enough, we can improve it 581 * later. 582 * @param fs The FileSystem 583 * @param reference The reference 584 * @param status The reference FileStatus 585 * @return HDFS blocks distribution 586 */ 587 private static HDFSBlocksDistribution computeRefFileHDFSBlockDistribution(final FileSystem fs, 588 final Reference reference, final FileStatus status) throws IOException { 589 if (status == null) { 590 return null; 591 } 592 593 long start = 0; 594 long length = 0; 595 596 if (Reference.isTopFileRegion(reference.getFileRegion())) { 597 start = status.getLen() / 2; 598 length = status.getLen() - status.getLen() / 2; 599 } else { 600 start = 0; 601 length = status.getLen() / 2; 602 } 603 return FSUtils.computeHDFSBlocksDistribution(fs, status, start, length); 604 } 605 606 @Override 607 public boolean equals(Object that) { 608 if (this == that) { 609 return true; 610 } 611 if (that == null) { 612 return false; 613 } 614 615 if (!(that instanceof StoreFileInfo)) { 616 return false; 617 } 618 619 StoreFileInfo o = (StoreFileInfo) that; 620 if (initialPath != null && o.initialPath == null) { 621 return false; 622 } 623 if (initialPath == null && o.initialPath != null) { 624 return false; 625 } 626 if (initialPath != o.initialPath && initialPath != null && !initialPath.equals(o.initialPath)) { 627 return false; 628 } 629 if (reference != null && o.reference == null) { 630 return false; 631 } 632 if (reference == null && o.reference != null) { 633 return false; 634 } 635 if (reference != o.reference && reference != null && !reference.equals(o.reference)) { 636 return false; 637 } 638 639 if (link != null && o.link == null) { 640 return false; 641 } 642 if (link == null && o.link != null) { 643 return false; 644 } 645 if (link != o.link && link != null && !link.equals(o.link)) { 646 return false; 647 } 648 649 return true; 650 } 651 652 @Override 653 public int hashCode() { 654 int hash = 17; 655 hash = hash * 31 + ((reference == null) ? 0 : reference.hashCode()); 656 hash = hash * 31 + ((initialPath == null) ? 0 : initialPath.hashCode()); 657 hash = hash * 31 + ((link == null) ? 0 : link.hashCode()); 658 return hash; 659 } 660 661 /** 662 * Return the active file name that contains the real data. 663 * <p> 664 * For referenced hfile, we will return the name of the reference file as it will be used to 665 * construct the StoreFileReader. And for linked hfile, we will return the name of the file being 666 * linked. 667 */ 668 public String getActiveFileName() { 669 if (reference != null || link == null) { 670 return initialPath.getName(); 671 } else { 672 return HFileLink.getReferencedHFileName(initialPath.getName()); 673 } 674 } 675 676 FileSystem getFileSystem() { 677 return this.fs; 678 } 679 680 boolean isNoReadahead() { 681 return this.noReadahead; 682 } 683 684 HFileInfo getHFileInfo() { 685 return hfileInfo; 686 } 687 688 void initHDFSBlocksDistribution() throws IOException { 689 hdfsBlocksDistribution = computeHDFSBlocksDistribution(fs); 690 } 691 692 StoreFileReader preStoreFileReaderOpen(ReaderContext context, CacheConfig cacheConf) 693 throws IOException { 694 StoreFileReader reader = null; 695 if (this.coprocessorHost != null) { 696 reader = this.coprocessorHost.preStoreFileReaderOpen(fs, this.getPath(), 697 context.getInputStreamWrapper(), context.getFileSize(), cacheConf, reference); 698 } 699 return reader; 700 } 701 702 StoreFileReader postStoreFileReaderOpen(ReaderContext context, CacheConfig cacheConf, 703 StoreFileReader reader) throws IOException { 704 StoreFileReader res = reader; 705 if (this.coprocessorHost != null) { 706 res = this.coprocessorHost.postStoreFileReaderOpen(fs, this.getPath(), 707 context.getInputStreamWrapper(), context.getFileSize(), cacheConf, reference, reader); 708 } 709 return res; 710 } 711 712 public void initHFileInfo(ReaderContext context) throws IOException { 713 this.hfileInfo = new HFileInfo(context, conf); 714 } 715 716}