hashStorage.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package global
  2. import (
  3. "crypto/md5"
  4. "encoding/hex"
  5. "sync"
  6. "time"
  7. )
  8. type HashEntry struct {
  9. Hash string
  10. Value string
  11. Timestamp time.Time
  12. }
  13. type HashStorage struct {
  14. sync.RWMutex
  15. Data map[string]HashEntry
  16. Expiration time.Duration
  17. ForceSave bool
  18. }
  19. func NewHashStorage(expiration time.Duration, forceSave bool) *HashStorage {
  20. return &HashStorage{
  21. Data: make(map[string]HashEntry),
  22. Expiration: expiration,
  23. ForceSave: forceSave,
  24. }
  25. }
  26. func (h *HashStorage) AddHash(query string) string {
  27. if h.ForceSave {
  28. return h.saveValue(query)
  29. }
  30. // we only need to hash for more than 64 chars by default
  31. if len(query) <= 64 {
  32. return query
  33. }
  34. return h.saveValue(query)
  35. }
  36. func (h *HashStorage) saveValue(query string) string {
  37. h.Lock()
  38. defer h.Unlock()
  39. md5Hash := md5.Sum([]byte(query))
  40. md5HashString := hex.EncodeToString(md5Hash[:])
  41. entry := HashEntry{
  42. Hash: md5HashString,
  43. Value: query,
  44. Timestamp: time.Now(),
  45. }
  46. h.Data[md5HashString] = entry
  47. return md5HashString
  48. }
  49. func (h *HashStorage) GetValue(hash string) string {
  50. h.RLock()
  51. defer h.RUnlock()
  52. entry, exists := h.Data[hash]
  53. if !exists {
  54. return hash
  55. }
  56. return entry.Value
  57. }
  58. func (h *HashStorage) RemoveExpiredHashes() {
  59. h.Lock()
  60. defer h.Unlock()
  61. now := time.Now()
  62. for hash, entry := range h.Data {
  63. if now.Sub(entry.Timestamp) > h.Expiration {
  64. delete(h.Data, hash)
  65. }
  66. }
  67. }
  68. func (h *HashStorage) Reset() {
  69. h.Lock()
  70. defer h.Unlock()
  71. h.Data = make(map[string]HashEntry)
  72. }