1#![deny(missing_docs)]
2use std::{iter, slice, vec};
6
7use futures::{Stream, stream};
8#[cfg(test)]
9use quickcheck::{Arbitrary, Gen};
10use vector_buffers::EventCount;
11use vector_common::{
12 byte_size_of::ByteSizeOf,
13 finalization::{
14 AddBatchNotifier, BatchNotifier, EventFinalizerGroups, EventFinalizers, Finalizable,
15 GroupedFinalizable, MergeFinalizable,
16 },
17 json_size::JsonSize,
18};
19
20use super::{
21 EstimatedJsonEncodedSizeOf, Event, EventDataEq, EventFinalizer, EventMetadata, EventMutRef,
22 EventRef, LogEvent, Metric, TraceEvent,
23};
24
25pub type LogArray = Vec<LogEvent>;
27
28pub type TraceArray = Vec<TraceEvent>;
30
31pub type MetricArray = Vec<Metric>;
33
34pub trait EventContainer: ByteSizeOf + EstimatedJsonEncodedSizeOf {
39 type IntoIter: Iterator<Item = Event>;
41
42 fn len(&self) -> usize;
44
45 fn is_empty(&self) -> bool {
47 self.len() == 0
48 }
49
50 fn into_events(self) -> Self::IntoIter;
52}
53
54pub fn into_event_stream(container: impl EventContainer) -> impl Stream<Item = Event> + Unpin {
60 stream::iter(container.into_events())
61}
62
63impl EventContainer for Event {
64 type IntoIter = iter::Once<Event>;
65
66 fn len(&self) -> usize {
67 1
68 }
69
70 fn is_empty(&self) -> bool {
71 false
72 }
73
74 fn into_events(self) -> Self::IntoIter {
75 iter::once(self)
76 }
77}
78
79impl EventContainer for LogEvent {
80 type IntoIter = iter::Once<Event>;
81
82 fn len(&self) -> usize {
83 1
84 }
85
86 fn is_empty(&self) -> bool {
87 false
88 }
89
90 fn into_events(self) -> Self::IntoIter {
91 iter::once(self.into())
92 }
93}
94
95impl EventContainer for Metric {
96 type IntoIter = iter::Once<Event>;
97
98 fn len(&self) -> usize {
99 1
100 }
101
102 fn is_empty(&self) -> bool {
103 false
104 }
105
106 fn into_events(self) -> Self::IntoIter {
107 iter::once(self.into())
108 }
109}
110
111impl EventContainer for LogArray {
112 type IntoIter = iter::Map<vec::IntoIter<LogEvent>, fn(LogEvent) -> Event>;
113
114 fn len(&self) -> usize {
115 self.len()
116 }
117
118 fn into_events(self) -> Self::IntoIter {
119 self.into_iter().map(Into::into)
120 }
121}
122
123impl EventContainer for MetricArray {
124 type IntoIter = iter::Map<vec::IntoIter<Metric>, fn(Metric) -> Event>;
125
126 fn len(&self) -> usize {
127 self.len()
128 }
129
130 fn into_events(self) -> Self::IntoIter {
131 self.into_iter().map(Into::into)
132 }
133}
134
135#[derive(Clone, Debug, PartialEq)]
137pub enum EventArray {
138 Logs(LogArray),
140 Metrics(MetricArray),
142 Traces(TraceArray),
144}
145
146impl EventArray {
147 pub fn iter_events(&self) -> impl Iterator<Item = EventRef<'_>> {
149 match self {
150 Self::Logs(array) => EventArrayIter::Logs(array.iter()),
151 Self::Metrics(array) => EventArrayIter::Metrics(array.iter()),
152 Self::Traces(array) => EventArrayIter::Traces(array.iter()),
153 }
154 }
155
156 pub fn iter_events_mut(&mut self) -> impl Iterator<Item = EventMutRef<'_>> {
158 match self {
159 Self::Logs(array) => EventArrayIterMut::Logs(array.iter_mut()),
160 Self::Metrics(array) => EventArrayIterMut::Metrics(array.iter_mut()),
161 Self::Traces(array) => EventArrayIterMut::Traces(array.iter_mut()),
162 }
163 }
164
165 pub fn iter_logs_mut(&mut self) -> impl Iterator<Item = &mut LogEvent> {
167 match self {
168 Self::Logs(array) => TypedArrayIterMut(Some(array.iter_mut())),
169 _ => TypedArrayIterMut(None),
170 }
171 }
172
173 pub fn for_each_metadata_mut(&mut self, mut f: impl FnMut(&mut EventMetadata)) {
175 match self {
176 Self::Logs(logs) => {
177 for log in logs {
178 f(log.metadata_mut());
179 }
180 }
181 Self::Metrics(metrics) => {
182 for metric in metrics {
183 f(metric.metadata_mut());
184 }
185 }
186 Self::Traces(traces) => {
187 for trace in traces {
188 f(trace.metadata_mut());
189 }
190 }
191 }
192 }
193}
194
195impl From<Event> for EventArray {
196 fn from(event: Event) -> Self {
197 match event {
198 Event::Log(log) => Self::Logs(vec![log]),
199 Event::Metric(metric) => Self::Metrics(vec![metric]),
200 Event::Trace(trace) => Self::Traces(vec![trace]),
201 }
202 }
203}
204
205impl From<LogEvent> for EventArray {
206 fn from(log: LogEvent) -> Self {
207 Event::from(log).into()
208 }
209}
210
211impl From<Metric> for EventArray {
212 fn from(metric: Metric) -> Self {
213 Event::from(metric).into()
214 }
215}
216
217impl From<TraceEvent> for EventArray {
218 fn from(trace: TraceEvent) -> Self {
219 Event::from(trace).into()
220 }
221}
222
223impl From<LogArray> for EventArray {
224 fn from(array: LogArray) -> Self {
225 Self::Logs(array)
226 }
227}
228
229impl From<MetricArray> for EventArray {
230 fn from(array: MetricArray) -> Self {
231 Self::Metrics(array)
232 }
233}
234
235impl AddBatchNotifier for EventArray {
236 fn add_batch_notifier(&mut self, batch: BatchNotifier) {
237 match self {
238 Self::Logs(array) => array
239 .iter_mut()
240 .for_each(|item| item.add_finalizer(EventFinalizer::new(batch.clone()))),
241 Self::Metrics(array) => array
242 .iter_mut()
243 .for_each(|item| item.add_finalizer(EventFinalizer::new(batch.clone()))),
244 Self::Traces(array) => array
245 .iter_mut()
246 .for_each(|item| item.add_finalizer(EventFinalizer::new(batch.clone()))),
247 }
248 }
249}
250
251impl ByteSizeOf for EventArray {
252 fn allocated_bytes(&self) -> usize {
253 match self {
254 Self::Logs(a) => a.allocated_bytes(),
255 Self::Metrics(a) => a.allocated_bytes(),
256 Self::Traces(a) => a.allocated_bytes(),
257 }
258 }
259}
260
261impl EstimatedJsonEncodedSizeOf for EventArray {
262 fn estimated_json_encoded_size_of(&self) -> JsonSize {
263 match self {
264 Self::Logs(v) => v.estimated_json_encoded_size_of(),
265 Self::Traces(v) => v.estimated_json_encoded_size_of(),
266 Self::Metrics(v) => v.estimated_json_encoded_size_of(),
267 }
268 }
269}
270
271impl EventCount for EventArray {
272 fn event_count(&self) -> usize {
273 match self {
274 Self::Logs(a) => a.len(),
275 Self::Metrics(a) => a.len(),
276 Self::Traces(a) => a.len(),
277 }
278 }
279}
280
281impl EventContainer for EventArray {
282 type IntoIter = EventArrayIntoIter;
283
284 fn len(&self) -> usize {
285 match self {
286 Self::Logs(a) => a.len(),
287 Self::Metrics(a) => a.len(),
288 Self::Traces(a) => a.len(),
289 }
290 }
291
292 fn into_events(self) -> Self::IntoIter {
293 match self {
294 Self::Logs(a) => EventArrayIntoIter::Logs(a.into_iter()),
295 Self::Metrics(a) => EventArrayIntoIter::Metrics(a.into_iter()),
296 Self::Traces(a) => EventArrayIntoIter::Traces(a.into_iter()),
297 }
298 }
299}
300
301impl EventDataEq for EventArray {
302 fn event_data_eq(&self, other: &Self) -> bool {
303 match (self, other) {
304 (Self::Logs(a), Self::Logs(b)) => a.event_data_eq(b),
305 (Self::Metrics(a), Self::Metrics(b)) => a.event_data_eq(b),
306 (Self::Traces(a), Self::Traces(b)) => a.event_data_eq(b),
307 _ => false,
308 }
309 }
310}
311
312impl Finalizable for EventArray {
313 fn take_finalizers(&mut self) -> EventFinalizers {
314 match self {
315 Self::Logs(a) => a.iter_mut().map(Finalizable::take_finalizers).collect(),
316 Self::Metrics(a) => a.iter_mut().map(Finalizable::take_finalizers).collect(),
317 Self::Traces(a) => a.iter_mut().map(Finalizable::take_finalizers).collect(),
318 }
319 }
320
321 fn take_finalizer_groups(&mut self) -> EventFinalizerGroups {
322 match self {
323 Self::Logs(a) => a.iter_mut().map(Finalizable::take_finalizers).collect(),
324 Self::Metrics(a) => a.iter_mut().map(Finalizable::take_finalizers).collect(),
325 Self::Traces(a) => a.iter_mut().map(Finalizable::take_finalizers).collect(),
326 }
327 }
328}
329
330impl GroupedFinalizable for EventArray {
331 fn merge_finalizer_groups(&mut self, finalizers: EventFinalizerGroups) {
332 fn merge_into<T: MergeFinalizable>(items: &mut [T], finalizers: EventFinalizerGroups) {
333 assert_eq!(
334 items.len(),
335 finalizers.len(),
336 "finalizer group count must match EventArray length"
337 );
338
339 for (item, finalizers) in items.iter_mut().zip(finalizers.into_groups()) {
340 item.merge_finalizers(finalizers);
341 }
342 }
343
344 match self {
345 Self::Logs(a) => merge_into(a, finalizers),
346 Self::Metrics(a) => merge_into(a, finalizers),
347 Self::Traces(a) => merge_into(a, finalizers),
348 }
349 }
350}
351
352#[cfg(test)]
353mod tests {
354 use tokio::sync::oneshot::error::TryRecvError;
355 use vector_common::finalization::{BatchStatus, EventStatus};
356
357 use super::*;
358
359 #[test]
360 fn grouped_finalizer_round_trip_preserves_event_ownership() {
361 let (first_batch, mut first_rx) = BatchNotifier::new_with_receiver();
362 let (second_batch, mut second_rx) = BatchNotifier::new_with_receiver();
363
364 let mut first = LogEvent::default();
365 first.add_finalizer(EventFinalizer::new(first_batch));
366
367 let mut second = LogEvent::default();
368 second.add_finalizer(EventFinalizer::new(second_batch));
369
370 let mut array = EventArray::Logs(vec![first, second]);
371 let finalizers = array.take_finalizer_groups();
372 array.merge_finalizer_groups(finalizers);
373
374 let mut events = array.into_events();
375 let mut first = events.next().expect("first event must exist");
376 let mut second = events.next().expect("second event must exist");
377 assert!(events.next().is_none());
378
379 let first_finalizers = first.take_finalizers();
380 first_finalizers.update_status(EventStatus::Delivered);
381 drop(first_finalizers);
382
383 assert_eq!(first_rx.try_recv(), Ok(BatchStatus::Delivered));
384 assert!(matches!(second_rx.try_recv(), Err(TryRecvError::Empty)));
385
386 let second_finalizers = second.take_finalizers();
387 second_finalizers.update_status(EventStatus::Errored);
388 drop(second_finalizers);
389
390 assert_eq!(second_rx.try_recv(), Ok(BatchStatus::Errored));
391 }
392
393 #[test]
394 fn empty_event_array_grouped_round_trip() {
395 let mut array = EventArray::Logs(Vec::new());
396 let finalizers = array.take_finalizer_groups();
397
398 assert!(finalizers.is_empty());
399 array.merge_finalizer_groups(finalizers);
400 assert!(array.is_empty());
401 }
402}
403
404#[cfg(test)]
405impl Arbitrary for EventArray {
406 fn arbitrary(g: &mut Gen) -> Self {
407 let len = u8::arbitrary(g) as usize;
408 let choice: u8 = u8::arbitrary(g);
409 if choice.is_multiple_of(2) {
412 let mut logs = Vec::new();
413 for _ in 0..len {
414 logs.push(LogEvent::arbitrary(g));
415 }
416 EventArray::Logs(logs)
417 } else {
418 let mut metrics = Vec::new();
419 for _ in 0..len {
420 metrics.push(Metric::arbitrary(g));
421 }
422 EventArray::Metrics(metrics)
423 }
424 }
425
426 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
427 match self {
428 EventArray::Logs(logs) => Box::new(logs.shrink().map(EventArray::Logs)),
429 EventArray::Metrics(metrics) => Box::new(metrics.shrink().map(EventArray::Metrics)),
430 EventArray::Traces(traces) => Box::new(traces.shrink().map(EventArray::Traces)),
431 }
432 }
433}
434
435#[derive(Debug)]
437pub enum EventArrayIter<'a> {
438 Logs(slice::Iter<'a, LogEvent>),
440 Metrics(slice::Iter<'a, Metric>),
442 Traces(slice::Iter<'a, TraceEvent>),
444}
445
446impl<'a> Iterator for EventArrayIter<'a> {
447 type Item = EventRef<'a>;
448
449 fn next(&mut self) -> Option<Self::Item> {
450 match self {
451 Self::Logs(i) => i.next().map(EventRef::from),
452 Self::Metrics(i) => i.next().map(EventRef::from),
453 Self::Traces(i) => i.next().map(EventRef::from),
454 }
455 }
456}
457
458#[derive(Debug)]
460pub enum EventArrayIterMut<'a> {
461 Logs(slice::IterMut<'a, LogEvent>),
463 Metrics(slice::IterMut<'a, Metric>),
465 Traces(slice::IterMut<'a, TraceEvent>),
467}
468
469impl<'a> Iterator for EventArrayIterMut<'a> {
470 type Item = EventMutRef<'a>;
471
472 fn next(&mut self) -> Option<Self::Item> {
473 match self {
474 Self::Logs(i) => i.next().map(EventMutRef::from),
475 Self::Metrics(i) => i.next().map(EventMutRef::from),
476 Self::Traces(i) => i.next().map(EventMutRef::from),
477 }
478 }
479}
480
481#[derive(Debug)]
483pub enum EventArrayIntoIter {
484 Logs(vec::IntoIter<LogEvent>),
486 Metrics(vec::IntoIter<Metric>),
488 Traces(vec::IntoIter<TraceEvent>),
490}
491
492impl Iterator for EventArrayIntoIter {
493 type Item = Event;
494
495 fn next(&mut self) -> Option<Self::Item> {
496 match self {
497 Self::Logs(i) => i.next().map(Into::into),
498 Self::Metrics(i) => i.next().map(Into::into),
499 Self::Traces(i) => i.next().map(Event::Trace),
500 }
501 }
502}
503
504struct TypedArrayIterMut<'a, T>(Option<slice::IterMut<'a, T>>);
505
506impl<'a, T> Iterator for TypedArrayIterMut<'a, T> {
507 type Item = &'a mut T;
508 fn next(&mut self) -> Option<Self::Item> {
509 self.0.as_mut().and_then(Iterator::next)
510 }
511}
512
513#[derive(Debug, Default)]
518pub struct EventArrayBuffer {
519 buffer: Option<EventArray>,
520 max_size: usize,
521}
522
523impl EventArrayBuffer {
524 fn new(max_size: Option<usize>) -> Self {
525 let max_size = max_size.unwrap_or(usize::MAX);
526 let buffer = None;
527 Self { buffer, max_size }
528 }
529
530 #[must_use]
531 fn push(&mut self, event: Event) -> Option<EventArray> {
532 match (event, &mut self.buffer) {
533 (Event::Log(event), Some(EventArray::Logs(array))) if array.len() < self.max_size => {
534 array.push(event);
535 None
536 }
537 (Event::Metric(event), Some(EventArray::Metrics(array)))
538 if array.len() < self.max_size =>
539 {
540 array.push(event);
541 None
542 }
543 (Event::Trace(event), Some(EventArray::Traces(array)))
544 if array.len() < self.max_size =>
545 {
546 array.push(event);
547 None
548 }
549 (event, current) => current.replace(EventArray::from(event)),
550 }
551 }
552
553 fn take(&mut self) -> Option<EventArray> {
554 self.buffer.take()
555 }
556}
557
558pub fn events_into_arrays(
561 events: impl IntoIterator<Item = Event>,
562 max_size: Option<usize>,
563) -> impl Iterator<Item = EventArray> {
564 IntoEventArraysIter {
565 inner: events.into_iter().fuse(),
566 current: EventArrayBuffer::new(max_size),
567 }
568}
569
570pub struct IntoEventArraysIter<I> {
572 inner: iter::Fuse<I>,
573 current: EventArrayBuffer,
574}
575
576impl<I: Iterator<Item = Event>> Iterator for IntoEventArraysIter<I> {
577 type Item = EventArray;
578 fn next(&mut self) -> Option<Self::Item> {
579 for event in self.inner.by_ref() {
580 if let Some(array) = self.current.push(event) {
581 return Some(array);
582 }
583 }
584 self.current.take()
585 }
586}