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