combine adds as much of the given load as possible to g.curOp and returns the number of bytes added. Preconditions: - fr.Length() > 0. - fr must be page-aligned.
(amfl *asyncMemoryFileLoad, fr memmap.FileRange, off uint64, tempRef bool)
| 1514 | // - fr.Length() > 0. |
| 1515 | // - fr must be page-aligned. |
| 1516 | func (apfl *AsyncPagesFileLoad) combine(amfl *asyncMemoryFileLoad, fr memmap.FileRange, off uint64, tempRef bool) uint64 { |
| 1517 | op := apfl.curOp |
| 1518 | if op.total != 0 { |
| 1519 | if op.end != off { |
| 1520 | // Non-contiguous in the pages file. |
| 1521 | return 0 |
| 1522 | } |
| 1523 | if op.amfl != amfl { |
| 1524 | // Differing MemoryFile. |
| 1525 | return 0 |
| 1526 | } |
| 1527 | if len(op.frs) == cap(op.frs) && op.frs[len(op.frs)-1].End != fr.Start { |
| 1528 | // Non-contiguous in the MemoryFile, and we're out of space for |
| 1529 | // FileRanges. |
| 1530 | return 0 |
| 1531 | } |
| 1532 | if op.tempRef != tempRef { |
| 1533 | // Incompatible reference-counting semantics. We could handle this |
| 1534 | // by making tempRef per-FileRange, but it's very unlikely that an |
| 1535 | // awaited load (tempRef=false) will happen to be followed by an |
| 1536 | // unawaited load (tempRef=true) at the correct offset. |
| 1537 | return 0 |
| 1538 | } |
| 1539 | } |
| 1540 | |
| 1541 | // Apply direct length limits. |
| 1542 | n := fr.Length() |
| 1543 | if op.total+n >= apfl.maxReadBytes { |
| 1544 | n = apfl.maxReadBytes - op.total |
| 1545 | } |
| 1546 | if n == 0 { |
| 1547 | return 0 |
| 1548 | } |
| 1549 | fr.End = fr.Start + n |
| 1550 | |
| 1551 | // Collect iovecs, which may further limit length. |
| 1552 | n = 0 |
| 1553 | amfl.f.forEachMappingSlice(fr, func(bs []byte) { |
| 1554 | if len(op.iovecs) > 0 { |
| 1555 | if canMergeIovecAndSlice(op.iovecs[len(op.iovecs)-1], bs) { |
| 1556 | op.iovecs[len(op.iovecs)-1].Len += uint64(len(bs)) |
| 1557 | n += uint64(len(bs)) |
| 1558 | return |
| 1559 | } |
| 1560 | if len(op.iovecs) == cap(op.iovecs) { |
| 1561 | return |
| 1562 | } |
| 1563 | } |
| 1564 | op.iovecs = append(op.iovecs, unix.Iovec{ |
| 1565 | Base: &bs[0], |
| 1566 | Len: uint64(len(bs)), |
| 1567 | }) |
| 1568 | n += uint64(len(bs)) |
| 1569 | }) |
| 1570 | if n == 0 { |
| 1571 | return 0 |
| 1572 | } |
| 1573 | fr.End = fr.Start + n |
no test coverage detected