1. 介绍
前面分析了基于Tree的索引过滤器的实现,Hudi来提供了基于List的索引过滤器的实现:ListBasedIndexFileFilter和ListBasedGlobalIndexFileFilter,下面进行分析。
2. 分析
ListBasedIndexFileFilter
是 ListBasedGlobalIndexFileFilter
的父类,两者实现了IndexFilter接口的 getMatchingFilesAndPartition
方法。
2.1 ListBasedIndexFileFilter实现
ListBasedIndexFileFilter
的 getMatchingFilesAndPartition
方法核心代码如下
public Set<Pair<String, String>> getMatchingFilesAndPartition(String partitionPath, String recordKey) { // 获取分区对应的列表 List<BloomIndexFileInfo> indexInfos = partitionToFileIndexInfo.get(partitionPath); Set<Pair<String, String>> toReturn = new HashSet<>(); if (indexInfos != null) { // 可能为null,即当分区路径下无文件时 // 遍历列表 for (BloomIndexFileInfo indexInfo : indexInfos) { if (shouldCompareWithFile(indexInfo, recordKey)) { // 判断是否已经比较 toReturn.add(Pair.of(partitionPath, indexInfo.getFileId())); } } } return toReturn; }
可以看到该方法的逻辑非常简单,遍历分区对应的BloomIndexFileIndex列表,若判断需要比较则返回,其中 shouldCompareWithFile
方法核心代码如下
protected boolean shouldCompareWithFile(BloomIndexFileInfo indexInfo, String recordKey) { // 无最大最小recordKey或者指定recordKey在最大最小recordKey之间 return !indexInfo.hasKeyRanges() || indexInfo.isKeyInRange(recordKey); }
是否需要比较的逻辑也很简单,若无最大最小值则需要比较,或者指定recordKey在最大最小值之间也需要比较。
2.2 ListBasedGlobalIndexFileFilter实现
ListBasedIndexFileFilter
的 getMatchingFilesAndPartition
方法核心代码如下
public Set<Pair<String, String>> getMatchingFilesAndPartition(String partitionPath, String recordKey) { Set<Pair<String, String>> toReturn = new HashSet<>(); // 遍历集合 partitionToFileIndexInfo.forEach((partition, bloomIndexFileInfoList) -> bloomIndexFileInfoList.forEach(file -> { if (shouldCompareWithFile(file, recordKey)) { // 判断是否需要比较 toReturn.add(Pair.of(partition, file.getFileId())); } })); return toReturn; }
可以看到入参中的partitionPath不再起作用,直接遍历整个集合。
3. 总结
ListBasedIndexFileFilter
和 ListBasedGlobalIndexFileFilter
是基于List的索引过滤器,前者也主要用于 HoodieBloomIndex
,后者主要用于 HoodieGlobalBloomIndex
;同样前者以分区为粒度处理,后者是全局的。