kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/platform/kcd/kzipdb/kzipdb.go (about) 1 /* 2 * Copyright 2018 The Kythe Authors. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Package kzipdb implements kcd.Reader using a kzip file as its backing 18 // store. See also: http://www.kythe.io/docs/kythe-kzip.html. 19 package kzipdb // import "kythe.io/kythe/go/platform/kcd/kzipdb" 20 21 import ( 22 "context" 23 24 "google.golang.org/protobuf/proto" 25 "kythe.io/kythe/go/platform/kcd" 26 "kythe.io/kythe/go/platform/kcd/kythe" 27 "kythe.io/kythe/go/platform/kzip" 28 ) 29 30 // DB implements kcd.Reader using a kzip.Reader as its backing store. 31 type DB struct { 32 Reader *kzip.Reader 33 } 34 35 // Revisions implements a method of kcd.Reader. 36 func (db DB) Revisions(ctx context.Context, want *kcd.RevisionsFilter, f func(kcd.Revision) error) error { 37 revisionMatches, err := want.Compile() 38 if err != nil { 39 return err 40 } 41 seen := make(map[kcd.Revision]bool) 42 return db.Reader.Scan(func(unit *kzip.Unit) error { 43 corpus := unit.Proto.GetVName().GetCorpus() 44 for _, revision := range unit.Index.GetRevisions() { 45 rev := kcd.Revision{Revision: revision, Corpus: corpus} 46 if !seen[rev] && revisionMatches(rev) { 47 if err := f(rev); err != nil { 48 return err 49 } 50 seen[rev] = true 51 } 52 } 53 return nil 54 }) 55 } 56 57 // Find implements a method of kcd.Reader. 58 func (db DB) Find(ctx context.Context, filter *kcd.FindFilter, f func(string) error) error { 59 cf, err := filter.Compile() 60 if err != nil { 61 return err 62 } else if cf == nil { 63 return nil 64 } 65 66 return db.Reader.Scan(func(unit *kzip.Unit) error { 67 idx := kythe.Unit{unit.Proto}.Index() 68 69 if cf.RevisionMatches(unit.Index.GetRevisions()...) && 70 cf.LanguageMatches(idx.Language) && 71 cf.TargetMatches(idx.Target) && 72 cf.OutputMatches(idx.Output) && 73 cf.SourcesMatch(idx.Sources...) { 74 return f(unit.Digest) 75 } 76 return nil 77 }) 78 } 79 80 // Units implements a method of kcd.Reader. 81 func (db DB) Units(ctx context.Context, unitDigests []string, f func(digest, key string, data []byte) error) error { 82 for _, digest := range unitDigests { 83 unit, err := db.Reader.Lookup(digest) 84 if err != nil { 85 return err 86 } 87 data, err := proto.Marshal(unit.Proto) 88 if err != nil { 89 return err 90 } 91 if err := f(unit.Digest, kythe.Format, data); err != nil { 92 return err 93 } 94 } 95 return nil 96 } 97 98 // Files implements a method of kcd.Reader. 99 func (db DB) Files(ctx context.Context, fileDigests []string, f func(string, []byte) error) error { 100 for _, digest := range fileDigests { 101 data, err := db.Reader.ReadAll(digest) 102 if err == kzip.ErrDigestNotFound { 103 continue 104 } else if err != nil { 105 return err 106 } 107 if err := f(digest, data); err != nil { 108 return err 109 } 110 } 111 return nil 112 } 113 114 // FilesExist implements a method of kcd.Reader. 115 func (db DB) FilesExist(ctx context.Context, fileDigests []string, f func(string) error) error { 116 for _, digest := range fileDigests { 117 rc, err := db.Reader.Open(digest) 118 if err == kzip.ErrDigestNotFound { 119 continue 120 } else if err != nil { 121 return err 122 } 123 rc.Close() 124 return f(digest) 125 } 126 return nil 127 }