volume_ttl.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package storage
  2. import (
  3. "strconv"
  4. )
  5. const (
  6. //stored unit types
  7. Empty byte = iota
  8. Minute
  9. Hour
  10. Day
  11. Week
  12. Month
  13. Year
  14. )
  15. type TTL struct {
  16. count byte
  17. unit byte
  18. }
  19. var EMPTY_TTL = &TTL{}
  20. // translate a readable ttl to internal ttl
  21. // Supports format example:
  22. // 3m: 3 minutes
  23. // 4h: 4 hours
  24. // 5d: 5 days
  25. // 6w: 6 weeks
  26. // 7M: 7 months
  27. // 8y: 8 years
  28. func ReadTTL(ttlString string) (*TTL, error) {
  29. if ttlString == "" {
  30. return EMPTY_TTL, nil
  31. }
  32. ttlBytes := []byte(ttlString)
  33. unitByte := ttlBytes[len(ttlBytes)-1]
  34. countBytes := ttlBytes[0 : len(ttlBytes)-1]
  35. if '0' <= unitByte && unitByte <= '9' {
  36. countBytes = ttlBytes
  37. unitByte = 'm'
  38. }
  39. count, err := strconv.Atoi(string(countBytes))
  40. unit := toStoredByte(unitByte)
  41. return &TTL{count: byte(count), unit: unit}, err
  42. }
  43. // read stored bytes to a ttl
  44. func LoadTTLFromBytes(input []byte) (t *TTL) {
  45. return &TTL{count: input[0], unit: input[1]}
  46. }
  47. // read stored bytes to a ttl
  48. func LoadTTLFromUint32(ttl uint32) (t *TTL) {
  49. input := make([]byte, 2)
  50. input[1] = byte(ttl)
  51. input[0] = byte(ttl >> 8)
  52. return LoadTTLFromBytes(input)
  53. }
  54. // save stored bytes to an output with 2 bytes
  55. func (t *TTL) ToBytes(output []byte) {
  56. output[0] = t.count
  57. output[1] = t.unit
  58. }
  59. func (t *TTL) ToUint32() (output uint32) {
  60. output = uint32(t.count) << 8
  61. output += uint32(t.unit)
  62. return output
  63. }
  64. func (t *TTL) String() string {
  65. if t == nil || t.count == 0 {
  66. return ""
  67. }
  68. if t.unit == Empty {
  69. return ""
  70. }
  71. countString := strconv.Itoa(int(t.count))
  72. switch t.unit {
  73. case Minute:
  74. return countString + "m"
  75. case Hour:
  76. return countString + "h"
  77. case Day:
  78. return countString + "d"
  79. case Week:
  80. return countString + "w"
  81. case Month:
  82. return countString + "M"
  83. case Year:
  84. return countString + "y"
  85. }
  86. return ""
  87. }
  88. func toStoredByte(readableUnitByte byte) byte {
  89. switch readableUnitByte {
  90. case 'm':
  91. return Minute
  92. case 'h':
  93. return Hour
  94. case 'd':
  95. return Day
  96. case 'w':
  97. return Week
  98. case 'M':
  99. return Month
  100. case 'y':
  101. return Year
  102. }
  103. return 0
  104. }
  105. func (t TTL) Minutes() uint32 {
  106. switch t.unit {
  107. case Empty:
  108. return 0
  109. case Minute:
  110. return uint32(t.count)
  111. case Hour:
  112. return uint32(t.count) * 60
  113. case Day:
  114. return uint32(t.count) * 60 * 24
  115. case Week:
  116. return uint32(t.count) * 60 * 24 * 7
  117. case Month:
  118. return uint32(t.count) * 60 * 24 * 31
  119. case Year:
  120. return uint32(t.count) * 60 * 24 * 365
  121. }
  122. return 0
  123. }