Blocks returns a slice of block readers for persisted blocks.
()
| 726 | |
| 727 | // Blocks returns a slice of block readers for persisted blocks. |
| 728 | func (db *DBReadOnly) Blocks() ([]BlockReader, error) { |
| 729 | select { |
| 730 | case <-db.closed: |
| 731 | return nil, ErrClosed |
| 732 | default: |
| 733 | } |
| 734 | loadable, corrupted, err := openBlocks(db.logger, db.dir, nil, nil, DefaultPostingsDecoderFactory) |
| 735 | if err != nil { |
| 736 | return nil, err |
| 737 | } |
| 738 | |
| 739 | // Corrupted blocks that have been superseded by a loadable block can be safely ignored. |
| 740 | for _, block := range loadable { |
| 741 | for _, b := range block.Meta().Compaction.Parents { |
| 742 | delete(corrupted, b.ULID) |
| 743 | } |
| 744 | } |
| 745 | if len(corrupted) > 0 { |
| 746 | for _, b := range loadable { |
| 747 | if err := b.Close(); err != nil { |
| 748 | db.logger.Warn("Closing block failed", "err", err, "block", b) |
| 749 | } |
| 750 | } |
| 751 | var errs []error |
| 752 | for ulid, err := range corrupted { |
| 753 | if err != nil { |
| 754 | errs = append(errs, fmt.Errorf("corrupted block %s: %w", ulid.String(), err)) |
| 755 | } |
| 756 | } |
| 757 | return nil, errors.Join(errs...) |
| 758 | } |
| 759 | |
| 760 | if len(loadable) == 0 { |
| 761 | return nil, nil |
| 762 | } |
| 763 | |
| 764 | slices.SortFunc(loadable, func(a, b *Block) int { |
| 765 | switch { |
| 766 | case a.Meta().MinTime < b.Meta().MinTime: |
| 767 | return -1 |
| 768 | case a.Meta().MinTime > b.Meta().MinTime: |
| 769 | return 1 |
| 770 | default: |
| 771 | return 0 |
| 772 | } |
| 773 | }) |
| 774 | |
| 775 | blockMetas := make([]BlockMeta, 0, len(loadable)) |
| 776 | for _, b := range loadable { |
| 777 | blockMetas = append(blockMetas, b.Meta()) |
| 778 | } |
| 779 | if overlaps := OverlappingBlocks(blockMetas); len(overlaps) > 0 { |
| 780 | db.logger.Warn("Overlapping blocks found during opening", "detail", overlaps.String()) |
| 781 | } |
| 782 | |
| 783 | // Close all previously open readers and add the new ones to the cache. |
| 784 | for _, closer := range db.closers { |
| 785 | closer.Close() |
no test coverage detected