5252import org .apache .doris .metric .Metric ;
5353import org .apache .doris .metric .MetricLabel ;
5454import org .apache .doris .metric .MetricRepo ;
55- import org .apache .doris .planner . ColumnBound ;
55+ import org .apache .doris .nereids . rules . expression . rules . SortedPartitionRanges ;
5656import org .apache .doris .planner .ListPartitionPrunerV2 ;
57- import org .apache .doris .planner .PartitionPrunerV2Base .UniqueId ;
5857
5958import com .github .benmanes .caffeine .cache .CacheLoader ;
6059import com .github .benmanes .caffeine .cache .LoadingCache ;
6665import com .google .common .collect .Iterables ;
6766import com .google .common .collect .Lists ;
6867import com .google .common .collect .Maps ;
69- import com .google .common .collect .Range ;
70- import com .google .common .collect .RangeMap ;
7168import com .google .common .collect .Streams ;
72- import com .google .common .collect .TreeRangeMap ;
7369import lombok .Data ;
7470import org .apache .commons .lang3 .math .NumberUtils ;
7571import org .apache .hadoop .fs .BlockLocation ;
@@ -251,7 +247,6 @@ private HivePartitionValues loadPartitionValues(PartitionValueCacheKey key) {
251247 }
252248 Map <Long , PartitionItem > idToPartitionItem = Maps .newHashMapWithExpectedSize (partitionNames .size ());
253249 BiMap <String , Long > partitionNameToIdMap = HashBiMap .create (partitionNames .size ());
254- Map <Long , List <UniqueId >> idToUniqueIdsMap = Maps .newHashMapWithExpectedSize (partitionNames .size ());
255250 for (String partitionName : partitionNames ) {
256251 long partitionId = Util .genIdByName (catalog .getName (), nameMapping .getLocalDbName (),
257252 nameMapping .getLocalTblName (), partitionName );
@@ -260,23 +255,8 @@ private HivePartitionValues loadPartitionValues(PartitionValueCacheKey key) {
260255 partitionNameToIdMap .put (partitionName , partitionId );
261256 }
262257
263- Map <UniqueId , Range <PartitionKey >> uidToPartitionRange = null ;
264- Map <Range <PartitionKey >, UniqueId > rangeToId = null ;
265- RangeMap <ColumnBound , UniqueId > singleColumnRangeMap = null ;
266- Map <UniqueId , Range <ColumnBound >> singleUidToColumnRangeMap = null ;
267- if (key .types .size () > 1 ) {
268- // uidToPartitionRange and rangeToId are only used for multi-column partition
269- uidToPartitionRange = ListPartitionPrunerV2 .genUidToPartitionRange (idToPartitionItem , idToUniqueIdsMap );
270- rangeToId = ListPartitionPrunerV2 .genRangeToId (uidToPartitionRange );
271- } else {
272- Preconditions .checkState (key .types .size () == 1 , key .types );
273- // singleColumnRangeMap is only used for single-column partition
274- singleColumnRangeMap = ListPartitionPrunerV2 .genSingleColumnRangeMap (idToPartitionItem , idToUniqueIdsMap );
275- singleUidToColumnRangeMap = ListPartitionPrunerV2 .genSingleUidToColumnRange (singleColumnRangeMap );
276- }
277258 Map <Long , List <String >> partitionValuesMap = ListPartitionPrunerV2 .getPartitionValuesMap (idToPartitionItem );
278- return new HivePartitionValues (idToPartitionItem , uidToPartitionRange , rangeToId , singleColumnRangeMap ,
279- partitionNameToIdMap , idToUniqueIdsMap , singleUidToColumnRangeMap , partitionValuesMap );
259+ return new HivePartitionValues (idToPartitionItem , partitionNameToIdMap , partitionValuesMap );
280260 }
281261
282262 private ListPartitionItem toListPartitionItem (String partitionName , List <Type > types ) {
@@ -661,7 +641,6 @@ public void addPartitionsCache(NameMapping nameMapping, List<String> partitionNa
661641 HivePartitionValues copy = partitionValues .copy ();
662642 Map <Long , PartitionItem > idToPartitionItemBefore = copy .getIdToPartitionItem ();
663643 Map <String , Long > partitionNameToIdMapBefore = copy .getPartitionNameToIdMap ();
664- Map <Long , List <UniqueId >> idToUniqueIdsMap = copy .getIdToUniqueIdsMap ();
665644 Map <Long , PartitionItem > idToPartitionItem = new HashMap <>();
666645 String localDbName = nameMapping .getLocalDbName ();
667646 String localTblName = nameMapping .getLocalTblName ();
@@ -679,28 +658,8 @@ public void addPartitionsCache(NameMapping nameMapping, List<String> partitionNa
679658 Map <Long , List <String >> partitionValuesMapBefore = copy .getPartitionValuesMap ();
680659 Map <Long , List <String >> partitionValuesMap = ListPartitionPrunerV2 .getPartitionValuesMap (idToPartitionItem );
681660 partitionValuesMapBefore .putAll (partitionValuesMap );
682- if (key .types .size () > 1 ) {
683- Map <UniqueId , Range <PartitionKey >> uidToPartitionRangeBefore = copy .getUidToPartitionRange ();
684- // uidToPartitionRange and rangeToId are only used for multi-column partition
685- Map <UniqueId , Range <PartitionKey >> uidToPartitionRange = ListPartitionPrunerV2
686- .genUidToPartitionRange (idToPartitionItem , idToUniqueIdsMap );
687- uidToPartitionRangeBefore .putAll (uidToPartitionRange );
688- Map <Range <PartitionKey >, UniqueId > rangeToIdBefore = copy .getRangeToId ();
689- Map <Range <PartitionKey >, UniqueId > rangeToId = ListPartitionPrunerV2 .genRangeToId (uidToPartitionRange );
690- rangeToIdBefore .putAll (rangeToId );
691- } else {
692- Preconditions .checkState (key .types .size () == 1 , key .types );
693- // singleColumnRangeMap is only used for single-column partition
694- RangeMap <ColumnBound , UniqueId > singleColumnRangeMapBefore = copy .getSingleColumnRangeMap ();
695- RangeMap <ColumnBound , UniqueId > singleColumnRangeMap = ListPartitionPrunerV2
696- .genSingleColumnRangeMap (idToPartitionItem , idToUniqueIdsMap );
697- singleColumnRangeMapBefore .putAll (singleColumnRangeMap );
698- Map <UniqueId , Range <ColumnBound >> singleUidToColumnRangeMapBefore = copy
699- .getSingleUidToColumnRangeMap ();
700- Map <UniqueId , Range <ColumnBound >> singleUidToColumnRangeMap = ListPartitionPrunerV2
701- .genSingleUidToColumnRange (singleColumnRangeMap );
702- singleUidToColumnRangeMapBefore .putAll (singleUidToColumnRangeMap );
703- }
661+ // Rebuild sorted partition ranges after adding partitions
662+ copy .rebuildSortedPartitionRanges ();
704663 HivePartitionValues partitionValuesCur = partitionValuesCache .getIfPresent (key );
705664 if (partitionValuesCur == partitionValues ) {
706665 partitionValuesCache .put (key , copy );
@@ -718,11 +677,6 @@ public void dropPartitionsCache(ExternalTable dorisTable, List<String> partition
718677 HivePartitionValues copy = partitionValues .copy ();
719678 Map <String , Long > partitionNameToIdMapBefore = copy .getPartitionNameToIdMap ();
720679 Map <Long , PartitionItem > idToPartitionItemBefore = copy .getIdToPartitionItem ();
721- Map <Long , List <UniqueId >> idToUniqueIdsMapBefore = copy .getIdToUniqueIdsMap ();
722- Map <UniqueId , Range <PartitionKey >> uidToPartitionRangeBefore = copy .getUidToPartitionRange ();
723- Map <Range <PartitionKey >, UniqueId > rangeToIdBefore = copy .getRangeToId ();
724- RangeMap <ColumnBound , UniqueId > singleColumnRangeMapBefore = copy .getSingleColumnRangeMap ();
725- Map <UniqueId , Range <ColumnBound >> singleUidToColumnRangeMapBefore = copy .getSingleUidToColumnRangeMap ();
726680 Map <Long , List <String >> partitionValuesMap = copy .getPartitionValuesMap ();
727681 for (String partitionName : partitionNames ) {
728682 if (!partitionNameToIdMapBefore .containsKey (partitionName )) {
@@ -733,27 +687,13 @@ public void dropPartitionsCache(ExternalTable dorisTable, List<String> partition
733687 Long partitionId = partitionNameToIdMapBefore .remove (partitionName );
734688 idToPartitionItemBefore .remove (partitionId );
735689 partitionValuesMap .remove (partitionId );
736- List <UniqueId > uniqueIds = idToUniqueIdsMapBefore .remove (partitionId );
737- for (UniqueId uniqueId : uniqueIds ) {
738- if (uidToPartitionRangeBefore != null ) {
739- Range <PartitionKey > range = uidToPartitionRangeBefore .remove (uniqueId );
740- if (range != null ) {
741- rangeToIdBefore .remove (range );
742- }
743- }
744-
745- if (singleUidToColumnRangeMapBefore != null ) {
746- Range <ColumnBound > range = singleUidToColumnRangeMapBefore .remove (uniqueId );
747- if (range != null ) {
748- singleColumnRangeMapBefore .remove (range );
749- }
750- }
751- }
752690
753691 if (invalidPartitionCache ) {
754692 invalidatePartitionCache (dorisTable , partitionName );
755693 }
756694 }
695+ // Rebuild sorted partition ranges after dropping partitions
696+ copy .rebuildSortedPartitionRanges ();
757697 HivePartitionValues partitionValuesCur = partitionValuesCache .getIfPresent (key );
758698 if (partitionValuesCur == partitionValues ) {
759699 partitionValuesCache .put (key , copy );
@@ -933,7 +873,7 @@ public boolean equals(Object obj) {
933873 return dummyKey == ((FileCacheKey ) obj ).dummyKey ;
934874 }
935875 return location .equals (((FileCacheKey ) obj ).location )
936- && Objects .equals (partitionValues , ((FileCacheKey ) obj ).partitionValues );
876+ && Objects .equals (partitionValues , ((FileCacheKey ) obj ).partitionValues );
937877 }
938878
939879 boolean isSameTable (long id ) {
@@ -1031,54 +971,69 @@ public static class HiveFileStatus {
1031971 @ Data
1032972 public static class HivePartitionValues {
1033973 private BiMap <String , Long > partitionNameToIdMap ;
1034- private Map <Long , List <UniqueId >> idToUniqueIdsMap ;
1035974 private Map <Long , PartitionItem > idToPartitionItem ;
1036975 private Map <Long , List <String >> partitionValuesMap ;
1037- //multi pair
1038- private Map <UniqueId , Range <PartitionKey >> uidToPartitionRange ;
1039- private Map <Range <PartitionKey >, UniqueId > rangeToId ;
1040- //single pair
1041- private RangeMap <ColumnBound , UniqueId > singleColumnRangeMap ;
1042- private Map <UniqueId , Range <ColumnBound >> singleUidToColumnRangeMap ;
976+
977+ // Sorted partition ranges for binary search filtering.
978+ // Built at construction time, shares the same lifecycle with HivePartitionValues.
979+ private SortedPartitionRanges <String > sortedPartitionRanges ;
1043980
1044981 public HivePartitionValues () {
1045982 }
1046983
1047984 public HivePartitionValues (Map <Long , PartitionItem > idToPartitionItem ,
1048- Map <UniqueId , Range <PartitionKey >> uidToPartitionRange ,
1049- Map <Range <PartitionKey >, UniqueId > rangeToId ,
1050- RangeMap <ColumnBound , UniqueId > singleColumnRangeMap ,
1051985 BiMap <String , Long > partitionNameToIdMap ,
1052- Map <Long , List <UniqueId >> idToUniqueIdsMap ,
1053- Map <UniqueId , Range <ColumnBound >> singleUidToColumnRangeMap ,
1054986 Map <Long , List <String >> partitionValuesMap ) {
1055987 this .idToPartitionItem = idToPartitionItem ;
1056- this .uidToPartitionRange = uidToPartitionRange ;
1057- this .rangeToId = rangeToId ;
1058- this .singleColumnRangeMap = singleColumnRangeMap ;
1059988 this .partitionNameToIdMap = partitionNameToIdMap ;
1060- this .idToUniqueIdsMap = idToUniqueIdsMap ;
1061- this .singleUidToColumnRangeMap = singleUidToColumnRangeMap ;
1062989 this .partitionValuesMap = partitionValuesMap ;
990+ this .sortedPartitionRanges = buildSortedPartitionRanges ();
1063991 }
1064992
993+ /**
994+ * Create a copy for incremental updates (add/drop partitions).
995+ * The sortedPartitionRanges will be rebuilt after the caller modifies the partition data.
996+ */
1065997 public HivePartitionValues copy () {
1066998 HivePartitionValues copy = new HivePartitionValues ();
1067999 copy .setPartitionNameToIdMap (partitionNameToIdMap == null ? null : HashBiMap .create (partitionNameToIdMap ));
1068- copy .setIdToUniqueIdsMap (idToUniqueIdsMap == null ? null : Maps .newHashMap (idToUniqueIdsMap ));
10691000 copy .setIdToPartitionItem (idToPartitionItem == null ? null : Maps .newHashMap (idToPartitionItem ));
10701001 copy .setPartitionValuesMap (partitionValuesMap == null ? null : Maps .newHashMap (partitionValuesMap ));
1071- copy .setUidToPartitionRange (uidToPartitionRange == null ? null : Maps .newHashMap (uidToPartitionRange ));
1072- copy .setRangeToId (rangeToId == null ? null : Maps .newHashMap (rangeToId ));
1073- copy .setSingleUidToColumnRangeMap (
1074- singleUidToColumnRangeMap == null ? null : Maps .newHashMap (singleUidToColumnRangeMap ));
1075- if (singleColumnRangeMap != null ) {
1076- RangeMap <ColumnBound , UniqueId > copySingleColumnRangeMap = TreeRangeMap .create ();
1077- copySingleColumnRangeMap .putAll (singleColumnRangeMap );
1078- copy .setSingleColumnRangeMap (copySingleColumnRangeMap );
1079- }
1002+ // sortedPartitionRanges is not copied here, caller should call rebuildSortedPartitionRanges()
1003+ // after modifying partition data
10801004 return copy ;
10811005 }
1006+
1007+ /**
1008+ * Rebuild sorted partition ranges after incremental updates.
1009+ * Should be called after add/drop partitions.
1010+ */
1011+ public void rebuildSortedPartitionRanges () {
1012+ this .sortedPartitionRanges = buildSortedPartitionRanges ();
1013+ }
1014+
1015+ /**
1016+ * Get sorted partition ranges for binary search filtering.
1017+ */
1018+ public Optional <SortedPartitionRanges <String >> getSortedPartitionRanges () {
1019+ return Optional .ofNullable (sortedPartitionRanges );
1020+ }
1021+
1022+ private SortedPartitionRanges <String > buildSortedPartitionRanges () {
1023+ if (partitionNameToIdMap == null || partitionNameToIdMap .isEmpty ()) {
1024+ return null ;
1025+ }
1026+
1027+ // Build name to partition item map for SortedPartitionRanges.buildFrom
1028+ BiMap <Long , String > idToName = partitionNameToIdMap .inverse ();
1029+ Map <String , PartitionItem > nameToPartitionItem = Maps .newHashMapWithExpectedSize (idToPartitionItem .size ());
1030+ for (Map .Entry <Long , PartitionItem > entry : idToPartitionItem .entrySet ()) {
1031+ String partitionName = idToName .get (entry .getKey ());
1032+ nameToPartitionItem .put (partitionName , entry .getValue ());
1033+ }
1034+
1035+ return SortedPartitionRanges .build (nameToPartitionItem );
1036+ }
10821037 }
10831038
10841039 /**
0 commit comments