1// Copyright (C) 2019 Storj Labs, Inc.
2// See LICENSE for copying information.
3
4package bandwidth
5
6import (
7	"context"
8	"time"
9
10	"storj.io/common/pb"
11	"storj.io/common/storj"
12)
13
14// DB contains information about bandwidth usage.
15//
16// architecture: Database
17type DB interface {
18	Add(ctx context.Context, satelliteID storj.NodeID, action pb.PieceAction, amount int64, created time.Time) error
19	// MonthSummary returns summary of the current months bandwidth usages.
20	MonthSummary(ctx context.Context, now time.Time) (int64, error)
21	Rollup(ctx context.Context) (err error)
22	// Summary returns summary of bandwidth usages.
23	Summary(ctx context.Context, from, to time.Time) (*Usage, error)
24	// EgressSummary returns summary of egress bandwidth usages.
25	EgressSummary(ctx context.Context, from, to time.Time) (*Usage, error)
26	// IngressSummary returns summary of ingress bandwidth usages.
27	IngressSummary(ctx context.Context, from, to time.Time) (*Usage, error)
28	// SatelliteSummary returns aggregated bandwidth usage for a particular satellite.
29	SatelliteSummary(ctx context.Context, satelliteID storj.NodeID, from, to time.Time) (*Usage, error)
30	// SatelliteEgressSummary returns egress bandwidth usage for a particular satellite.
31	SatelliteEgressSummary(ctx context.Context, satelliteID storj.NodeID, from, to time.Time) (*Usage, error)
32	// SatelliteIngressSummary returns ingress bandwidth usage for a particular satellite.
33	SatelliteIngressSummary(ctx context.Context, satelliteID storj.NodeID, from, to time.Time) (*Usage, error)
34	SummaryBySatellite(ctx context.Context, from, to time.Time) (map[storj.NodeID]*Usage, error)
35	// GetDailyRollups returns slice of daily bandwidth usage rollups for provided time range,
36	// sorted in ascending order.
37	GetDailyRollups(ctx context.Context, from, to time.Time) ([]UsageRollup, error)
38	// GetDailySatelliteRollups returns slice of daily bandwidth usage for provided time range,
39	// sorted in ascending order for a particular satellite.
40	GetDailySatelliteRollups(ctx context.Context, satelliteID storj.NodeID, from, to time.Time) ([]UsageRollup, error)
41}
42
43// Usage contains bandwidth usage information based on the type.
44type Usage struct {
45	Invalid int64
46	Unknown int64
47
48	Put       int64
49	Get       int64
50	GetAudit  int64
51	GetRepair int64
52	PutRepair int64
53	Delete    int64
54}
55
56// Egress stores info about storage node egress usage.
57type Egress struct {
58	Repair int64 `json:"repair"`
59	Audit  int64 `json:"audit"`
60	Usage  int64 `json:"usage"`
61}
62
63// Ingress stores info about storage node ingress usage.
64type Ingress struct {
65	Repair int64 `json:"repair"`
66	Usage  int64 `json:"usage"`
67}
68
69// UsageRollup contains rolluped bandwidth usage.
70type UsageRollup struct {
71	Egress        Egress    `json:"egress"`
72	Ingress       Ingress   `json:"ingress"`
73	Delete        int64     `json:"delete"`
74	IntervalStart time.Time `json:"intervalStart"`
75}
76
77// Include adds specified action to the appropriate field.
78func (usage *Usage) Include(action pb.PieceAction, amount int64) {
79	switch action {
80	case pb.PieceAction_INVALID:
81		usage.Invalid += amount
82	case pb.PieceAction_PUT:
83		usage.Put += amount
84	case pb.PieceAction_GET:
85		usage.Get += amount
86	case pb.PieceAction_GET_AUDIT:
87		usage.GetAudit += amount
88	case pb.PieceAction_GET_REPAIR:
89		usage.GetRepair += amount
90	case pb.PieceAction_PUT_REPAIR:
91		usage.PutRepair += amount
92	case pb.PieceAction_DELETE:
93		usage.Delete += amount
94	default:
95		usage.Unknown += amount
96	}
97}
98
99// Add adds another usage to this one.
100func (usage *Usage) Add(b *Usage) {
101	usage.Invalid += b.Invalid
102	usage.Unknown += b.Unknown
103	usage.Put += b.Put
104	usage.Get += b.Get
105	usage.GetAudit += b.GetAudit
106	usage.GetRepair += b.GetRepair
107	usage.PutRepair += b.PutRepair
108	usage.Delete += b.Delete
109}
110
111// Total sums all type of bandwidths.
112func (usage *Usage) Total() int64 {
113	return usage.Invalid +
114		usage.Unknown +
115		usage.Put +
116		usage.Get +
117		usage.GetAudit +
118		usage.GetRepair +
119		usage.PutRepair +
120		usage.Delete
121}
122
123// TotalMonthlySummary returns total bandwidth usage for current month.
124func TotalMonthlySummary(ctx context.Context, db DB) (*Usage, error) {
125	return db.Summary(ctx, getBeginningOfMonth(), time.Now())
126}
127
128func getBeginningOfMonth() time.Time {
129	t := time.Now()
130	y, m, _ := t.Date()
131	return time.Date(y, m, 1, 0, 0, 0, 0, time.Now().Location())
132}
133