summaryrefslogtreecommitdiffstats
path: root/src/fluent-bit/plugins/filter_throttle_size/size_window.h
blob: be661d6ec1a465877e3079013224c865bdd93a76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*  Fluent Bit
 *  ==========
 *  Copyright (C) 2015-2022 The Fluent Bit Authors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#ifndef FLB_SIZE_WINDOW_H
#define FLB_SIZE_WINDOW_H

#include <fluent-bit/flb_hash_table.h>

#define FLB_SIZE_WINDOW_HASH_MAX_ENTRIES 100000

struct throttle_size_pane
{
    long timestamp;
    unsigned long size;
};

struct throttle_size_window
{
    char *name;
    unsigned size;
    unsigned long total;
    long timestamp;
    int head;
    int tail;
    struct throttle_size_pane *table;
};

struct throttle_size_table
{
    struct flb_hash_table *windows;
    void *lock;
};

struct throttle_size_table *create_throttle_size_table();

struct throttle_size_window *size_window_create(const char *name,
                                                unsigned name_length,
                                                unsigned int size);

/*This function adds new pane on top of the pane stack by overwriting the oldes one
  which @timestamp and load size of 0 bytes. The oldes pane's amount of load size
  is subtracted of the total amount.*/
inline static void add_new_pane(struct throttle_size_window *stw,
                                long timestamp)
{
    unsigned long tail_size = 0;
    tail_size = stw->table[stw->tail].size;
    if (stw->size - 1 == stw->head) {
        /* the head will exceed the end of the inner array end must be put at the begging.  */
        stw->head = -1;
    }
    stw->head += 1;
    stw->table[stw->head].timestamp = timestamp;
    stw->table[stw->head].size = 0;
    stw->total -= tail_size;
    if (stw->size - 1 == stw->tail) {
        /* the tail will exceed the end of the inner array end must be put at the begging. */
        stw->tail = -1;
    }
    stw->tail += 1;
}

/*This function adds @load to the latest pane which is on top of the pane stack.
  @load is added to the total amount of the size throttling window.
  If @load is not 0 then the size throttling window's timestamp will be updated to the
  one which is on top of the pane stack(latest)*/
inline static void add_load(struct throttle_size_window *stw,
                            unsigned long load)
{
    stw->table[stw->head].size += load;
    stw->total += load;
    if (load) {
        stw->timestamp = stw->table[stw->head].timestamp;
    }
}

inline static void free_stw_content(struct throttle_size_window *stw)
{
    flb_free(stw->name);
    flb_free(stw->table);
}

inline static void free_stw(struct throttle_size_window *stw)
{
    free_stw_content(stw);
    flb_free(stw);
}

inline static struct throttle_size_window *find_throttle_size_window(struct
                                                                     throttle_size_table
                                                                     *table,
                                                                     char
                                                                     *name,
                                                                     unsigned
                                                                     name_length)
{
    char *window = NULL;
    size_t out_size;
    if (flb_hash_table_get(table->windows, name, name_length,
                           (const char **)&window, &out_size) >= 0) {
        if (out_size < sizeof(struct throttle_size_window)) {
            flb_error("Malformed data in size window hashtable");
            return NULL;
        }
        return (struct throttle_size_window *) window;
    }
    return NULL;
}

inline static void add_throttle_size_window(struct throttle_size_table
                                            *table,
                                            struct throttle_size_window
                                            *window)
{
    flb_hash_table_add(table->windows, window->name, strlen(window->name),
                       (char *) window, sizeof(struct throttle_size_window));
}

void destroy_throttle_size_table(struct throttle_size_table *table);

void lock_throttle_size_table(struct throttle_size_table *ht);
void unlock_throttle_size_table(struct throttle_size_table *ht);

#endif