You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
2.5 KiB

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