1package cache
2
3import (
4 "encoding/gob"
5
6 "github.com/MichaelMure/git-bug/bug"
7 "github.com/MichaelMure/git-bug/identity"
8 "github.com/MichaelMure/git-bug/util/lamport"
9)
10
11// Package initialisation used to register the type for (de)serialization
12func init() {
13 gob.Register(BugExcerpt{})
14}
15
16// BugExcerpt hold a subset of the bug values to be able to sort and filter bugs
17// efficiently without having to read and compile each raw bugs.
18type BugExcerpt struct {
19 Id string
20
21 CreateLamportTime lamport.Time
22 EditLamportTime lamport.Time
23 CreateUnixTime int64
24 EditUnixTime int64
25
26 Title string
27 Status bug.Status
28 Author identity.Interface
29 LenComments int
30 Labels []bug.Label
31
32 CreateMetadata map[string]string
33}
34
35// identity.Bare data are directly embedded in the bug excerpt
36type LegacyAuthorExcerpt struct {
37 Name string
38 Login string
39}
40
41func NewBugExcerpt(b bug.Interface, snap *bug.Snapshot) *BugExcerpt {
42 e := &BugExcerpt{
43 Id: b.Id(),
44 CreateLamportTime: b.CreateLamportTime(),
45 EditLamportTime: b.EditLamportTime(),
46 CreateUnixTime: b.FirstOp().GetUnixTime(),
47 EditUnixTime: snap.LastEditUnix(),
48 Title: snap.Title,
49 Status: snap.Status,
50 Labels: snap.Labels,
51 LenComments: len(snap.Comments),
52 CreateMetadata: b.FirstOp().AllMetadata(),
53 }
54
55 return e
56}
57
58func (b *BugExcerpt) HumanId() string {
59 return bug.FormatHumanID(b.Id)
60}
61
62/*
63 * Sorting
64 */
65
66type BugsById []*BugExcerpt
67
68func (b BugsById) Len() int {
69 return len(b)
70}
71
72func (b BugsById) Less(i, j int) bool {
73 return b[i].Id < b[j].Id
74}
75
76func (b BugsById) Swap(i, j int) {
77 b[i], b[j] = b[j], b[i]
78}
79
80type BugsByCreationTime []*BugExcerpt
81
82func (b BugsByCreationTime) Len() int {
83 return len(b)
84}
85
86func (b BugsByCreationTime) Less(i, j int) bool {
87 if b[i].CreateLamportTime < b[j].CreateLamportTime {
88 return true
89 }
90
91 if b[i].CreateLamportTime > b[j].CreateLamportTime {
92 return false
93 }
94
95 // When the logical clocks are identical, that means we had a concurrent
96 // edition. In this case we rely on the timestamp. While the timestamp might
97 // be incorrect due to a badly set clock, the drift in sorting is bounded
98 // by the first sorting using the logical clock. That means that if users
99 // synchronize their bugs regularly, the timestamp will rarely be used, and
100 // should still provide a kinda accurate sorting when needed.
101 return b[i].CreateUnixTime < b[j].CreateUnixTime
102}
103
104func (b BugsByCreationTime) Swap(i, j int) {
105 b[i], b[j] = b[j], b[i]
106}
107
108type BugsByEditTime []*BugExcerpt
109
110func (b BugsByEditTime) Len() int {
111 return len(b)
112}
113
114func (b BugsByEditTime) Less(i, j int) bool {
115 if b[i].EditLamportTime < b[j].EditLamportTime {
116 return true
117 }
118
119 if b[i].EditLamportTime > b[j].EditLamportTime {
120 return false
121 }
122
123 // When the logical clocks are identical, that means we had a concurrent
124 // edition. In this case we rely on the timestamp. While the timestamp might
125 // be incorrect due to a badly set clock, the drift in sorting is bounded
126 // by the first sorting using the logical clock. That means that if users
127 // synchronize their bugs regularly, the timestamp will rarely be used, and
128 // should still provide a kinda accurate sorting when needed.
129 return b[i].EditUnixTime < b[j].EditUnixTime
130}
131
132func (b BugsByEditTime) Swap(i, j int) {
133 b[i], b[j] = b[j], b[i]
134}