You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.7 KiB
130 lines
4.7 KiB
#ifndef LL_QUEUE_H |
|
#define LL_QUEUE_H |
|
#include <stddef.h> |
|
#include <stdint.h> |
|
#include "memory_pool.h" |
|
#ifdef _WIN32 |
|
#include <winsock2.h> |
|
#include <windows.h> |
|
#else |
|
#include <pthread.h> |
|
#endif |
|
|
|
#define QUEUE_DEBUG 1 |
|
//#define QUEUE_THREAD_CHECK 1 |
|
|
|
// Forward declaration |
|
struct ll_queue; |
|
|
|
/** |
|
* @struct ll_entry |
|
* @brief Элемент очереди (переменного размера). |
|
* |
|
* Память: [struct ll_entry + data[size]]. |
|
* Индекс для поиска (произвольной длины) хранится в data[index_offset]. |
|
* Хеш (uint64_t) вычисляется по последним 8 байтам индекса. |
|
*/ |
|
struct ll_entry { |
|
char* name; |
|
struct ll_entry* next; |
|
struct ll_entry* prev; |
|
uint16_t size; ///< Размер data[] |
|
uint16_t len; |
|
uint16_t memlen; |
|
uint16_t int_len; |
|
uint8_t* dgram; |
|
void (*dgram_free_fn)(uint8_t* data); |
|
struct memory_pool* dgram_pool; |
|
struct memory_pool* pool; |
|
|
|
/* === НОВОЕ: поддержка индекса произвольной длины === */ |
|
uint16_t index_offset; ///< Смещение индекса в data[] |
|
uint16_t index_size; ///< Длина индекса (0 = без индекса) |
|
uint64_t index_hash; ///< Хеш по последним 8 байтам индекса |
|
|
|
struct ll_entry* hash_next; |
|
uint8_t data[0]; ///< Гибкий массив |
|
}; |
|
|
|
/* ... (остальные typedef'ы без изменений) ... */ |
|
|
|
struct ll_queue { |
|
char* name; |
|
struct ll_entry* head; |
|
struct ll_entry* tail; |
|
int count; |
|
size_t total_bytes; |
|
int size_limit; |
|
queue_callback_fn callback; |
|
void* callback_arg; |
|
int callback_suspended; |
|
void* resume_timeout_id; |
|
struct UASYNC* ua; |
|
struct queue_waiter waiter; |
|
struct ll_entry** hash_table; |
|
size_t hash_size; |
|
#ifdef QUEUE_THREAD_CHECK |
|
#ifdef _WIN32 |
|
DWORD owner_thread; |
|
#else |
|
pthread_t owner_thread; |
|
#endif |
|
#endif |
|
}; |
|
|
|
/* ==================== Создание / уничтожение ==================== */ |
|
struct ll_queue* queue_new(struct UASYNC* ua, size_t hash_size, char* name); |
|
void queue_free(struct ll_queue* q); |
|
|
|
/* ==================== Конфигурация ==================== */ |
|
void queue_set_size_limit(struct ll_queue* q, int lim); |
|
|
|
/* ==================== Автозабор элементов ==================== */ |
|
void queue_set_callback(struct ll_queue* q, queue_callback_fn cbk_fn, void* arg); |
|
void queue_resume_callback(struct ll_queue* q); |
|
|
|
/* ==================== Пороговое ожидание ==================== */ |
|
struct queue_waiter* queue_wait_threshold(struct ll_queue* q, int max_packets, size_t max_bytes, |
|
queue_threshold_callback_fn callback, void* arg); |
|
void queue_cancel_wait(struct ll_queue* q, struct queue_waiter* waiter); |
|
|
|
/* ==================== Работа с данными ==================== */ |
|
/* Упрощённая версия (без индекса) */ |
|
int queue_data_put(struct ll_queue* q, struct ll_entry* entry); |
|
int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry); |
|
|
|
/* Версия с хешем по индексу произвольной длины */ |
|
int queue_data_put_with_index(struct ll_queue* q, struct ll_entry* entry, |
|
uint16_t index_offset, uint16_t index_size); |
|
int queue_data_put_first_with_index(struct ll_queue* q, struct ll_entry* entry, |
|
uint16_t index_offset, uint16_t index_size); |
|
|
|
struct ll_entry* queue_data_get(struct ll_queue* q); |
|
int queue_entry_count(struct ll_queue* q); |
|
|
|
/* ==================== Управление памятью ==================== */ |
|
struct ll_entry* ll_alloc_lldgram(uint16_t len); |
|
struct ll_entry* queue_entry_new(size_t data_size); |
|
struct ll_entry* queue_entry_new_from_pool(struct memory_pool* pool); |
|
void queue_entry_free(struct ll_entry* entry); |
|
void queue_dgram_free(struct ll_entry* entry); |
|
|
|
/* ==================== Поиск и удаление ==================== */ |
|
/** |
|
* @brief Поиск по индексу произвольной длины. |
|
* @note Хеш вычисляется по последним 8 байтам индекса. |
|
*/ |
|
struct ll_entry* queue_find_data_by_index(struct ll_queue* q, |
|
const void* index_key, |
|
uint16_t index_size); |
|
|
|
int queue_remove_data(struct ll_queue* q, struct ll_entry* entry); |
|
|
|
/* ==================== Утилиты ==================== */ |
|
static inline size_t queue_total_bytes(struct ll_queue* q) { |
|
return q ? q->total_bytes : 0; |
|
} |
|
|
|
int queue_check_consistency(struct ll_queue* q); |
|
|
|
#endif // LL_QUEUE_H
|
|
|