volume_ttl.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package needle
  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. if input[0] == 0 && input[1] == 0 {
  46. return EMPTY_TTL
  47. }
  48. return &TTL{Count: input[0], Unit: input[1]}
  49. }
  50. // read stored bytes to a ttl
  51. func LoadTTLFromUint32(ttl uint32) (t *TTL) {
  52. input := make([]byte, 2)
  53. input[1] = byte(ttl)
  54. input[0] = byte(ttl >> 8)
  55. return LoadTTLFromBytes(input)
  56. }
  57. // save stored bytes to an output with 2 bytes
  58. func (t *TTL) ToBytes(output []byte) {
  59. output[0] = t.Count
  60. output[1] = t.Unit
  61. }
  62. func (t *TTL) ToUint32() (output uint32) {
  63. output = uint32(t.Count) << 8
  64. output += uint32(t.Unit)
  65. return output
  66. }
  67. func (t *TTL) String() string {
  68. if t == nil || t.Count == 0 {
  69. return ""
  70. }
  71. if t.Unit == Empty {
  72. return ""
  73. }
  74. countString := strconv.Itoa(int(t.Count))
  75. switch t.Unit {
  76. case Minute:
  77. return countString + "m"
  78. case Hour:
  79. return countString + "h"
  80. case Day:
  81. return countString + "d"
  82. case Week:
  83. return countString + "w"
  84. case Month:
  85. return countString + "M"
  86. case Year:
  87. return countString + "y"
  88. }
  89. return ""
  90. }
  91. func toStoredByte(readableUnitByte byte) byte {
  92. switch readableUnitByte {
  93. case 'm':
  94. return Minute
  95. case 'h':
  96. return Hour
  97. case 'd':
  98. return Day
  99. case 'w':
  100. return Week
  101. case 'M':
  102. return Month
  103. case 'y':
  104. return Year
  105. }
  106. return 0
  107. }
  108. func (t TTL) Minutes() uint32 {
  109. switch t.Unit {
  110. case Empty:
  111. return 0
  112. case Minute:
  113. return uint32(t.Count)
  114. case Hour:
  115. return uint32(t.Count) * 60
  116. case Day:
  117. return uint32(t.Count) * 60 * 24
  118. case Week:
  119. return uint32(t.Count) * 60 * 24 * 7
  120. case Month:
  121. return uint32(t.Count) * 60 * 24 * 31
  122. case Year:
  123. return uint32(t.Count) * 60 * 24 * 365
  124. }
  125. return 0
  126. }