If copyHeadChunk is true, then the head chunk (i.e. the in-memory chunk of the TSDB) is deep copied to avoid races between reads and copying chunk bytes. However, if the deletion intervals overlaps with the head chunk, then the head chunk is not copied irrespective of copyHeadChunk because it will b
(copyHeadChunk bool)
| 711 | // However, if the deletion intervals overlaps with the head chunk, then the head chunk is |
| 712 | // not copied irrespective of copyHeadChunk because it will be re-encoded later anyway. |
| 713 | func (p *populateWithDelGenericSeriesIterator) next(copyHeadChunk bool) bool { |
| 714 | if p.err != nil || p.i >= len(p.metas)-1 { |
| 715 | return false |
| 716 | } |
| 717 | |
| 718 | p.i++ |
| 719 | p.currMeta = p.metas[p.i] |
| 720 | |
| 721 | p.bufIter.Intervals = p.bufIter.Intervals[:0] |
| 722 | for _, interval := range p.intervals { |
| 723 | if p.currMeta.OverlapsClosedInterval(interval.Mint, interval.Maxt) { |
| 724 | p.bufIter.Intervals = p.bufIter.Intervals.Add(interval) |
| 725 | } |
| 726 | } |
| 727 | |
| 728 | hcr, ok := p.cr.(ChunkReaderWithCopy) |
| 729 | var iterable chunkenc.Iterable |
| 730 | if ok && copyHeadChunk && len(p.bufIter.Intervals) == 0 { |
| 731 | // ChunkOrIterableWithCopy will copy the head chunk, if it can. |
| 732 | var maxt int64 |
| 733 | p.currMeta.Chunk, iterable, maxt, p.err = hcr.ChunkOrIterableWithCopy(p.currMeta) |
| 734 | if p.currMeta.Chunk != nil { |
| 735 | // For the in-memory head chunk the index reader sets maxt as MaxInt64. We fix it here. |
| 736 | p.currMeta.MaxTime = maxt |
| 737 | } |
| 738 | } else { |
| 739 | p.currMeta.Chunk, iterable, p.err = p.cr.ChunkOrIterable(p.currMeta) |
| 740 | } |
| 741 | |
| 742 | if p.err != nil { |
| 743 | p.err = fmt.Errorf("cannot populate chunk %d from block %s: %w", p.currMeta.Ref, p.blockID.String(), p.err) |
| 744 | return false |
| 745 | } |
| 746 | |
| 747 | // Use the single chunk if possible. |
| 748 | if p.currMeta.Chunk != nil { |
| 749 | if len(p.bufIter.Intervals) == 0 { |
| 750 | // If there is no overlap with deletion intervals and a single chunk is |
| 751 | // returned, we can take chunk as it is. |
| 752 | p.currDelIter = nil |
| 753 | return true |
| 754 | } |
| 755 | // Otherwise we need to iterate over the samples in the single chunk |
| 756 | // and create new chunks. |
| 757 | p.bufIter.Iter = p.currMeta.Chunk.Iterator(p.bufIter.Iter) |
| 758 | p.currDelIter = &p.bufIter |
| 759 | return true |
| 760 | } |
| 761 | |
| 762 | // Otherwise, use the iterable to create an iterator. |
| 763 | p.bufIter.Iter = iterable.Iterator(p.bufIter.Iter) |
| 764 | p.currDelIter = &p.bufIter |
| 765 | return true |
| 766 | } |
| 767 | |
| 768 | func (p *populateWithDelGenericSeriesIterator) Err() error { return p.err } |
| 769 |