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