node_extern.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright 2015 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package v2store
  15. import (
  16. "sort"
  17. "time"
  18. "github.com/jonboulle/clockwork"
  19. )
  20. // NodeExtern is the external representation of the
  21. // internal node with additional fields
  22. // PrevValue is the previous value of the node
  23. // TTL is time to live in second
  24. type NodeExtern struct {
  25. Key string `json:"key,omitempty"`
  26. Value *string `json:"value,omitempty"`
  27. Dir bool `json:"dir,omitempty"`
  28. Expiration *time.Time `json:"expiration,omitempty"`
  29. TTL int64 `json:"ttl,omitempty"`
  30. Nodes NodeExterns `json:"nodes,omitempty"`
  31. ModifiedIndex uint64 `json:"modifiedIndex,omitempty"`
  32. CreatedIndex uint64 `json:"createdIndex,omitempty"`
  33. }
  34. func (eNode *NodeExtern) loadInternalNode(n *node, recursive, sorted bool, clock clockwork.Clock) {
  35. if n.IsDir() { // node is a directory
  36. eNode.Dir = true
  37. children, _ := n.List()
  38. eNode.Nodes = make(NodeExterns, len(children))
  39. // we do not use the index in the children slice directly
  40. // we need to skip the hidden one
  41. i := 0
  42. for _, child := range children {
  43. if child.IsHidden() { // get will not return hidden nodes
  44. continue
  45. }
  46. eNode.Nodes[i] = child.Repr(recursive, sorted, clock)
  47. i++
  48. }
  49. // eliminate hidden nodes
  50. eNode.Nodes = eNode.Nodes[:i]
  51. if sorted {
  52. sort.Sort(eNode.Nodes)
  53. }
  54. } else { // node is a file
  55. value, _ := n.Read()
  56. eNode.Value = &value
  57. }
  58. eNode.Expiration, eNode.TTL = n.expirationAndTTL(clock)
  59. }
  60. func (eNode *NodeExtern) Clone() *NodeExtern {
  61. if eNode == nil {
  62. return nil
  63. }
  64. nn := &NodeExtern{
  65. Key: eNode.Key,
  66. Dir: eNode.Dir,
  67. TTL: eNode.TTL,
  68. ModifiedIndex: eNode.ModifiedIndex,
  69. CreatedIndex: eNode.CreatedIndex,
  70. }
  71. if eNode.Value != nil {
  72. s := *eNode.Value
  73. nn.Value = &s
  74. }
  75. if eNode.Expiration != nil {
  76. t := *eNode.Expiration
  77. nn.Expiration = &t
  78. }
  79. if eNode.Nodes != nil {
  80. nn.Nodes = make(NodeExterns, len(eNode.Nodes))
  81. for i, n := range eNode.Nodes {
  82. nn.Nodes[i] = n.Clone()
  83. }
  84. }
  85. return nn
  86. }
  87. type NodeExterns []*NodeExtern
  88. // interfaces for sorting
  89. func (ns NodeExterns) Len() int {
  90. return len(ns)
  91. }
  92. func (ns NodeExterns) Less(i, j int) bool {
  93. return ns[i].Key < ns[j].Key
  94. }
  95. func (ns NodeExterns) Swap(i, j int) {
  96. ns[i], ns[j] = ns[j], ns[i]
  97. }