namespaced.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This program is free software: you can redistribute it and/or modify it
  4. // under the terms of the GNU General Public License as published by the Free
  5. // Software Foundation, either version 3 of the License, or (at your option)
  6. // any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful, but WITHOUT
  9. // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. // more details.
  12. //
  13. // You should have received a copy of the GNU General Public License along
  14. // with this program. If not, see <http://www.gnu.org/licenses/>.
  15. package db
  16. import (
  17. "encoding/binary"
  18. "time"
  19. "github.com/syndtr/goleveldb/leveldb"
  20. )
  21. // NamespacedKV is a simple key-value store using a specific namespace within
  22. // a leveldb.
  23. type NamespacedKV struct {
  24. db *leveldb.DB
  25. prefix []byte
  26. }
  27. // NewNamespacedKV returns a new NamespacedKV that lives in the namespace
  28. // specified by the prefix.
  29. func NewNamespacedKV(db *leveldb.DB, prefix string) *NamespacedKV {
  30. return &NamespacedKV{
  31. db: db,
  32. prefix: []byte(prefix),
  33. }
  34. }
  35. // PutInt64 stores a new int64. Any existing value (even if of another type)
  36. // is overwritten.
  37. func (n *NamespacedKV) PutInt64(key string, val int64) {
  38. keyBs := append(n.prefix, []byte(key)...)
  39. var valBs [8]byte
  40. binary.BigEndian.PutUint64(valBs[:], uint64(val))
  41. n.db.Put(keyBs, valBs[:], nil)
  42. }
  43. // Int64 returns the stored value interpreted as an int64 and a boolean that
  44. // is false if no value was stored at the key.
  45. func (n *NamespacedKV) Int64(key string) (int64, bool) {
  46. keyBs := append(n.prefix, []byte(key)...)
  47. valBs, err := n.db.Get(keyBs, nil)
  48. if err != nil {
  49. return 0, false
  50. }
  51. val := binary.BigEndian.Uint64(valBs)
  52. return int64(val), true
  53. }
  54. // PutTime stores a new time.Time. Any existing value (even if of another
  55. // type) is overwritten.
  56. func (n *NamespacedKV) PutTime(key string, val time.Time) {
  57. keyBs := append(n.prefix, []byte(key)...)
  58. valBs, _ := val.MarshalBinary() // never returns an error
  59. n.db.Put(keyBs, valBs, nil)
  60. }
  61. // Time returns the stored value interpreted as a time.Time and a boolean
  62. // that is false if no value was stored at the key.
  63. func (n NamespacedKV) Time(key string) (time.Time, bool) {
  64. var t time.Time
  65. keyBs := append(n.prefix, []byte(key)...)
  66. valBs, err := n.db.Get(keyBs, nil)
  67. if err != nil {
  68. return t, false
  69. }
  70. err = t.UnmarshalBinary(valBs)
  71. return t, err == nil
  72. }
  73. // PutString stores a new string. Any existing value (even if of another type)
  74. // is overwritten.
  75. func (n *NamespacedKV) PutString(key, val string) {
  76. keyBs := append(n.prefix, []byte(key)...)
  77. n.db.Put(keyBs, []byte(val), nil)
  78. }
  79. // String returns the stored value interpreted as a string and a boolean that
  80. // is false if no value was stored at the key.
  81. func (n NamespacedKV) String(key string) (string, bool) {
  82. keyBs := append(n.prefix, []byte(key)...)
  83. valBs, err := n.db.Get(keyBs, nil)
  84. if err != nil {
  85. return "", false
  86. }
  87. return string(valBs), true
  88. }
  89. // Delete deletes the specified key. It is allowed to delete a nonexistent
  90. // key.
  91. func (n NamespacedKV) Delete(key string) {
  92. keyBs := append(n.prefix, []byte(key)...)
  93. n.db.Delete(keyBs, nil)
  94. }