blob: 7ba870cbe7b8900b0f4ff067a53ac0314609bc9c [file] [log] [blame]
khenaidood948f772021-08-11 17:49:24 -04001// 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
15package store
16
17import (
18 "sort"
19 "time"
20
21 "github.com/jonboulle/clockwork"
22)
23
24// NodeExtern is the external representation of the
25// internal node with additional fields
26// PrevValue is the previous value of the node
27// TTL is time to live in second
28type NodeExtern struct {
29 Key string `json:"key,omitempty"`
30 Value *string `json:"value,omitempty"`
31 Dir bool `json:"dir,omitempty"`
32 Expiration *time.Time `json:"expiration,omitempty"`
33 TTL int64 `json:"ttl,omitempty"`
34 Nodes NodeExterns `json:"nodes,omitempty"`
35 ModifiedIndex uint64 `json:"modifiedIndex,omitempty"`
36 CreatedIndex uint64 `json:"createdIndex,omitempty"`
37}
38
39func (eNode *NodeExtern) loadInternalNode(n *node, recursive, sorted bool, clock clockwork.Clock) {
40 if n.IsDir() { // node is a directory
41 eNode.Dir = true
42
43 children, _ := n.List()
44 eNode.Nodes = make(NodeExterns, len(children))
45
46 // we do not use the index in the children slice directly
47 // we need to skip the hidden one
48 i := 0
49
50 for _, child := range children {
51 if child.IsHidden() { // get will not return hidden nodes
52 continue
53 }
54
55 eNode.Nodes[i] = child.Repr(recursive, sorted, clock)
56 i++
57 }
58
59 // eliminate hidden nodes
60 eNode.Nodes = eNode.Nodes[:i]
61
62 if sorted {
63 sort.Sort(eNode.Nodes)
64 }
65
66 } else { // node is a file
67 value, _ := n.Read()
68 eNode.Value = &value
69 }
70
71 eNode.Expiration, eNode.TTL = n.expirationAndTTL(clock)
72}
73
74func (eNode *NodeExtern) Clone() *NodeExtern {
75 if eNode == nil {
76 return nil
77 }
78 nn := &NodeExtern{
79 Key: eNode.Key,
80 Dir: eNode.Dir,
81 TTL: eNode.TTL,
82 ModifiedIndex: eNode.ModifiedIndex,
83 CreatedIndex: eNode.CreatedIndex,
84 }
85 if eNode.Value != nil {
86 s := *eNode.Value
87 nn.Value = &s
88 }
89 if eNode.Expiration != nil {
90 t := *eNode.Expiration
91 nn.Expiration = &t
92 }
93 if eNode.Nodes != nil {
94 nn.Nodes = make(NodeExterns, len(eNode.Nodes))
95 for i, n := range eNode.Nodes {
96 nn.Nodes[i] = n.Clone()
97 }
98 }
99 return nn
100}
101
102type NodeExterns []*NodeExtern
103
104// interfaces for sorting
105
106func (ns NodeExterns) Len() int {
107 return len(ns)
108}
109
110func (ns NodeExterns) Less(i, j int) bool {
111 return ns[i].Key < ns[j].Key
112}
113
114func (ns NodeExterns) Swap(i, j int) {
115 ns[i], ns[j] = ns[j], ns[i]
116}