1package main
2
3import (
4 "fmt"
5 "io/ioutil"
6 "log"
7 "os"
8 "path"
9
10 "github.com/MichaelMure/git-bug/bug"
11 "github.com/MichaelMure/git-bug/misc/random_bugs"
12 "github.com/MichaelMure/git-bug/repository"
13 "github.com/MichaelMure/git-bug/util"
14 "github.com/ugorji/go/codec"
15)
16
17type writer func(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error)
18
19type testCase struct {
20 name string
21 writer writer
22}
23
24func main() {
25 packs := random_bugs.GenerateRandomOperationPacks(10, 5)
26
27 repo := createRepo(false)
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 total := int64(0)
53 for _, opp := range packs {
54 rawSize, hash, err := testcase.writer(opp, repo)
55 if err != nil {
56 panic(err)
57 }
58
59 size := blobSize(hash, repo)
60
61 total += size
62
63 ratio := float32(size) / float32(rawSize) * 100.0
64 fmt.Printf("raw: %v, git: %v, ratio: %v%%\n", rawSize, size, ratio)
65 }
66
67 fmt.Printf("total: %v\n", total)
68 }
69}
70
71func createRepo(bare bool) *repository.GitRepo {
72 dir, err := ioutil.TempDir("", "")
73 if err != nil {
74 log.Fatal(err)
75 }
76
77 fmt.Println("Creating repo:", dir)
78
79 var creator func(string) (*repository.GitRepo, error)
80
81 if bare {
82 creator = repository.InitBareGitRepo
83 } else {
84 creator = repository.InitGitRepo
85 }
86
87 repo, err := creator(dir)
88 if err != nil {
89 log.Fatal(err)
90 }
91
92 return repo
93}
94
95func writeData(data []byte, repo repository.Repo) (int, util.Hash, error) {
96 hash, err := repo.StoreData(data)
97
98 if err != nil {
99 return -1, "", err
100 }
101
102 return len(data), hash, nil
103}
104
105func blobSize(hash util.Hash, repo *repository.GitRepo) int64 {
106 rootPath := path.Join(repo.GetPath(), ".git", "objects")
107
108 prefix := hash.String()[:2]
109 suffix := hash.String()[2:]
110
111 blobPath := path.Join(rootPath, prefix, suffix)
112
113 fi, err := os.Stat(blobPath)
114 if err != nil {
115 panic(err)
116 }
117
118 return fi.Size()
119}
120
121func writeGOB(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error) {
122 data, err := opp.Serialize()
123 if err != nil {
124 return -1, "", err
125 }
126
127 return writeData(data, repo)
128}
129
130func writeJSON(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error) {
131 var data = make([]byte, 0, 64)
132 var h codec.Handle = new(codec.JsonHandle)
133 var enc = codec.NewEncoderBytes(&data, h)
134
135 err := enc.Encode(opp)
136 if err != nil {
137 return -1, "", err
138 }
139
140 return writeData(data, repo)
141}
142
143func writeCBOR(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error) {
144 var data = make([]byte, 0, 64)
145 var h codec.Handle = new(codec.CborHandle)
146 var enc = codec.NewEncoderBytes(&data, h)
147
148 err := enc.Encode(opp)
149 if err != nil {
150 return -1, "", err
151 }
152
153 return writeData(data, repo)
154}
155
156func writeMsgPack(opp *bug.OperationPack, repo repository.Repo) (int, util.Hash, error) {
157 var data = make([]byte, 0, 64)
158 var h codec.Handle = new(codec.MsgpackHandle)
159 var enc = codec.NewEncoderBytes(&data, h)
160
161 err := enc.Encode(opp)
162 if err != nil {
163 return -1, "", err
164 }
165
166 return writeData(data, repo)
167}