Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: logdog/appengine/coordinator/hierarchy/component.go

Issue 2991253004: [logdog] Remove list functionality. (Closed)
Patch Set: fix test Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The LUCI 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
15 package hierarchy
16
17 import (
18 ds "github.com/luci/gae/service/datastore"
19 "github.com/luci/luci-go/logdog/common/types"
20
21 "golang.org/x/net/context"
22 )
23
24 // Component is a log stream hierarchy component.
25 type Component struct {
26 // Parent is the partial stream path parent of this component.
27 Parent types.StreamPath
28 // Name is the name of this Component.
29 Name string
30 // Stream is true if this is a stream component, false if it is a path
31 // component.
32 Stream bool
33 }
34
35 // Components returns the set of hierarchy components for a given stream path.
36 //
37 // If isFullStream is false, all of the components in p will be considered
38 // intermediate components. If isFullStream is true, p is regarded as a full
39 // stream, and the last element will be marked as a stream component.
40 func Components(p types.StreamPath, isFullStream bool) []*Component {
41 segments := p.SegmentCount()
42 if segments == 0 {
43 return nil
44 }
45
46 // Build all Component objects for our parts.
47 //
48 // The first component is the stream component.
49 components := make([]*Component, 0, segments)
50 for {
51 var last string
52 p, last = p.SplitLast()
53 components = append(components, &Component{
54 Parent: p,
55 Name: last,
56 Stream: isFullStream && (len(components) == 0),
57 })
58
59 if p == "" {
60 break
61 }
62 }
63
64 return components
65 }
66
67 // String returns a string representation for this Component.
68 //
69 // For path components, this is the path. For stream components, this is the
70 // path followed by a dollar sign. Note that the dollar sign is not a valid
71 // types.StreamName character, and so this will not conflict with other valid
72 // Components.
73 //
74 // For example, for {Parent="foo/bar", Name="baz"}, we get "foo/bar/baz".
75 // If {Stream=true}, we would get "foo/bar/baz$".
76 //
77 // Two Components with the same String result reference the same path component.
78 func (comp *Component) String() string {
79 s := string(comp.Path())
80 if comp.Stream {
81 s += "$"
82 }
83 return s
84 }
85
86 // Path returns the StreamPath for this Component.
87 func (comp *Component) Path() types.StreamPath {
88 return comp.Parent.Append(comp.Name)
89 }
90
91 // Exists checks whether this Component exists in the datastore.
92 func (comp *Component) Exists(c context.Context) (bool, error) {
93 er, err := ds.Exists(c, ds.KeyForObj(c, comp.entity()))
94 if err != nil {
95 return false, err
96 }
97 return er.All(), nil
98 }
99
100 // Put writes this Component to the datastore.
101 //
102 // Prior to writing, it will verify that the Component represents a valid
103 // partial log stream path.
104 func (comp *Component) Put(c context.Context) error {
105 path := comp.Path()
106 if err := path.ValidatePartial(); err != nil {
107 return err
108 }
109 return ds.Put(c, comp.entity())
110 }
111
112 // entity returns the componentEntity that this Component describes.
113 func (comp *Component) entity() *componentEntity {
114 return mkComponentEntity(comp.Parent, comp.Name, comp.Stream)
115 }
116
117 // Missing checks the status of the supplied Components in the datastore.
118 //
119 // It mutates the supplied components array, shrinking it if necessary, to
120 // return only the Components that were not already present.
121 //
122 // If Missing failed, it will return the original components array and the
123 // failure error.
124 func Missing(c context.Context, components []*Component) ([]*Component, error) {
125 exists := make([]*ds.Key, len(components))
126 for i, comp := range components {
127 exists[i] = ds.KeyForObj(c, comp.entity())
128 }
129 er, err := ds.Exists(c, exists)
130 if err != nil {
131 return nil, err
132 }
133
134 // Condense the components array.
135 nidx := 0
136 for i, v := range er.List(0) {
137 if !v {
138 components[nidx] = components[i]
139 nidx++
140 }
141 }
142 return components[:nidx], nil
143 }
144
145 // PutMulti performs a datastore PutMulti on all of the hierarchy entities for
146 // components.
147 func PutMulti(c context.Context, components []*Component) error {
148 ents := make([]*componentEntity, len(components))
149 for i, comp := range components {
150 ents[i] = comp.entity()
151 }
152 return ds.Put(c, ents)
153 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698