Files
utun2/lib/swm_min.c
T
evgeny 38c9f229bc stcp: ed25519 pubkey exchange in handshake, fix instance destroy segfault, fix chat_tcp_test
- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll
- stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close
- utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP),
  add deferred drain in both Phase J and L
- stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39,
  exchange ed25519_pubkey in both handshake directions
- etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in
  etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb
- chat_sync.c: fix lk->conn NULL dereference for TCP links
- test_stcp.c: update stcp_server_create/stcp_client_connect callsites
- tools/chat_tcp_test: change transport udp→tcp
2026-08-07 00:48:27 +03:00

100 lines
2.4 KiB
C

/* sliding_window_min.c */
#include "swm_min.h"
#include <stdlib.h>
#include <limits.h>
struct SlidingWindowMin {
int* data; /* кольцевой буфер значений */
int* deq; /* deque индексов (тоже кольцевой) */
int dq_head;
int dq_tail;
int deq_count;
int cur_pos;
int window_size;
};
SlidingWindowMin* swm_create(int window_size)
{
if (window_size <= 0) {
return NULL;
}
SlidingWindowMin* swm = (SlidingWindowMin*)malloc(sizeof(SlidingWindowMin));
if (!swm) {
return NULL;
}
swm->data = (int*)malloc((size_t)window_size * sizeof(int));
if (!swm->data) {
free(swm);
return NULL;
}
swm->deq = (int*)malloc((size_t)window_size * sizeof(int));
if (!swm->deq) {
free(swm->data);
free(swm);
return NULL;
}
swm->window_size = window_size;
swm->dq_head = 0;
swm->dq_tail = 0;
swm->deq_count = 0;
swm->cur_pos = 0;
return swm;
}
void swm_destroy(SlidingWindowMin* swm)
{
if (swm) {
free(swm->data);
free(swm->deq);
free(swm);
}
}
void swm_add(SlidingWindowMin* swm, int val)
{
if (!swm) return;
int idx = swm->cur_pos;
int w = swm->window_size;
/* записываем в кольцевой буфер */
swm->data[idx % w] = val;
/* 1. удаляем из начала deque индексы, которые уже вышли за окно */
while (swm->deq_count > 0 && swm->deq[swm->dq_head] <= idx - w) {
swm->dq_head = (swm->dq_head + 1) % w;
swm->deq_count--;
}
/* 2. удаляем из хвоста все элементы, которые хуже текущего */
while (swm->deq_count > 0) {
int last_idx = swm->deq[(swm->dq_tail - 1 + w) % w];
if (swm->data[last_idx % w] < val) {
break;
}
swm->dq_tail = (swm->dq_tail - 1 + w) % w;
swm->deq_count--;
}
/* 3. добавляем текущий индекс */
swm->deq[swm->dq_tail] = idx;
swm->dq_tail = (swm->dq_tail + 1) % w;
swm->deq_count++;
swm->cur_pos++;
}
int swm_get_min(const SlidingWindowMin* swm)
{
if (!swm || swm->deq_count == 0) {
return INT_MAX;
}
int min_idx = swm->deq[swm->dq_head];
return swm->data[min_idx % swm->window_size];
}