Skip to content

Commit 8e0e44f

Browse files
committed
WIP: implement maxSize alongside maxCapacity
WIP TBD Signed-off-by: Francesco Romani <fromani@redhat.com>
1 parent 613ca36 commit 8e0e44f

1 file changed

Lines changed: 46 additions & 3 deletions

File tree

pkg/pfpstatus/record/recorder.go

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package record
1919
import (
2020
"errors"
2121
"time"
22+
"unsafe"
2223

2324
"github.com/k8stopologyawareschedwg/podfingerprint"
2425
)
@@ -36,6 +37,28 @@ type RecordedStatus struct {
3637
podfingerprint.Status
3738
// RecordTime is a timestamp of when the RecordedStatus was added to the record
3839
RecordTime time.Time `json:"recordTime"`
40+
statusSize int `json:"-"`
41+
}
42+
43+
func cloneStatus(st podfingerprint.Status) (podfingerprint.Status, int) {
44+
size := len(st.NodeName) + len(st.FingerprintExpected) + len(st.FingerprintComputed)
45+
pods := make([]podfingerprint.NamespacedName, len(st.Pods))
46+
for idx := 0; idx < len(st.Pods); idx++ {
47+
pods[idx].Namespace = st.Pods[idx].Namespace
48+
pods[idx].Name = st.Pods[idx].Name
49+
size += len(pods[idx].Namespace) + len(pods[idx].Name)
50+
}
51+
ret := podfingerprint.Status{
52+
FingerprintExpected: st.FingerprintExpected,
53+
FingerprintComputed: st.FingerprintComputed,
54+
Pods: pods,
55+
NodeName: st.NodeName,
56+
}
57+
return ret, size
58+
}
59+
60+
func (rs RecordedStatus) Size() int {
61+
return rs.statusSize + int(unsafe.Sizeof(rs.RecordTime))
3962
}
4063

4164
func (rs RecordedStatus) Equal(x RecordedStatus) bool {
@@ -51,6 +74,8 @@ type NodeRecorder struct {
5174
timestamper func() time.Time
5275
nodeName string // shortcut
5376
capacity int
77+
maxSize int
78+
size int
5479
statuses []RecordedStatus
5580
}
5681

@@ -62,6 +87,13 @@ func WithCapacity(capacity int) NodeOption {
6287
}
6388
}
6489

90+
func WithMaxSize(maxSize int) NodeOption {
91+
return func(nr *NodeRecorder) {
92+
nr.maxSize = maxSize
93+
nr.capacity = 1
94+
}
95+
}
96+
6597
// NewNodeRecorder creates a new recorder for the given node with the given capacity.
6698
// The record is a ring buffer, so only the latest <capacity> Statuses are kept at any time.
6799
// The timestamper callback is used to mark times. Use `time.Now` if unsure.
@@ -91,14 +123,21 @@ func (nr *NodeRecorder) dropOldest() {
91123
if nr.Len() < 1 {
92124
return
93125
}
126+
nr.size -= nr.statuses[0].Size()
94127
nr.statuses = nr.statuses[1:]
95128
}
96129

97130
func (nr *NodeRecorder) makeRoom() {
98-
if nr.Len() < nr.Cap() {
131+
if nr.capacity > 1 && nr.Len() == nr.Cap() {
132+
nr.dropOldest()
99133
return
100134
}
101-
nr.dropOldest()
135+
if nr.maxSize == 0 {
136+
return
137+
}
138+
for nr.size > nr.maxSize {
139+
nr.dropOldest()
140+
}
102141
}
103142

104143
// Push adds a new Status to the record, evicting the oldest Status if necessary.
@@ -113,16 +152,20 @@ func (nr *NodeRecorder) Push(st podfingerprint.Status) error {
113152
return ErrMismatchingNode
114153
}
115154
ts := nr.timestamper()
155+
cloned, size := cloneStatus(st)
116156
item := RecordedStatus{
117-
Status: st.Clone(),
157+
Status: cloned,
118158
RecordTime: ts,
159+
statusSize: size,
119160
}
120161
if nr.capacity == 1 { // handle common special case, avoid any resize
121162
nr.statuses[0] = item
163+
nr.size = item.Size()
122164
return nil
123165
}
124166
nr.makeRoom()
125167
nr.statuses = append(nr.statuses, item)
168+
nr.size += item.Size()
126169
return nil
127170
}
128171

0 commit comments

Comments
 (0)