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  }