main.go

  1package main
  2
  3import (
  4	"fmt"
  5	"io/ioutil"
  6	"log"
  7	"os"
  8	"path"
  9	"path/filepath"
 10
 11	"github.com/MichaelMure/git-bug/bug"
 12	"github.com/MichaelMure/git-bug/misc/random_bugs"
 13	"github.com/MichaelMure/git-bug/repository"
 14	"github.com/MichaelMure/git-bug/util"
 15	"github.com/dustin/go-humanize"
 16	"github.com/ugorji/go/codec"
 17)
 18
 19type writer func(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error)
 20
 21type testCase struct {
 22	name   string
 23	writer writer
 24}
 25
 26func main() {
 27	packs := random_bugs.GenerateRandomOperationPacks(1000, 5)
 28
 29	testCases := []testCase{
 30		{
 31			name:   "GOB",
 32			writer: writeGOB,
 33		},
 34		{
 35			name:   "JSON",
 36			writer: writeJSON,
 37		},
 38		{
 39			name:   "CBOR",
 40			writer: writeCBOR,
 41		},
 42		{
 43			name:   "MsgPack",
 44			writer: writeMsgPack,
 45		},
 46	}
 47
 48	for _, testcase := range testCases {
 49		fmt.Println()
 50		fmt.Println(testcase.name)
 51
 52		repo := createRepo(false)
 53
 54		sizeEmpty, err := dirSize(repo.GetPath())
 55		if err != nil {
 56			panic(err)
 57		}
 58
 59		// total := int64(0)
 60		for i, opp := range packs {
 61			rawSize, hash, err := testcase.writer(opp, repo)
 62			if err != nil {
 63				panic(err)
 64			}
 65
 66			size := blobSize(hash, repo)
 67
 68			// total += size
 69
 70			if i < 10 {
 71				ratio := float32(size) / float32(rawSize) * 100.0
 72				fmt.Printf("raw: %v, git: %v, ratio: %v%%\n", rawSize, size, ratio)
 73			}
 74		}
 75
 76		fmt.Println("...")
 77
 78		sizeFilled, err := dirSize(repo.GetPath())
 79		if err != nil {
 80			panic(err)
 81		}
 82
 83		err = repo.GC()
 84		if err != nil {
 85			panic(err)
 86		}
 87
 88		sizePacked, err := dirSize(repo.GetPath())
 89		if err != nil {
 90			panic(err)
 91		}
 92
 93		err = repo.GCAggressive()
 94		if err != nil {
 95			panic(err)
 96		}
 97
 98		sizeAggressive, err := dirSize(repo.GetPath())
 99		if err != nil {
100			panic(err)
101		}
102
103		fmt.Printf("Unpacked: %v\n", humanize.Bytes(uint64(sizeFilled-sizeEmpty)))
104		fmt.Printf("GC packed: %v\n", humanize.Bytes(uint64(sizePacked-sizeEmpty)))
105		fmt.Printf("Packing diff: %v\n", sizePacked-sizeFilled)
106		fmt.Printf("GC packed aggressive: %v\n", humanize.Bytes(uint64(sizeAggressive-sizeEmpty)))
107		fmt.Printf("Packing diff: %v\n", sizeAggressive-sizePacked)
108	}
109}
110
111func createRepo(bare bool) *repository.GitRepo {
112	dir, err := ioutil.TempDir("", "")
113	if err != nil {
114		log.Fatal(err)
115	}
116
117	fmt.Println("Creating repo:", dir)
118
119	var creator func(string) (*repository.GitRepo, error)
120
121	if bare {
122		creator = repository.InitBareGitRepo
123	} else {
124		creator = repository.InitGitRepo
125	}
126
127	repo, err := creator(dir)
128	if err != nil {
129		log.Fatal(err)
130	}
131
132	return repo
133}
134
135func writeData(data []byte, repo repository.Repo) (int, util.Hash, error) {
136	hash, err := repo.StoreData(data)
137
138	if err != nil {
139		return -1, "", err
140	}
141
142	return len(data), hash, nil
143}
144
145func blobSize(hash util.Hash, repo *repository.GitRepo) int64 {
146	rootPath := path.Join(repo.GetPath(), ".git", "objects")
147
148	prefix := hash.String()[:2]
149	suffix := hash.String()[2:]
150
151	blobPath := path.Join(rootPath, prefix, suffix)
152
153	fi, err := os.Stat(blobPath)
154	if err != nil {
155		panic(err)
156	}
157
158	return fi.Size()
159}
160
161func dirSize(path string) (int64, error) {
162	var size int64
163	err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
164		if !info.IsDir() {
165			size += info.Size()
166		}
167		return err
168	})
169	return size, err
170}
171
172func writeGOB(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error) {
173	data, err := opp.Serialize()
174	if err != nil {
175		return -1, "", err
176	}
177
178	return writeData(data, repo)
179}
180
181func writeJSON(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error) {
182	var data = make([]byte, 0, 64)
183	var h codec.Handle = new(codec.JsonHandle)
184	var enc = codec.NewEncoderBytes(&data, h)
185
186	err := enc.Encode(opp)
187	if err != nil {
188		return -1, "", err
189	}
190
191	return writeData(data, repo)
192}
193
194func writeCBOR(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error) {
195	var data = make([]byte, 0, 64)
196	var h codec.Handle = new(codec.CborHandle)
197	var enc = codec.NewEncoderBytes(&data, h)
198
199	err := enc.Encode(opp)
200	if err != nil {
201		return -1, "", err
202	}
203
204	return writeData(data, repo)
205}
206
207func writeMsgPack(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error) {
208	var data = make([]byte, 0, 64)
209	var h codec.Handle = new(codec.MsgpackHandle)
210	var enc = codec.NewEncoderBytes(&data, h)
211
212	err := enc.Encode(opp)
213	if err != nil {
214		return -1, "", err
215	}
216
217	return writeData(data, repo)
218}