#ifndef LL_QUEUE_H #define LL_QUEUE_H #include #include #include "memory_pool.h" #ifdef _WIN32 #include #include #else #include #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