blob: 9db20bafb7c4e180b1122c05343e22050c10f591 [file] [log] [blame]
// Copyright (C) 2015 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 database implements the persistence layer for the gpu debugger tools.
package database
import (
"crypto/sha1"
"android.googlesource.com/platform/tools/gpu/binary"
"android.googlesource.com/platform/tools/gpu/binary/any"
"android.googlesource.com/platform/tools/gpu/binary/cyclic"
"android.googlesource.com/platform/tools/gpu/binary/vle"
"android.googlesource.com/platform/tools/gpu/log"
)
// Database is the interface to a resource store.
type Database interface {
// Store adds a key-value pair to the database.
// It is an error if the id is already mapped to an object.
Store(binary.ID, interface{}, log.Logger) error
// Resolve attempts to resolve the final value associated with an id.
// It will traverse all Lazy objects, blocking until they are ready.
Resolve(binary.ID, log.Logger) (interface{}, error)
// Containts returns true if the database has an entry for the specified id.
Contains(binary.ID, log.Logger) bool
}
// Store is a helper that stores v to the database with the id calculated by
// the Hash function.
func Store(v interface{}, d Database, l log.Logger) (binary.ID, error) {
id, err := Hash(v)
if err != nil {
return id, err
}
return id, d.Store(id, v, l)
}
// Resolve is a helper that resolves id from the database.
func Resolve(id binary.ID, d Database, l log.Logger) (interface{}, error) {
return d.Resolve(id, l)
}
// Build stores lazy into d, and then resolves and returns the lazy-built
// object.
func Build(lazy Lazy, d Database, l log.Logger) (interface{}, error) {
id, err := Store(lazy, d, l)
if err != nil {
return nil, err
}
return d.Resolve(id, l)
}
// Hash returns a unique binary.ID based on the contents of the object.
// Two objects of identical content will return the same ID, and the
// probability of two objects with different content generating the same ID
// will be ignorable.
// Objects with a graph structure are allowed.
// Only members that would be encoded using a binary.Encoder are considered.
func Hash(v interface{}) (binary.ID, error) {
id := binary.ID{}
h := sha1.New()
e := cyclic.Encoder(vle.Writer(h))
o, err := any.Box(v)
if err != nil {
return id, err
}
if err := e.Object(o); err != nil {
return id, err
}
copy(id[:], h.Sum(nil))
return id, nil
}