Make explicit metadata queries lightweight
This commit is contained in:
@@ -19,10 +19,7 @@ type Metadata struct {
|
||||
// Lookup returns information for an effective path. Unknown and invalid paths
|
||||
// return false.
|
||||
func (m Metadata) Lookup(path Path) (FieldInfo, bool) {
|
||||
if !path.valid() || !matchesPathShape(path, m.effectivePaths[path.String()]) {
|
||||
return FieldInfo{}, false
|
||||
}
|
||||
info, ok := m.fields[path.String()]
|
||||
info, ok := m.effectiveField(path)
|
||||
if !ok {
|
||||
return FieldInfo{}, false
|
||||
}
|
||||
@@ -34,10 +31,23 @@ func (m Metadata) Lookup(path Path) (FieldInfo, bool) {
|
||||
// IsExplicit reports whether a surviving input contribution, including one
|
||||
// inherited from a sibling, explicitly defined path.
|
||||
func (m Metadata) IsExplicit(path Path) bool {
|
||||
info, ok := m.Lookup(path)
|
||||
info, ok := m.effectiveField(path)
|
||||
return ok && info.Explicit
|
||||
}
|
||||
|
||||
func (m Metadata) effectiveField(path Path) (FieldInfo, bool) {
|
||||
if !path.valid() {
|
||||
return FieldInfo{}, false
|
||||
}
|
||||
pointer := path.String()
|
||||
candidate, ok := m.effectivePaths[pointer]
|
||||
if !ok || !matchesPathShapeWithPointer(path, candidate, pointer) {
|
||||
return FieldInfo{}, false
|
||||
}
|
||||
info, ok := m.fields[pointer]
|
||||
return info, ok
|
||||
}
|
||||
|
||||
// History returns detached definition, inheritance, and resolution records for path. A record's
|
||||
// Path can be an ancestor when that container operation replaced or removed path.
|
||||
// Removed historical paths can have history even though Lookup returns false.
|
||||
@@ -79,7 +89,14 @@ func (m Metadata) HistoricalPaths() []Path {
|
||||
// Textual pointers are lookup keys, but explicit key/index kinds remain part of
|
||||
// the query. Candidate paths are constructed from actual document containers.
|
||||
func matchesPathShape(query, candidate Path) bool {
|
||||
if !query.valid() || query.String() != candidate.String() || len(query.segments) != len(candidate.segments) {
|
||||
if !query.valid() {
|
||||
return false
|
||||
}
|
||||
return matchesPathShapeWithPointer(query, candidate, query.String())
|
||||
}
|
||||
|
||||
func matchesPathShapeWithPointer(query, candidate Path, pointer string) bool {
|
||||
if pointer != candidate.String() || len(query.segments) != len(candidate.segments) {
|
||||
return false
|
||||
}
|
||||
for i, segment := range query.segments {
|
||||
|
||||
Reference in New Issue
Block a user