internal/repo/pricing.go (91 lines of code) (raw):

package repo import "errors" type StorageClass string type Location string const ( StorageStandard StorageClass = "STANDARD" StorageNearline StorageClass = "NEARLINE" StorageColdline StorageClass = "COLDLINE" StorageArchive StorageClass = "ARCHIVE" LocationUS Location = "US" LocationASIA Location = "ASIA" LocationEU Location = "EU" LocationCA Location = "CA" LocationAU Location = "AU" LocationIN Location = "IN" ) const bytesPerGB = 1024 * 1024 * 1024 // LocationPricing holds a general pricing per location // based on the most expensive region for each location // // Pricing is sourced from https://cloud.google.com/storage/pricing var locationPricing = map[Location]map[StorageClass]float64{ LocationUS: { // us-west4 StorageStandard: 0.0230, StorageNearline: 0.0160, StorageColdline: 0.0070, StorageArchive: 0.0025, }, LocationASIA: { // asia-east2 StorageStandard: 0.0230, StorageNearline: 0.0160, StorageColdline: 0.0070, StorageArchive: 0.0025, }, LocationEU: { // europe-west6 StorageStandard: 0.0250, StorageNearline: 0.0100, StorageColdline: 0.0070, StorageArchive: 0.0025, }, LocationCA: { // nothamerica-northeast1 StorageStandard: 0.0230, StorageNearline: 0.0130, StorageColdline: 0.0070, StorageArchive: 0.0025, }, LocationAU: { // australia-southeast1 StorageStandard: 0.0230, StorageNearline: 0.0160, StorageColdline: 0.0060, StorageArchive: 0.0025, }, LocationIN: { // asia-south2 StorageStandard: 0.0230, StorageNearline: 0.0160, StorageColdline: 0.0060, StorageArchive: 0.0025, }, } // getPrice returns the price for a given storage class in a specific location. func getPrice(costMap map[StorageClass]float64, storageClass StorageClass, size int64) (float64, error) { price, ok := costMap[storageClass] if !ok { return 0, errors.New("invalid storage class") } sizeGB := float64(size / bytesPerGB) return price * sizeGB, nil } // getObjectCost returns the total cost for an object based on its storage class func getObjectCost(location Location, storageClass StorageClass, size int64) (float64, error) { costMap, ok := locationPricing[location] if !ok { return 0, errors.New("invalid location") } cost, err := getPrice(costMap, storageClass, size) if err != nil { return 0, err } return cost, nil } // getDirectoryCost returns the total cost for a directory based on all its storage class' sizes func getDirectoryCost(location Location, sizeStandard, sizeNearline, sizeColdline, sizeArchive int64) (float64, error) { var totalCost float64 = 0 costMap, ok := locationPricing[location] if !ok { return 0, errors.New("invalid location") } classes := []StorageClass{StorageStandard, StorageNearline, StorageColdline, StorageArchive} sizes := []int64{sizeStandard, sizeNearline, sizeColdline, sizeArchive} for i, size := range sizes { cost, err := getPrice(costMap, classes[i], size) if err != nil { return 0, err } totalCost += cost } return totalCost, nil }