github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/segment/query/metadata/metautils/metacheckers.go (about)

     1  /*
     2  Copyright 2023.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package metautils
    18  
    19  import (
    20  	"github.com/bits-and-blooms/bloom/v3"
    21  	dtu "github.com/siglens/siglens/pkg/common/dtypeutils"
    22  	"github.com/siglens/siglens/pkg/segment/structs"
    23  	"github.com/siglens/siglens/pkg/segment/utils"
    24  	log "github.com/sirupsen/logrus"
    25  )
    26  
    27  func CheckBloomIndex(colNames map[string]string, bloom *bloom.BloomFilter) bool {
    28  	for colName := range colNames {
    29  		if !bloom.TestString(colName) {
    30  			return false
    31  		}
    32  	}
    33  	return true
    34  }
    35  
    36  func CheckRangeIndex(filterCol map[string]string, allRangeEntries map[string]*structs.Numbers, operator utils.FilterOperator, qid uint64) bool {
    37  	var valueInRangeIndex bool
    38  	for rawColName, colVal := range filterCol {
    39  		if rawColName == "*" {
    40  			for _, ri := range allRangeEntries {
    41  				valueInRangeIndex = checkRangeIndexHelper(ri, colVal, operator, qid)
    42  				if valueInRangeIndex {
    43  					return true
    44  				}
    45  			}
    46  		} else {
    47  			if ri, ok := allRangeEntries[rawColName]; ok {
    48  				valueInRangeIndex = checkRangeIndexHelper(ri, colVal, operator, qid)
    49  				if valueInRangeIndex {
    50  					return true
    51  				}
    52  			}
    53  		}
    54  	}
    55  	return false
    56  }
    57  
    58  func checkRangeIndexHelper(ri *structs.Numbers, colVal string, operator utils.FilterOperator, qid uint64) bool {
    59  	var valueInRangeIndex bool
    60  	if operator == utils.Equals || operator == utils.NotEquals || operator == utils.LessThan || operator == utils.LessThanOrEqualTo || operator == utils.GreaterThan || operator == utils.GreaterThanOrEqualTo {
    61  		switch ri.NumType {
    62  		case utils.RNT_UNSIGNED_INT:
    63  			convertedVal, err := dtu.ConvertToUInt(colVal, 64)
    64  			if err != nil {
    65  				log.Errorf("qid=%d checkRangeIndexHelper: Got an invalid literal for range filter: %s", qid, err)
    66  				return false
    67  			}
    68  			valueInRangeIndex = doesUintPassRangeFilter(operator, convertedVal, ri.Min_uint64, ri.Max_uint64)
    69  		case utils.RNT_SIGNED_INT:
    70  			convertedVal, err := dtu.ConvertToInt(colVal, 64)
    71  			if err != nil {
    72  				log.Errorf("qid=%d checkRangeIndexHelper: Got an invalid literal for range filter: %s", qid, err)
    73  				return false
    74  			}
    75  			valueInRangeIndex = doesIntPassRangeFilter(operator, convertedVal, ri.Min_int64, ri.Max_int64)
    76  		case utils.RNT_FLOAT64:
    77  			convertedVal, err := dtu.ConvertToFloat(colVal, 64)
    78  			if err != nil {
    79  				log.Errorf("qid=%d checkRangeIndexHelper: Got an invalid literal for range filter: %s", qid, err)
    80  				return false
    81  			}
    82  			valueInRangeIndex = doesFloatPassRangeFilter(operator, convertedVal, ri.Min_float64, ri.Max_float64)
    83  		default:
    84  			log.Errorf("qid=%d checkRangeIndexHelper: Got an invalid range index type: %d", qid, ri.NumType)
    85  		}
    86  	}
    87  	return valueInRangeIndex
    88  }
    89  
    90  func FilterBlocksByTime(bSum []*structs.BlockSummary, blkTracker *structs.BlockTracker,
    91  	timeRange *dtu.TimeRange) map[uint16]map[string]bool {
    92  
    93  	timeFilteredBlocks := make(map[uint16]map[string]bool)
    94  	for i, blockSummary := range bSum {
    95  		blkNum := uint16(i)
    96  		if blkTracker.ShouldProcessBlock(blkNum) && timeRange.CheckRangeOverLap(blockSummary.LowTs, blockSummary.HighTs) {
    97  			timeFilteredBlocks[blkNum] = make(map[string]bool)
    98  		}
    99  	}
   100  	return timeFilteredBlocks
   101  }
   102  
   103  func doesUintPassRangeFilter(op utils.FilterOperator, lookupValue uint64, minVal uint64, maxVal uint64) bool {
   104  	switch op {
   105  	case utils.Equals:
   106  		return lookupValue >= minVal && lookupValue <= maxVal
   107  	case utils.NotEquals:
   108  		if lookupValue == minVal || lookupValue == maxVal {
   109  			return false
   110  		}
   111  		return true
   112  	case utils.GreaterThan:
   113  		return lookupValue < minVal || lookupValue < maxVal
   114  	case utils.GreaterThanOrEqualTo:
   115  		return lookupValue <= minVal || lookupValue <= maxVal
   116  	case utils.LessThan:
   117  		return lookupValue > minVal || lookupValue > maxVal
   118  	case utils.LessThanOrEqualTo:
   119  		return lookupValue >= minVal || lookupValue >= maxVal
   120  	default:
   121  		return true
   122  	}
   123  }
   124  
   125  func doesIntPassRangeFilter(op utils.FilterOperator, lookupValue int64, minVal int64, maxVal int64) bool {
   126  	switch op {
   127  	case utils.Equals:
   128  		return lookupValue >= minVal && lookupValue <= maxVal
   129  	case utils.NotEquals:
   130  		if lookupValue == minVal || lookupValue == maxVal {
   131  			return false
   132  		}
   133  		return true
   134  	case utils.GreaterThan:
   135  		return lookupValue < minVal || lookupValue < maxVal
   136  	case utils.GreaterThanOrEqualTo:
   137  		return lookupValue <= minVal || lookupValue <= maxVal
   138  	case utils.LessThan:
   139  		return lookupValue > minVal || lookupValue > maxVal
   140  	case utils.LessThanOrEqualTo:
   141  		return lookupValue >= minVal || lookupValue >= maxVal
   142  	default:
   143  		return true
   144  	}
   145  }
   146  
   147  func doesFloatPassRangeFilter(op utils.FilterOperator, lookupValue float64, minVal float64, maxVal float64) bool {
   148  	switch op {
   149  	case utils.Equals:
   150  		return lookupValue >= minVal && lookupValue <= maxVal
   151  	case utils.NotEquals:
   152  		if lookupValue == minVal || lookupValue == maxVal {
   153  			return false
   154  		}
   155  		return true
   156  	case utils.GreaterThan:
   157  		return lookupValue < minVal || lookupValue < maxVal
   158  	case utils.GreaterThanOrEqualTo:
   159  		return lookupValue <= minVal || lookupValue <= maxVal
   160  	case utils.LessThan:
   161  		return lookupValue > minVal || lookupValue > maxVal
   162  	case utils.LessThanOrEqualTo:
   163  		return lookupValue >= minVal || lookupValue >= maxVal
   164  	default:
   165  		return true
   166  	}
   167  }