hlswmaster/gamelist.c

86 lines
1.8 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "gamelist.h"
#include "logging.h"
#define BUCKET_NUM 127
static struct list_head *bucket;
static unsigned int hash_entry(struct game_entry *entry)
{
unsigned int hash = 0x12345678;
hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->ip >> 0) & 0xFF);
hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->ip >> 8) & 0xFF);
hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->ip >> 16) & 0xFF);
hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->ip >> 24) & 0xFF);
hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->port1 >> 0) & 0xFF);
hash = ((hash << 5) ^ (hash >> 27)) ^ ((entry->port1 >> 8) & 0xFF);
return hash % BUCKET_NUM;
}
static int compare_entry(struct game_entry *a, struct game_entry *b)
{
return (a->gameid == b->gameid && a->ip == b->ip &&
a->port1 == b->port1 && a->port2 == b->port2);
}
int gamelist_add(struct game_entry *entry)
{
unsigned int hash = hash_entry(entry);
struct game_entry *search;
list_for_each_entry(search, &bucket[hash], list) {
if (compare_entry(search, entry)) {
search->modtime = time(NULL);
return 0;
}
}
entry->modtime = time(NULL);
list_add_tail(&entry->list, &bucket[hash]);
return 0;
}
int gamelist_gc_and_dump(int (*callback)(struct game_entry *entry), int timeout)
{
long now = time(NULL);
int i;
for (i = 0; i < BUCKET_NUM; i++) {
struct game_entry *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &bucket[i], list) {
if (entry->modtime + timeout >= now) {
callback(entry);
} else {
list_del(&entry->list);
free(entry);
}
}
}
return 0;
}
int gamelist_init()
{
bucket = malloc(sizeof(struct list_head) * BUCKET_NUM);
if (bucket == NULL) {
log_print(LOG_ERROR, "scan_init(): out of memory");
return -1;
}
int i;
for (i = 0; i < BUCKET_NUM; i++)
INIT_LIST_HEAD(&bucket[i]);
return 0;
}