store.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package bitseq
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/docker/libnetwork/datastore"
  6. "github.com/docker/libnetwork/types"
  7. )
  8. // Key provides the Key to be used in KV Store
  9. func (h *Handle) Key() []string {
  10. h.Lock()
  11. defer h.Unlock()
  12. return []string{h.app, h.id}
  13. }
  14. // KeyPrefix returns the immediate parent key that can be used for tree walk
  15. func (h *Handle) KeyPrefix() []string {
  16. h.Lock()
  17. defer h.Unlock()
  18. return []string{h.app}
  19. }
  20. // Value marshals the data to be stored in the KV store
  21. func (h *Handle) Value() []byte {
  22. b, err := json.Marshal(h)
  23. if err != nil {
  24. return nil
  25. }
  26. return b
  27. }
  28. // SetValue unmarshals the data from the KV store
  29. func (h *Handle) SetValue(value []byte) error {
  30. return json.Unmarshal(value, h)
  31. }
  32. // Index returns the latest DB Index as seen by this object
  33. func (h *Handle) Index() uint64 {
  34. h.Lock()
  35. defer h.Unlock()
  36. return h.dbIndex
  37. }
  38. // SetIndex method allows the datastore to store the latest DB Index into this object
  39. func (h *Handle) SetIndex(index uint64) {
  40. h.Lock()
  41. h.dbIndex = index
  42. h.dbExists = true
  43. h.Unlock()
  44. }
  45. // Exists method is true if this object has been stored in the DB.
  46. func (h *Handle) Exists() bool {
  47. h.Lock()
  48. defer h.Unlock()
  49. return h.dbExists
  50. }
  51. // New method returns a handle based on the receiver handle
  52. func (h *Handle) New() datastore.KVObject {
  53. h.Lock()
  54. defer h.Unlock()
  55. return &Handle{
  56. app: h.app,
  57. store: h.store,
  58. }
  59. }
  60. // CopyTo deep copies the handle into the passed destination object
  61. func (h *Handle) CopyTo(o datastore.KVObject) error {
  62. h.Lock()
  63. defer h.Unlock()
  64. dstH := o.(*Handle)
  65. if h == dstH {
  66. return nil
  67. }
  68. dstH.Lock()
  69. dstH.bits = h.bits
  70. dstH.unselected = h.unselected
  71. dstH.head = h.head.getCopy()
  72. dstH.app = h.app
  73. dstH.id = h.id
  74. dstH.dbIndex = h.dbIndex
  75. dstH.dbExists = h.dbExists
  76. dstH.store = h.store
  77. dstH.Unlock()
  78. return nil
  79. }
  80. // Skip provides a way for a KV Object to avoid persisting it in the KV Store
  81. func (h *Handle) Skip() bool {
  82. return false
  83. }
  84. // DataScope method returns the storage scope of the datastore
  85. func (h *Handle) DataScope() string {
  86. h.Lock()
  87. defer h.Unlock()
  88. return h.store.Scope()
  89. }
  90. func (h *Handle) fromDsValue(value []byte) error {
  91. var ba []byte
  92. if err := json.Unmarshal(value, &ba); err != nil {
  93. return fmt.Errorf("failed to decode json: %s", err.Error())
  94. }
  95. if err := h.FromByteArray(ba); err != nil {
  96. return fmt.Errorf("failed to decode handle: %s", err.Error())
  97. }
  98. return nil
  99. }
  100. func (h *Handle) writeToStore() error {
  101. h.Lock()
  102. store := h.store
  103. h.Unlock()
  104. if store == nil {
  105. return nil
  106. }
  107. err := store.PutObjectAtomic(h)
  108. if err == datastore.ErrKeyModified {
  109. return types.RetryErrorf("failed to perform atomic write (%v). Retry might fix the error", err)
  110. }
  111. return err
  112. }
  113. func (h *Handle) deleteFromStore() error {
  114. h.Lock()
  115. store := h.store
  116. h.Unlock()
  117. if store == nil {
  118. return nil
  119. }
  120. return store.DeleteObjectAtomic(h)
  121. }