305 строки
10 KiB
Go
305 строки
10 KiB
Go
package sizes
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/github/git-sizer/counts"
|
|
"github.com/github/git-sizer/git"
|
|
)
|
|
|
|
type Size interface {
|
|
fmt.Stringer
|
|
}
|
|
|
|
type BlobSize struct {
|
|
Size counts.Count32
|
|
}
|
|
|
|
type TreeSize struct {
|
|
// The maximum depth of trees and blobs starting at this object
|
|
// (not including this object).
|
|
MaxPathDepth counts.Count32 `json:"max_path_depth"`
|
|
|
|
// The maximum length of any path relative to this object, in
|
|
// characters.
|
|
MaxPathLength counts.Count32 `json:"max_path_length"`
|
|
|
|
// The total number of trees, including duplicates.
|
|
ExpandedTreeCount counts.Count32 `json:"expanded_tree_count"`
|
|
|
|
// The total number of blobs, including duplicates.
|
|
ExpandedBlobCount counts.Count32 `json:"expanded_blob_count"`
|
|
|
|
// The total size of all blobs, including duplicates.
|
|
ExpandedBlobSize counts.Count64 `json:"expanded_blob_size"`
|
|
|
|
// The total number of symbolic links, including duplicates.
|
|
ExpandedLinkCount counts.Count32 `json:"expanded_link_count"`
|
|
|
|
// The total number of submodules referenced, including duplicates.
|
|
ExpandedSubmoduleCount counts.Count32 `json:"expanded_submodule_count"`
|
|
}
|
|
|
|
func (s *TreeSize) addDescendent(filename string, s2 TreeSize) {
|
|
s.MaxPathDepth.AdjustMaxIfNecessary(s2.MaxPathDepth.Plus(1))
|
|
if s2.MaxPathLength > 0 {
|
|
s.MaxPathLength.AdjustMaxIfNecessary(
|
|
(counts.NewCount32(uint64(len(filename))) + 1).Plus(s2.MaxPathLength),
|
|
)
|
|
} else {
|
|
s.MaxPathLength.AdjustMaxIfNecessary(counts.NewCount32(uint64(len(filename))))
|
|
}
|
|
s.ExpandedTreeCount.Increment(s2.ExpandedTreeCount)
|
|
s.ExpandedBlobCount.Increment(s2.ExpandedBlobCount)
|
|
s.ExpandedBlobSize.Increment(s2.ExpandedBlobSize)
|
|
s.ExpandedLinkCount.Increment(s2.ExpandedLinkCount)
|
|
s.ExpandedSubmoduleCount.Increment(s2.ExpandedSubmoduleCount)
|
|
}
|
|
|
|
// Record that the object has a blob of the specified `size` as a
|
|
// direct descendant.
|
|
func (s *TreeSize) addBlob(filename string, size BlobSize) {
|
|
s.MaxPathDepth.AdjustMaxIfNecessary(1)
|
|
s.MaxPathLength.AdjustMaxIfNecessary(counts.NewCount32(uint64(len(filename))))
|
|
s.ExpandedBlobSize.Increment(counts.Count64(size.Size))
|
|
s.ExpandedBlobCount.Increment(1)
|
|
}
|
|
|
|
// Record that the object has a link as a direct descendant.
|
|
func (s *TreeSize) addLink(filename string) {
|
|
s.MaxPathDepth.AdjustMaxIfNecessary(1)
|
|
s.MaxPathLength.AdjustMaxIfNecessary(counts.NewCount32(uint64(len(filename))))
|
|
s.ExpandedLinkCount.Increment(1)
|
|
}
|
|
|
|
// Record that the object has a submodule as a direct descendant.
|
|
func (s *TreeSize) addSubmodule(filename string) {
|
|
s.MaxPathDepth.AdjustMaxIfNecessary(1)
|
|
s.MaxPathLength.AdjustMaxIfNecessary(counts.NewCount32(uint64(len(filename))))
|
|
s.ExpandedSubmoduleCount.Increment(1)
|
|
}
|
|
|
|
type CommitSize struct {
|
|
// The height of the ancestor graph, including this commit.
|
|
MaxAncestorDepth counts.Count32 `json:"max_ancestor_depth"`
|
|
}
|
|
|
|
func (s *CommitSize) addParent(s2 CommitSize) {
|
|
s.MaxAncestorDepth.AdjustMaxIfNecessary(s2.MaxAncestorDepth)
|
|
}
|
|
|
|
func (s *CommitSize) addTree(s2 TreeSize) {
|
|
}
|
|
|
|
type TagSize struct {
|
|
// The number of tags that have to be traversed (including this
|
|
// one) to get to an object.
|
|
TagDepth counts.Count32
|
|
}
|
|
|
|
type HistorySize struct {
|
|
// The total number of unique commits analyzed.
|
|
UniqueCommitCount counts.Count32 `json:"unique_commit_count"`
|
|
|
|
// The total size of all commits analyzed.
|
|
UniqueCommitSize counts.Count64 `json:"unique_commit_size"`
|
|
|
|
// The maximum size of any analyzed commit.
|
|
MaxCommitSize counts.Count32 `json:"max_commit_size"`
|
|
|
|
// The commit with the maximum size.
|
|
MaxCommitSizeCommit *Path `json:"max_commit,omitempty"`
|
|
|
|
// The maximum ancestor depth of any analyzed commit.
|
|
MaxHistoryDepth counts.Count32 `json:"max_history_depth"`
|
|
|
|
// The maximum number of direct parents of any analyzed commit.
|
|
MaxParentCount counts.Count32 `json:"max_parent_count"`
|
|
|
|
// The commit with the maximum number of direct parents.
|
|
MaxParentCountCommit *Path `json:"max_parent_count_commit,omitempty"`
|
|
|
|
// The total number of unique trees analyzed.
|
|
UniqueTreeCount counts.Count32 `json:"unique_tree_count"`
|
|
|
|
// The total size of all trees analyzed.
|
|
UniqueTreeSize counts.Count64 `json:"unique_tree_size"`
|
|
|
|
// The total number of tree entries in all unique trees analyzed.
|
|
UniqueTreeEntries counts.Count64 `json:"unique_tree_entries"`
|
|
|
|
// The maximum number of entries an a tree.
|
|
MaxTreeEntries counts.Count32 `json:"max_tree_entries"`
|
|
|
|
// The tree with the maximum number of entries.
|
|
MaxTreeEntriesTree *Path `json:"max_tree_entries_tree,omitempty"`
|
|
|
|
// The total number of unique blobs analyzed.
|
|
UniqueBlobCount counts.Count32 `json:"unique_blob_count"`
|
|
|
|
// The total size of all of the unique blobs analyzed.
|
|
UniqueBlobSize counts.Count64 `json:"unique_blob_size"`
|
|
|
|
// The maximum size of any analyzed blob.
|
|
MaxBlobSize counts.Count32 `json:"max_blob_size"`
|
|
|
|
// The biggest blob found.
|
|
MaxBlobSizeBlob *Path `json:"max_blob_size_blob,omitempty"`
|
|
|
|
// The total number of unique tag objects analyzed.
|
|
UniqueTagCount counts.Count32 `json:"unique_tag_count"`
|
|
|
|
// The maximum number of tags in a chain.
|
|
MaxTagDepth counts.Count32 `json:"max_tag_depth"`
|
|
|
|
// The tag with the maximum tag depth.
|
|
MaxTagDepthTag *Path `json:"max_tag_depth_tag,omitempty"`
|
|
|
|
// The number of references analyzed. Note that we don't eliminate
|
|
// duplicates if the user passes the same reference more than
|
|
// once.
|
|
ReferenceCount counts.Count32 `json:"reference_count"`
|
|
|
|
// ReferenceGroups keeps track of how many references in each
|
|
// reference group were scanned.
|
|
ReferenceGroups map[RefGroupSymbol]*counts.Count32 `json:"reference_groups"`
|
|
|
|
// The maximum TreeSize in the analyzed history (where each
|
|
// attribute is maximized separately).
|
|
|
|
// The maximum depth of trees and blobs starting at this object
|
|
// (not including this object).
|
|
MaxPathDepth counts.Count32 `json:"max_path_depth"`
|
|
|
|
// The tree with the maximum path depth.
|
|
MaxPathDepthTree *Path `json:"max_path_depth_tree,omitempty"`
|
|
|
|
// The maximum length of any path relative to this object, in
|
|
// characters.
|
|
MaxPathLength counts.Count32 `json:"max_path_length"`
|
|
|
|
// The tree with the maximum path length.
|
|
MaxPathLengthTree *Path `json:"max_path_length_tree,omitempty"`
|
|
|
|
// The total number of trees, including duplicates.
|
|
MaxExpandedTreeCount counts.Count32 `json:"max_expanded_tree_count"`
|
|
|
|
// The tree with the maximum expanded tree count.
|
|
MaxExpandedTreeCountTree *Path `json:"max_expanded_tree_count_tree,omitempty"`
|
|
|
|
// The total number of blobs, including duplicates.
|
|
MaxExpandedBlobCount counts.Count32 `json:"max_expanded_blob_count"`
|
|
|
|
// The tree with the maximum expanded blob count.
|
|
MaxExpandedBlobCountTree *Path `json:"max_expanded_blob_count_tree,omitempty"`
|
|
|
|
// The total size of all blobs, including duplicates.
|
|
MaxExpandedBlobSize counts.Count64 `json:"max_expanded_blob_size"`
|
|
|
|
// The tree with the maximum expanded blob size.
|
|
MaxExpandedBlobSizeTree *Path `json:"max_expanded_blob_size_tree,omitempty"`
|
|
|
|
// The total number of symbolic links, including duplicates.
|
|
MaxExpandedLinkCount counts.Count32 `json:"max_expanded_link_count"`
|
|
|
|
// The tree with the maximum expanded link count.
|
|
MaxExpandedLinkCountTree *Path `json:"max_expanded_link_count_tree,omitempty"`
|
|
|
|
// The total number of submodules referenced, including duplicates.
|
|
MaxExpandedSubmoduleCount counts.Count32 `json:"max_expanded_submodule_count"`
|
|
|
|
// The tree with the maximum expanded submodule count.
|
|
MaxExpandedSubmoduleCountTree *Path `json:"max_expanded_submodule_count_tree,omitempty"`
|
|
}
|
|
|
|
// Convenience function: forget `*path` if it is non-nil and overwrite
|
|
// it with a `*Path` for the object corresponding to `(oid,
|
|
// objectType)`. This function can be used if a new largest item was
|
|
// found.
|
|
func setPath(
|
|
pr PathResolver,
|
|
path **Path,
|
|
oid git.OID, objectType string) {
|
|
if *path != nil {
|
|
pr.ForgetPath(*path)
|
|
}
|
|
*path = pr.RequestPath(oid, objectType)
|
|
}
|
|
|
|
func (s *HistorySize) recordBlob(g *Graph, oid git.OID, blobSize BlobSize) {
|
|
s.UniqueBlobCount.Increment(1)
|
|
s.UniqueBlobSize.Increment(counts.Count64(blobSize.Size))
|
|
if s.MaxBlobSize.AdjustMaxIfNecessary(blobSize.Size) {
|
|
setPath(g.pathResolver, &s.MaxBlobSizeBlob, oid, "blob")
|
|
}
|
|
}
|
|
|
|
func (s *HistorySize) recordTree(
|
|
g *Graph, oid git.OID, treeSize TreeSize, size counts.Count32, treeEntries counts.Count32,
|
|
) {
|
|
s.UniqueTreeCount.Increment(1)
|
|
s.UniqueTreeSize.Increment(counts.Count64(size))
|
|
s.UniqueTreeEntries.Increment(counts.Count64(treeEntries))
|
|
if s.MaxTreeEntries.AdjustMaxIfNecessary(treeEntries) {
|
|
setPath(g.pathResolver, &s.MaxTreeEntriesTree, oid, "tree")
|
|
}
|
|
|
|
if s.MaxPathDepth.AdjustMaxIfNecessary(treeSize.MaxPathDepth) {
|
|
setPath(g.pathResolver, &s.MaxPathDepthTree, oid, "tree")
|
|
}
|
|
if s.MaxPathLength.AdjustMaxIfNecessary(treeSize.MaxPathLength) {
|
|
setPath(g.pathResolver, &s.MaxPathLengthTree, oid, "tree")
|
|
}
|
|
if s.MaxExpandedTreeCount.AdjustMaxIfNecessary(treeSize.ExpandedTreeCount) {
|
|
setPath(g.pathResolver, &s.MaxExpandedTreeCountTree, oid, "tree")
|
|
}
|
|
if s.MaxExpandedBlobCount.AdjustMaxIfNecessary(treeSize.ExpandedBlobCount) {
|
|
setPath(g.pathResolver, &s.MaxExpandedBlobCountTree, oid, "tree")
|
|
}
|
|
if s.MaxExpandedBlobSize.AdjustMaxIfNecessary(treeSize.ExpandedBlobSize) {
|
|
setPath(g.pathResolver, &s.MaxExpandedBlobSizeTree, oid, "tree")
|
|
}
|
|
if s.MaxExpandedLinkCount.AdjustMaxIfNecessary(treeSize.ExpandedLinkCount) {
|
|
setPath(g.pathResolver, &s.MaxExpandedLinkCountTree, oid, "tree")
|
|
}
|
|
if s.MaxExpandedSubmoduleCount.AdjustMaxIfNecessary(treeSize.ExpandedSubmoduleCount) {
|
|
setPath(g.pathResolver, &s.MaxExpandedSubmoduleCountTree, oid, "tree")
|
|
}
|
|
}
|
|
|
|
func (s *HistorySize) recordCommit(
|
|
g *Graph, oid git.OID, commitSize CommitSize,
|
|
size counts.Count32, parentCount counts.Count32,
|
|
) {
|
|
s.UniqueCommitCount.Increment(1)
|
|
s.UniqueCommitSize.Increment(counts.Count64(size))
|
|
if s.MaxCommitSize.AdjustMaxIfPossible(size) {
|
|
setPath(g.pathResolver, &s.MaxCommitSizeCommit, oid, "commit")
|
|
}
|
|
s.MaxHistoryDepth.AdjustMaxIfPossible(commitSize.MaxAncestorDepth)
|
|
if s.MaxParentCount.AdjustMaxIfPossible(parentCount) {
|
|
setPath(g.pathResolver, &s.MaxParentCountCommit, oid, "commit")
|
|
}
|
|
}
|
|
|
|
func (s *HistorySize) recordTag(g *Graph, oid git.OID, tagSize TagSize, size counts.Count32) {
|
|
s.UniqueTagCount.Increment(1)
|
|
if s.MaxTagDepth.AdjustMaxIfNecessary(tagSize.TagDepth) {
|
|
setPath(g.pathResolver, &s.MaxTagDepthTag, oid, "tag")
|
|
}
|
|
}
|
|
|
|
func (s *HistorySize) recordReference(g *Graph, ref git.Reference) {
|
|
s.ReferenceCount.Increment(1)
|
|
}
|
|
|
|
func (s *HistorySize) recordReferenceGroup(g *Graph, group RefGroupSymbol) {
|
|
c, ok := s.ReferenceGroups[group]
|
|
if ok {
|
|
c.Increment(1)
|
|
} else {
|
|
n := counts.Count32(1)
|
|
s.ReferenceGroups[group] = &n
|
|
}
|
|
}
|