我们先看一下scan类描述中的功能:
用setCaching(int) 设置缓存
通过指定start 设置扫描范围
通过addFamily(byte[]) 设置加载的fm
通过addColumn(byte[],byte[]) 设置获取的列
获取时间范围之内的所有列,setTimeRange(long, long)
.................
可以禁用cacheBlock ,setCacheBlocks(boolean)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面以一个get为例:
public Scan(Get get) {
this.startRow = get.getRow();
this.stopRow = get.getRow();
this.filter = get.getFilter();
this.cacheBlocks = get.getCacheBlocks();
this.maxVersions = get.getMaxVersions();
this.tr = get.getTimeRange();
this.familyMap = get.getFamilyMap();
}
把get 封装到scan 中, 将scan 传给 RegionScanner , RegionScanner 通过获取 stores 然后下放到StoreScanner。
Get过程中涉及到的类: Get 、scan 、RegionScan 、StoreScan、scanInfo (属于store级别的)、ScanQueryMatcher 用于查询匹配。
获取所有的StoreFile,循环每个StoreFile,针对每个StoreFile获取一个StoreFile.Reader reader 主要有两个HFileReaderV1 或 HFileReaderV2,通过reader获取HFileScanner ,将 reader 和 HFileScanner封装到StoreFileScanner 中。
通过上面步骤获取到所有StoreFileScanner 和 MemStoreScanner,然后每一个scanner进行判断是不是需要,为什么还要问是不是需要内、因为某些情况下(时间范围查询、bloomFilter),
storeFileScanner
public boolean shouldUseScanner(Scan scan, SortedSet<byte[]> columns, long oldestUnexpiredTS) {
return reader.passesTimerangeFilter(scan, oldestUnexpiredTS)
&& reader.passesKeyRangeFilter(scan) && reader.passesBloomFilter(scan, columns);
}