MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / rows_between_offset_and_offset

Function rows_between_offset_and_offset

src/expr/src/relation/func.rs:1464–1517  ·  view source on GitHub ↗
(
            args: Vec<Datum<'a>>,
            result: &mut Vec<Datum<'a>>,
            wrapped_aggregate: &AggregateFunc,
            temp_storage: &'a RowArena,
            offset_start: i64,
     

Source from the content-addressed store, hash-verified

1462 }
1463
1464 fn rows_between_offset_and_offset<'a>(
1465 args: Vec<Datum<'a>>,
1466 result: &mut Vec<Datum<'a>>,
1467 wrapped_aggregate: &AggregateFunc,
1468 temp_storage: &'a RowArena,
1469 offset_start: i64,
1470 offset_end: i64,
1471 ) {
1472 let len = args
1473 .len()
1474 .to_i64()
1475 .expect("window partition's len should fit into i64");
1476 for i in 0..len {
1477 let i = i.to_i64().expect("window partition shouldn't be super big");
1478 // Trim the start of the frame to make it not reach over the start of the window
1479 // partition.
1480 let frame_start = max(i + offset_start, 0)
1481 .to_usize()
1482 .expect("The max made sure it's not negative");
1483 // Trim the end of the frame to make it not reach over the end of the window
1484 // partition.
1485 let frame_end = min(i + offset_end, len - 1).to_usize();
1486 match frame_end {
1487 Some(frame_end) => {
1488 if frame_start <= frame_end {
1489 // Compute the aggregate on the frame.
1490 // TODO:
1491 // This implementation is quite slow if the frame is large: we do an
1492 // inner loop over the entire frame, and compute the aggregate from
1493 // scratch. We could do better:
1494 // - For invertible aggregations we could do a rolling aggregation.
1495 // - There are various tricks for min/max as well, making use of either
1496 // the fixed size of the window, or that we are not retracting
1497 // arbitrary elements but doing queue operations. E.g., see
1498 // http://codercareer.blogspot.com/2012/02/no-33-maximums-in-sliding-windows.html
1499 let frame_values = args[frame_start..=frame_end]
1500 .iter()
1501 .map(|d| (*d, Diff::ONE));
1502 let result_value = wrapped_aggregate.eval(frame_values, temp_storage);
1503 result.push(result_value);
1504 } else {
1505 // frame_start > frame_end, so this is an empty frame.
1506 let result_value = wrapped_aggregate.default();
1507 result.push(result_value);
1508 }
1509 }
1510 None => {
1511 // frame_end would be negative, so this is an empty frame.
1512 let result_value = wrapped_aggregate.default();
1513 result.push(result_value);
1514 }
1515 }
1516 }
1517 }
1518
1519 match (
1520 &window_frame.units,

Callers 1

window_aggr_innerFunction · 0.85

Calls 7

expectMethod · 0.80
lenMethod · 0.45
mapMethod · 0.45
iterMethod · 0.45
evalMethod · 0.45
pushMethod · 0.45
defaultMethod · 0.45

Tested by

no test coverage detected