aboutsummaryrefslogtreecommitdiff
path: root/weed/storage/volume_ttl.go
blob: 4318bb04879c80f6e6c1e3c405c2a410e4eb4c6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package storage

import (
	"strconv"
)

const (
	//stored unit types
	Empty byte = iota
	Minute
	Hour
	Day
	Week
	Month
	Year
)

type TTL struct {
	count byte
	unit  byte
}

var EMPTY_TTL = &TTL{}

// translate a readable ttl to internal ttl
// Supports format example:
// 3m: 3 minutes
// 4h: 4 hours
// 5d: 5 days
// 6w: 6 weeks
// 7M: 7 months
// 8y: 8 years
func ReadTTL(ttlString string) (*TTL, error) {
	if ttlString == "" {
		return EMPTY_TTL, nil
	}
	ttlBytes := []byte(ttlString)
	unitByte := ttlBytes[len(ttlBytes)-1]
	countBytes := ttlBytes[0 : len(ttlBytes)-1]
	if '0' <= unitByte && unitByte <= '9' {
		countBytes = ttlBytes
		unitByte = 'm'
	}
	count, err := strconv.Atoi(string(countBytes))
	unit := toStoredByte(unitByte)
	return &TTL{count: byte(count), unit: unit}, err
}

// read stored bytes to a ttl
func LoadTTLFromBytes(input []byte) (t *TTL) {
	return &TTL{count: input[0], unit: input[1]}
}

// read stored bytes to a ttl
func LoadTTLFromUint32(ttl uint32) (t *TTL) {
	input := make([]byte, 2)
	input[1] = byte(ttl)
	input[0] = byte(ttl >> 8)
	return LoadTTLFromBytes(input)
}

// save stored bytes to an output with 2 bytes
func (t *TTL) ToBytes(output []byte) {
	output[0] = t.count
	output[1] = t.unit
}

func (t *TTL) ToUint32() (output uint32) {
	output = uint32(t.count) << 8
	output += uint32(t.unit)
	return output
}

func (t *TTL) String() string {
	if t == nil || t.count == 0 {
		return ""
	}
	if t.unit == Empty {
		return ""
	}
	countString := strconv.Itoa(int(t.count))
	switch t.unit {
	case Minute:
		return countString + "m"
	case Hour:
		return countString + "h"
	case Day:
		return countString + "d"
	case Week:
		return countString + "w"
	case Month:
		return countString + "M"
	case Year:
		return countString + "y"
	}
	return ""
}

func toStoredByte(readableUnitByte byte) byte {
	switch readableUnitByte {
	case 'm':
		return Minute
	case 'h':
		return Hour
	case 'd':
		return Day
	case 'w':
		return Week
	case 'M':
		return Month
	case 'y':
		return Year
	}
	return 0
}

func (t TTL) Minutes() uint32 {
	switch t.unit {
	case Empty:
		return 0
	case Minute:
		return uint32(t.count)
	case Hour:
		return uint32(t.count) * 60
	case Day:
		return uint32(t.count) * 60 * 24
	case Week:
		return uint32(t.count) * 60 * 24 * 7
	case Month:
		return uint32(t.count) * 60 * 24 * 31
	case Year:
		return uint32(t.count) * 60 * 24 * 365
	}
	return 0
}