blob: 3eb9523bc41d54c980b214972b716277c33c8eb1 [file] [log] [blame]
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package stash
import (
"fmt"
"reflect"
"sync"
"time"
"android.googlesource.com/platform/tools/gpu/framework/event"
"android.googlesource.com/platform/tools/gpu/framework/log"
"android.googlesource.com/platform/tools/gpu/gapid/search"
"android.googlesource.com/platform/tools/gpu/gapid/search/eval"
"github.com/golang/protobuf/ptypes"
)
var entityClass = reflect.TypeOf(&Entity{})
// EntityHandler is a fuction that can be invoked for each entry in a
// stream of entities.
type EntityHandler func(log.Context, *Entity) error
type entityIndex struct {
mu sync.Mutex
entities []*Entity
byID map[string]*Entity
onAdd event.Broadcast
}
func (i *entityIndex) init() {
i.entities = []*Entity{}
i.byID = map[string]*Entity{}
}
func (i *entityIndex) lockedAddEntry(ctx log.Context, entity *Entity) {
i.entities = append(i.entities, entity)
i.byID[entity.Upload.Id] = entity
if err := i.onAdd.Send(ctx, entity); err != nil {
ctx.Fail(err, "Stash notification failed")
}
}
func (e *entityIndex) Lookup(ctx log.Context, id string) (*Entity, error) {
e.mu.Lock()
defer e.mu.Unlock()
return e.byID[id], nil
}
func (e *entityIndex) Search(ctx log.Context, query *search.Query, handler EntityHandler) error {
filter := eval.Filter(ctx, query, entityClass, event.AsHandler(ctx, handler))
initial := event.AsProducer(ctx, e.entities)
if query.Monitor {
return event.Monitor(ctx, &e.mu, e.onAdd.Listen, initial, filter)
}
return event.Feed(ctx, filter, initial)
}
func (e *Entity) Format(f fmt.State, c rune) {
name := "?"
if len(e.Upload.Name) > 0 {
name = e.Upload.Name[0]
}
t, _ := ptypes.Timestamp(e.Timestamp)
fmt.Fprintf(f, "%s %s : %s", name, t.Format(time.Stamp), e.Upload.Id)
}