Repository: prometheus/prometheus
File: tsdb/db.go (Go)

Code before:
				deletable[b.meta.ULID] = struct{}{}
			}
			db.metrics.timeRetentionCount.Inc()
			break
		}
	}
	return deletable
}

// BeyondSizeRetention returns those blocks which are beyond the size retention
// set in the db options.
func BeyondSizeRetention(db *DB, blocks []*Block) (deletable map[ulid.ULID]struct{}) {
	// No blocks to work with
	if len(blocks) == 0 {
		return deletable
	}

	maxBytes := db.getMaxBytes()
	maxPercentage := db.getMaxPercentage()

	// percentage prevails
	if maxPercentage > 0 {
		// retrieve FS size
		diskSize := db.fsSizeFunc(db.dir)
		if diskSize <= 0 {
			db.logger.Warn("msg", "Unable to retrieve filesystem size of database directory (%s), skip percentage limitation and default to fixed size limitation", db.dir)
		} else {
			// apply percentage
			maxBytes = int64(uint64(maxPercentage) * diskSize / 100)
		}
	}

	// Size retention is disabled
	if maxBytes <= 0 {
		return deletable
	}
	// update MaxBytes gauge
	db.metrics.maxBytes.Set(float64(maxBytes))

	deletable = make(map[ulid.ULID]struct{})

	// Initializing size counter with WAL size and Head chunks
	// written to disk, as that is part of the retention strategy.
	blocksSize := db.Head().Size()
	for i, block := range blocks {
		blocksSize += block.Size()
		if blocksSize > maxBytes {
			// Add this and all following blocks for deletion.
			for _, b := range blocks[i:] {
				deletable[b.meta.ULID] = struct{}{}
			}

Review comment (bug):
Wrong usage:

```suggestion
			db.logger.Warn("Unable to retrieve filesystem size of database directory, skip percentage limitation and default to fixed size limitation", "dir", db.dir)
```

Code after:
		// The difference between the first block and this block is greater than or equal to
		// the retention period so any blocks after that are added as deletable.
		if i > 0 && blocks[0].Meta().MaxTime-block.Meta().MaxTime >= retentionDuration {
			for _, b := range blocks[i:] {
				deletable[b.meta.ULID] = struct{}{}
			}
			db.metrics.timeRetentionCount.Inc()
			break
		}
	}
	return deletable
}

// BeyondSizeRetention returns those blocks which are beyond the size retention
// set in the db options.
func BeyondSizeRetention(db *DB, blocks []*Block) (deletable map[ulid.ULID]struct{}) {
	// No blocks to work with
	if len(blocks) == 0 {
		return deletable
	}

	maxBytes, maxPercentage := db.getRetentionSettings()

	// Max percentage prevails over max size.
	if maxPercentage > 0 {
		diskSize := db.fsSizeFunc(db.dir)
		if diskSize <= 0 {
			db.logger.Warn("Unable to retrieve filesystem size of database directory, skip percentage limitation and default to fixed size limitation", "dir", db.dir)
		} else {
			maxBytes = int64(uint64(maxPercentage) * diskSize / 100)
		}
	}

	// Size retention is disabled.
	if maxBytes <= 0 {
		return deletable
	}

	deletable = make(map[ulid.ULID]struct{})

	// Initializing size counter with WAL size and Head chunks
	// written to disk, as that is part of the retention strategy.
	blocksSize := db.Head().Size()
	for i, block := range blocks {
		blocksSize += block.Size()
		if blocksSize > maxBytes {
			// Add this and all following blocks for deletion.
			for _, b := range blocks[i:] {
				deletable[b.meta.ULID] = struct{}{}
			}
			db.metrics.sizeRetentionCount.Inc()