You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: tally.go
    path of file: ./repos/storj/satellite/accounting/tally
    
    the code of the file until where you have to start completion: // Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.

package tally

import (
	"context"
	"time"

	"github.com/spacemonkeygo/monkit/v3"
	"github.com/zeebo/errs"
	"go.uber.org/zap"

	"storj.io/common/sync2"
	"storj.io/common/uuid"
	"storj.io/storj/satellite/accounting"
	"storj.io/storj/satellite/buckets"
	"storj.io/storj/satellite/metabase"
)

// Error is a standard error class for this package.
var (
	Error = errs.Class("tally")
	mon   = monkit.Package()
)

// Config contains configurable values for the tally service.
type Config struct {
	Interval             time.Duration `help:"how frequently the tally service should run" releaseDefault:"1h" devDefault:"30s" testDefault:"$TESTINTERVAL"`
	SaveRollupBatchSize  int           `help:"how large of batches SaveRollup should process at a time" default:"1000"`
	ReadRollupBatchSize  int           `help:"how large of bat
    
func (observer *BucketTallyCollector) fillBucketTallies(ctx context.Context, startingTime time.Time) (err error) {
	defer mon.Task()(&ctx)(&err)

	return observer.bucketsDB.IterateBucketLocations(ctx, observer.config.ListLimit, func(bucketLocations []metabase.BucketLocation) (err error) {
		fromBucket := bucketLocations[0]
		toBucket := bucketLocations[len(bucketLocations)-1]

		// Prepopulate the results with empty tallies. Otherwise, empty buckets will be unaccounted for
		// since they're not reached when iterating over objects in the metainfo DB.
		// We only do this for buckets whose last tally is non-empty because only one empty tally is
		// required for us to know that a bucket was empty the last time we checked.
		locs, err := observer.projectAccountingDB.GetNonEmptyTallyBucketsInRange(ctx, fromBucket, toBucket, observer.config.AsOfSystemInterval)
		if err != nil {
			return err
		}
		for _, loc := range locs {
			observer.Bucket[loc] = &accounting.BucketTally{BucketLocation: loc}
		}

		tallies, err := observer.metabase.CollectBucketTallies(ctx, metabase.CollectBucketTallies{
			From:               fromBucket,
			To:                 toBucket,
			AsOfSystemTime:     startingTime,
			AsOfSystemInterval: observer.config.AsOfSystemInterval,
			Now:                observer.Now,
		})
		if err != nil {
			return err
		}

		for _, tally := range tallies {
			bucket := observer.ensureBucket(tally.BucketLocation)
			bucket.TotalSegments = tally.TotalSegments
			bucket.TotalBytes = tally.TotalBytes
			bucket.MetadataSize = tally.MetadataSize
			bucket.ObjectCount = tally.ObjectCount
			bucket.PendingObjectCount = tally.PendingObjectCount
		}

		return nil
	})
}