estimateMemUsageForBatch calculates memory usage including: * Index vector * Predicate vector * Dimension * Measurement * Sort (hash/index) * Reduce
(firstColumnSize, columnMemUsage, maxSizeAfterPreFilter int)
| 1110 | // * Sort (hash/index) |
| 1111 | // * Reduce |
| 1112 | func (qc *AQLQueryContext) estimateMemUsageForBatch(firstColumnSize, columnMemUsage, maxSizeAfterPreFilter int) (memUsage int) { |
| 1113 | // 1. columnMemUsage |
| 1114 | memUsageBeforeAgg := columnMemUsage |
| 1115 | |
| 1116 | // 2. index vector memory usage (4 bytes each) |
| 1117 | memUsageBeforeAgg += firstColumnSize * 4 |
| 1118 | |
| 1119 | // 3. predicate memory usage (1 byte each) |
| 1120 | memUsageBeforeAgg += firstColumnSize |
| 1121 | |
| 1122 | // 4. record id vector for foreign table (8 bytes each recordID) |
| 1123 | memUsageBeforeAgg += firstColumnSize * 8 * len(qc.OOPK.foreignTables) |
| 1124 | |
| 1125 | // 5. expression eval memory (max scratch space) |
| 1126 | memUsageBeforeAgg += qc.estimateExpressionEvaluationMemUsage(firstColumnSize) |
| 1127 | |
| 1128 | // 6. geoPredicateVector |
| 1129 | if qc.OOPK.geoIntersection != nil { |
| 1130 | memUsageBeforeAgg += firstColumnSize * 4 * 2 |
| 1131 | } |
| 1132 | |
| 1133 | // 7. max(memUsageBeforeAgg, sortReduceMemoryUsage) |
| 1134 | memUsage = memUsageBeforeAgg |
| 1135 | if !qc.IsNonAggregationQuery { |
| 1136 | memUsage = int(math.Max(float64(memUsage), float64(estimateSortReduceMemUsage(firstColumnSize)))) |
| 1137 | } |
| 1138 | |
| 1139 | // 8. Dimension vector memory usage (input + output) |
| 1140 | if qc.IsNonAggregationQuery { |
| 1141 | maxRowsPerBatch := maxSizeAfterPreFilter |
| 1142 | if qc.Query.Limit < maxRowsPerBatch { |
| 1143 | maxRowsPerBatch = qc.Query.Limit |
| 1144 | } |
| 1145 | memUsage += maxRowsPerBatch * qc.OOPK.DimRowBytes * 2 |
| 1146 | } else { |
| 1147 | if qc.OOPK.UseHashReduction() { |
| 1148 | // For hash reduction, need hash table with int64_t key (8 bytes) and measureBytes value. |
| 1149 | // The capacity is 2 * size. |
| 1150 | memUsage += firstColumnSize * (8 + qc.OOPK.MeasureBytes) * 2 |
| 1151 | } else { |
| 1152 | // For sort based reduction, need to allocate space for hash vectors (8bytes each) and |
| 1153 | // dim index vectors (4 bytes each) |
| 1154 | memUsage += firstColumnSize * (4 + 8) * 2 |
| 1155 | } |
| 1156 | memUsage += firstColumnSize * qc.OOPK.DimRowBytes * 2 |
| 1157 | } |
| 1158 | |
| 1159 | // 9. Measure vector memory usage (input + output) |
| 1160 | memUsage += firstColumnSize * qc.OOPK.MeasureBytes * 2 |
| 1161 | |
| 1162 | return |
| 1163 | } |
| 1164 | |
| 1165 | // memory usage duration expression (filter, dimension, measure) evaluation |
| 1166 | func (qc *AQLQueryContext) estimateExpressionEvaluationMemUsage(inputSize int) (memUsage int) { |
no test coverage detected