<commit_before>/*
 *  Libaxl:  Another XML library
 *  Copyright (C) 2013 Advanced Software Production Line, S.L.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free
 *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307 USA
 *  
 *  You may find a copy of the license under this software is released
 *  at COPYING file. This is LGPL software: you are welcome to
 *  develop proprietary applications using this library without any
 *  royalty or fee but returning back any change, improvement or
 *  addition in the form of source code, project image, documentation
 *  patches, etc. 
 *
 *  For commercial support on build XML enabled solutions contact us:
 *          
 *      Postal address:
 *         Advanced Software Production Line, S.L.
 *         Edificio Alius A, Oficina 102,
 *         C/ Antonio Suarez Nº 10,
 *         Alcalá de Henares 28802 Madrid
 *         Spain
 *
 *      Email address:
 *         <EMAIL> - http://www.aspl.es/xml
 */
#include <axl_hash.h>
#include <axl_factory.h>
#include <axl_log.h>

#define LOG_DOMAIN "axl-hash"

/**
 * \defgroup axl_hash_module Axl Hash: A hash table used by Axl Library
 */

/** 
 * \addtogroup axl_hash_module
 * @{
 */

typedef struct _axlHashNode axlHashNode;

struct _axlHashNode {
	/* the key stored and the destroy function */
	axlPointer        key;
	axlDestroyFunc    key_destroy;

	/* the data stored and the destroy function */
	axlPointer        data;
	axlDestroyFunc    data_destroy;

	/* a pointer to the next item */
	axlHashNode     * next;
};

struct _axlHash {
	/* the hash function */
	axlHashFunc  hash;
	axlEqualFunc equal;

	/* the hash table, implemented using chaining for collition
	 * resolution. */
	axlHashNode ** table;

	/* factory to allocate nodes */
	axlFactory   * factory;

	/* stored items in the hash */
	int items;

	/* the hash size */
	int hash_size;

	/* steps: how many slots are allocated when the hash is
	 * resized */
	int step;
};

/** 
 * @internal Implementation of the axl hash cursor.
 */
struct _axlHashCursor {
	/* a pointer to the hash */
	axlHash     * hash;

	/* a pointer to the node inside the hash (current value) */
	axlHashNode * node;

	/* the value if the index being accessed by the node
	 * pointed (current value) */
	int           index;
};

/** 
 * @brief Public hash implementation for keys that are strings.
 * 
 * @param _key The string key to hash.
 * 
 * @return A value associated to the key.
 */
unsigned int axl_hash_string (axlPointer _key)
{
	/* never is received a NULL value at this function, so, don't
	 * check it */
	int    g, h = 0;
	char * key  = _key;

	if (_key == NULL)
		return 0;

	/* hashing taken from the Red Dragon book!! */
	while (*key) {
		h = (h << 4) + *key;
		if ((g = h & 0xF0000000) != 0) {
			h ^= g >> 24;
			h ^= g;
		}
		
		++ key;
	} /* end while */

	/* return the value */
	return h;
}

/** 
 * @brief Common equal hash function associated to \ref
 * axl_hash_string that allows to check two keys to be equal,
 * conforming to the results expected by the hash (\ref axlHash).
 * 
 * @param keya The key to compare.
 *
 * @param keyb The other key to compare.
 * 
 * @return 0 if both strings are equal and any other else value when
 * they differs.
 */
int             axl_hash_equal_string (axlPointer keya, 
				       axlPointer keyb)
{
	char * _keya = keya;
	char * _keyb = keyb;
	int    i     = 0;

	while (_keya [i] != 0 && _keyb [i] != 0) {

		/* check values */
		if (_keya [i] != _keyb [i])
			return 1;

		/* update the iterator */
		i++;
	} /* end while */

	/* check that both string ends at the same point */
	if (_keya [i] != 0 || _keyb [i] != 0)
		return 1;
	
	/* both keys are equal */
	return 0;
}

/** 
 * @brief Convenience hashing function to store keys that are
 * integers.
 * 
 * @param key The key that is supported to contain a int value stored<commit_msg>libaxl: * [fix] Added some additional checks inside axl_hash_string to clarify   NULL key handling.<commit_after>/*
 *  Libaxl:  Another XML library
 *  Copyright (C) 2013 Advanced Software Production Line, S.L.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free
 *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307 USA
 *  
 *  You may find a copy of the license under this software is released
 *  at COPYING file. This is LGPL software: you are welcome to
 *  develop proprietary applications using this library without any
 *  royalty or fee but returning back any change, improvement or
 *  addition in the form of source code, project image, documentation
 *  patches, etc. 
 *
 *  For commercial support on build XML enabled solutions contact us:
 *          
 *      Postal address:
 *         Advanced Software Production Line, S.L.
 *         <NAME>, Oficina 102,
 *         C/ <NAME> Nº 10,
 *         Alcalá de Henares 28802 Madrid
 *         Spain
 *
 *      Email address:
 *         <EMAIL> - http://www.aspl.es/xml
 */
#include <axl_hash.h>
#include <axl_factory.h>
#include <axl_log.h>

#define LOG_DOMAIN "axl-hash"

/**
 * \defgroup axl_hash_module Axl Hash: A hash table used by Axl Library
 */

/** 
 * \addtogroup axl_hash_module
 * @{
 */

typedef struct _axlHashNode axlHashNode;

struct _axlHashNode {
	/* the key stored and the destroy function */
	axlPointer        key;
	axlDestroyFunc    key_destroy;

	/* the data stored and the destroy function */
	axlPointer        data;
	axlDestroyFunc    data_destroy;

	/* a pointer to the next item */
	axlHashNode     * next;
};

struct _axlHash {
	/* the hash function */
	axlHashFunc  hash;
	axlEqualFunc equal;

	/* the hash table, implemented using chaining for collition
	 * resolution. */
	axlHashNode ** table;

	/* factory to allocate nodes */
	axlFactory   * factory;

	/* stored items in the hash */
	int items;

	/* the hash size */
	int hash_size;

	/* steps: how many slots are allocated when the hash is
	 * resized */
	int step;
};

/** 
 * @internal Implementation of the axl hash cursor.
 */
struct _axlHashCursor {
	/* a pointer to the hash */
	axlHash     * hash;

	/* a pointer to the node inside the hash (current value) */
	axlHashNode * node;

	/* the value if the index being accessed by the node
	 * pointed (current value) */
	int           index;
};

/** 
 * @brief Public hash implementation for keys that are strings.
 * 
 * @param _key The string key to hash.
 * 
 * @return A value associated to the key.
 */
unsigned int axl_hash_string (axlPointer _key)
{
	/* never is received a NULL value at this function, so, don't
	 * check it */
	int    g, h = 0;
	char * key  = _key;

	if (_key == NULL)
		return 0;

	/* hashing taken from the Red Dragon book!! */
	while (*key) {
		h = (h << 4) + *key;
		if ((g = h & 0xF0000000) != 0) {
			h ^= g >> 24;
			h ^= g;
		}
		
		++ key;
	} /* end while */

	/* return the value */
	return h;
}

/** 
 * @brief Common equal hash function associated to \ref
 * axl_hash_string that allows to check two keys to be equal,
 * conforming to the results expected by the hash (\ref axlHash).
 * 
 * @param keya The key to compare.
 *
 * @param keyb The other key to compare.
 * 
 * @return 0 if both strings are equal and any other else value when
 * they differs.
 */
int             axl_hash_equal_string (axlPointer keya, 
				       axlPointer keyb)
{
	char * _keya = keya;
	char * _keyb = keyb;
	int    i     = 0;

	if (keya == NULL)
		return (keyb == NULL);
	if (keyb == NULL)
		return (keya == NULL);

	while (_keya [i] != 0 && _keyb [i] != 0) {

		/* check values */
		if (_keya [i] != _keyb [i])
			return 1;

		/* update the iterator */
		i++;
	} /* end while */

	/* check that both string ends at the same point */
	if (_keya [i] != 0 || _keyb [i] != 0)
		return 1;
	
	/* both keys are equal */
	return 0;
}

/** 
 * @brief Convenience hashing function to store keys that are
 * integers.
 * 
 * @param key The key that is supported to contain a int value stored
{'fraction_non_alphanumeric': 0.09605507594798382, 'fraction_numerical': 0.011583433504535024, 'mean_word_length': 2.7097689501418727, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3774830', 'n_tokens_mistral': 3047, 'n_tokens_neox': 2824, 'n_words': 1212}