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