Logo Search packages:      
Sourcecode: haproxy version File versions  Download package

sessionhash.c

/*
 * HashTable functions.
 *
 * Copyright 2007 Arnaud Cornet
 *
 * This file is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License, version 2.1 as published by the Free Software Foundation.
 *
 */

/*
 * quick and dirty AppSession hash table, using sessid as key
 */

#include <common/sessionhash.h>
#include <string.h>
#ifdef TEST
#include <stdio.h>
#endif

/*
 * This is a bernstein hash derivate
 * returns unsigned int between 0 and (TABLESIZE - 1) inclusive
 */
unsigned int appsession_hash_f(char *ptr)
{
      unsigned int h = 5381;

      while (*ptr) {
            h = (h << 5) + h + *ptr;
            ptr++;
      }
      return ((h >> 16) ^ h) & TABLEMASK;
}

int appsession_hash_init(struct appsession_hash *hash,
            void(*destroy)(appsess*))
{
      int i;

      hash->destroy = destroy;
      hash->table = malloc(TABLESIZE * sizeof(struct list));
      if (hash->table == NULL)
            return 0;
      for (i = 0; i < TABLESIZE; i++)
            LIST_INIT(&hash->table[i]);
      return 1;
}

void appsession_hash_insert(struct appsession_hash *hash, appsess *session)
{
      unsigned int idx;

      idx = appsession_hash_f(session->sessid);
      LIST_ADDQ(&hash->table[idx], &session->hash_list);
}

appsess *appsession_hash_lookup(struct appsession_hash *hash, char *sessid)
{
      unsigned int idx;
      appsess *item;

      idx = appsession_hash_f(sessid);

      list_for_each_entry(item, &hash->table[idx], hash_list) {
            if (strcmp(item->sessid, sessid) == 0)
                  return item;
      }
      return NULL;
}

void appsession_hash_remove(struct appsession_hash *hash, appsess *session)
{
      unsigned int idx;
      appsess *item;

      idx = appsession_hash_f(session->sessid);

      /* we don't even need to call _safe because we return at once */
      list_for_each_entry(item, &hash->table[idx], hash_list) {
            if (strcmp(item->sessid, session->sessid) == 0) {
                  LIST_DEL(&item->hash_list);
                  hash->destroy(item);
                  return;
            }
      }
}

void appsession_hash_destroy(struct appsession_hash *hash)
{
      unsigned int i;
      appsess *item;

      for (i = 0; i < TABLESIZE; i++) {
            while (!LIST_ISEMPTY(&hash->table[i])) {
                  item = LIST_ELEM(hash->table[i].n, appsess *,
                              hash_list);
                  hash->destroy(item);
                  LIST_DEL(&item->hash_list);
            }
      }
      free(hash->table);
      hash->table = NULL;
      hash->destroy = NULL;
}

#if defined(DEBUG_HASH)
void appsession_hash_dump(struct appsession_hash *hash)
{
      unsigned int idx;
      appsess *sess_head, *item;

      printf("Dumping hashtable 0x%x\n", hash);
      for (idx = 0; idx < TABLESIZE; idx++) {
            /* we don't even need to call _safe because we return at once */
            list_for_each_entry(item, &hash->table[idx], hash_list) {
                  printf("\ttable[%d]:\t%s\t-> 0x%x\n", idx, item->sessid,
                              item);
            }
      }
      printf(".\n");
}
#endif

Generated by  Doxygen 1.6.0   Back to index