@@ -6,10 +6,156 @@ import (
66 "bytes"
77 "fmt"
88 "math"
9+ "sync"
10+ "unsafe"
911
1012 "github.com/prometheus/prometheus/model/histogram"
13+ "google.golang.org/grpc/encoding"
14+ "google.golang.org/grpc/encoding/proto"
15+ "google.golang.org/grpc/mem"
1116)
1217
18+ func init () {
19+ c := encoding .GetCodecV2 (proto .Name )
20+ encoding .RegisterCodecV2 (& CodecV2 {
21+ c : c ,
22+ refs : map [uintptr ]mem.BufferSlice {},
23+ })
24+ }
25+
26+ type CodecV2 struct {
27+ c encoding.CodecV2
28+
29+ mtx sync.Mutex
30+ refs map [uintptr ]mem.BufferSlice
31+ }
32+
33+ func (* CodecV2 ) Name () string {
34+ return proto .Name
35+ }
36+
37+ func (c * CodecV2 ) Marshal (v any ) (out mem.BufferSlice , err error ) {
38+ return c .c .Marshal (v )
39+ }
40+
41+ func (c * CodecV2 ) Unmarshal (data mem.BufferSlice , v any ) error {
42+ if err := c .c .Unmarshal (data , v ); err != nil {
43+ return err
44+ }
45+
46+ switch fmt .Sprintf ("%T" , v ) {
47+ case "*alertmanagerpb.ReadStateRequest" :
48+ case "*alertmanagerpb.ReadStateResponse" :
49+ case "*alertmanagerpb.UpdateStateResponse" :
50+ case "*client.ActiveSeriesRequest" :
51+ case "*client.ActiveSeriesResponse" :
52+ case "*client.ExemplarQueryRequest" :
53+ case "*client.ExemplarQueryResponse" :
54+ case "*client.LabelNamesRequest" :
55+ case "*client.LabelNamesResponse" :
56+ case "*client.LabelNamesAndValuesRequest" :
57+ case "*client.LabelNamesAndValuesResponse" :
58+ case "*client.LabelValuesCardinalityRequest" :
59+ case "*client.LabelValuesCardinalityResponse" :
60+ case "*client.LabelValuesRequest" :
61+ case "*client.LabelValuesResponse" :
62+ case "*client.MetricsForLabelMatchersRequest" :
63+ case "*client.MetricsForLabelMatchersResponse" :
64+ case "*client.QueryRequest" :
65+ case "*client.QueryStreamResponse" :
66+ case "*client.UserStatsRequest" :
67+ case "*client.UserStatsResponse" :
68+ case "*clusterpb.Part" :
69+ case "*etcdserverpb.DeleteRangeResponse" :
70+ case "*etcdserverpb.RangeResponse" :
71+ case "*etcdserverpb.TxnResponse" :
72+ case "*etcdserverpb.WatchResponse" :
73+ case "*emptypb.Empty" :
74+ case "*frontendv1pb.ClientToFrontend" :
75+ case "*frontendv1pb.FrontendToClient" :
76+ case "*frontendv1pb.NotifyClientShutdownRequest" :
77+ case "*frontendv1pb.NotifyClientShutdownResponse" :
78+ case "*frontendv2pb.QueryResultRequest" :
79+ case "*frontendv2pb.QueryResultResponse" :
80+ case "*grpc_health_v1.HealthCheckRequest" :
81+ case "*grpc_health_v1.HealthCheckResponse" :
82+ case "*httpgrpc.HTTPRequest" :
83+ case "*httpgrpc.HTTPResponse" :
84+ case "*mimirpb.WriteRequest" :
85+ case "*mimirpb.WriteResponse" :
86+ case "*ruler.RulesRequest" :
87+ case "*ruler.RulesResponse" :
88+ case "*ruler.SyncRulesRequest" :
89+ case "*ruler.SyncRulesResponse" :
90+ case "*schedulerpb.FrontendToScheduler" :
91+ case "*schedulerpb.NotifyQuerierShutdownRequest" :
92+ case "*schedulerpb.NotifyQuerierShutdownResponse" :
93+ case "*schedulerpb.QuerierToScheduler" :
94+ case "*schedulerpb.SchedulerToFrontend" :
95+ case "*schedulerpb.SchedulerToQuerier" :
96+ case "*storepb.LabelNamesRequest" :
97+ case "*storepb.LabelValuesRequest" :
98+ case "*storepb.LabelValuesResponse" :
99+ case "*storepb.SeriesRequest" :
100+ case "*storepb.SeriesResponse" :
101+ default :
102+ panic (fmt .Errorf ("unrecognized protobuf message %T" , v ))
103+ }
104+
105+ /*
106+ switch x := v.(type) {
107+ case *WriteRequest:
108+ data.Ref()
109+ c.mtx.Lock()
110+ defer c.mtx.Unlock()
111+ c.refs[uintptr(unsafe.Pointer(x))] = data
112+ case *PreallocTimeseries:
113+ panic("unmarshaling PreallocTimeseries")
114+ case *LabelAdapter:
115+ panic("unmarshaling label adapter")
116+ }
117+ */
118+
119+ return nil
120+ }
121+
122+ // FreeWriteRequest frees a previously unmarshaled WriteRequest.
123+ func (c * CodecV2 ) FreeWriteRequest (req * WriteRequest ) {
124+ c .mtx .Lock ()
125+ defer c .mtx .Unlock ()
126+
127+ ptr := uintptr (unsafe .Pointer (& req ))
128+ c .refs [ptr ].Free ()
129+ delete (c .refs , ptr )
130+
131+ for i , ts := range req .Timeseries {
132+ ptr := uintptr (unsafe .Pointer (& req .Timeseries [i ]))
133+ c .refs [ptr ].Free ()
134+ delete (c .refs , ptr )
135+
136+ for j := range ts .Labels {
137+ ptr := uintptr (unsafe .Pointer (& ts .Labels [j ]))
138+ c .refs [ptr ].Free ()
139+ delete (c .refs , ptr )
140+ }
141+
142+ for _ , e := range ts .Exemplars {
143+ for j := range e .Labels {
144+ ptr := uintptr (unsafe .Pointer (& e .Labels [j ]))
145+ c .refs [ptr ].Free ()
146+ delete (c .refs , ptr )
147+ }
148+ }
149+ }
150+ }
151+
152+ type UnmarshalerV2 interface {
153+ UnmarshalV2 (encoding.CodecV2 , mem.BufferSlice ) error
154+ Free ()
155+ }
156+
157+ // var _ UnmarshalerV2 = &WriteRequest{}
158+
13159// MinTimestamp returns the minimum timestamp (milliseconds) among all series
14160// in the WriteRequest. Returns math.MaxInt64 if the request is empty.
15161func (m * WriteRequest ) MinTimestamp () int64 {
0 commit comments