/**
 * Sparse array. Basically, a collection of elements where each element is
 * univocally identified by an index. Indeces can be positive and negative.
 * Each entry of the sparse array holds a pointer to some client data.
 * 
 * @file
 * @author Umberto Salsi <salsi@icosaedro.it>
 * @version $Date: 2017/08/04 10:21:54 $
 */

#ifndef SPARSEARRAY_H
#define SPARSEARRAY_H

#ifdef sparsearray_IMPORT
	#define EXTERN
#else
	#define EXTERN extern
#endif

/**
 * Sparse array type.
 */
typedef struct sparsearray_Type sparsearray_Type;

/**
 * Allocates a new, empty sparse array.
 * @param size Expected or estimated total number of elements that will be stored.
 * @param keep_elements If the elements must not be released.
 * @return 
 */
EXTERN sparsearray_Type * sparsearray_new(int size, int keep_elements);

/**
 * Set and entry in the sparse array. Replaces the existing entry, if any; the
 * existing entry is released depending on the 'keep elements' flag set while
 * creating this sparse array.
 * @param sa Involved sparse array.
 * @param index Index of the entry to set.
 * @param entry Entry to set.
 */
EXTERN void sparsearray_set(sparsearray_Type *sa, int index, void *entry);

/**
 * Retrieves the entry at the given index.
 * @param sa Involved sparse array.
 * @param index Index of the entry to retrieve.
 * @return Retrieved user element or NULL if not found.
 */
EXTERN void * sparsearray_get(sparsearray_Type * sa, int index);

/**
 * Returns the current average comparisons to be performed to fetch an entry,
 * assuming each index has the same probability. Values greater than 2.0 indicate
 * sub-optimal performances.
 * @param sa
 * @return 
 */
EXTERN double sparsearray_getAverageComparisonsPerSearch(sparsearray_Type *sa);

/**
 * Writes to stdout a detailed report about the internals (for debugging only).
 * @param sa
 * @param title
 */
EXTERN void sparsearray_report(sparsearray_Type *sa, char * title);

#undef EXTERN
#endif
