/*
   File:        skid.h
   Authors:     Andrew W. Moore
   Created:     Wed Apr 17 16:09:44 EDT 2002
   Description: Header for Sparse Kd Array

   Copyright 2002, Andrew W. Moore
*/


#ifndef SKID_H
#define SKID_H

#include "amdmex.h"
#include "genarray.h"
#include "hash.h"

typedef struct skelt
{
  ivec *indexes;
  int count;
} skelt;

typedef struct skelts
{
  generic_array *genarr;
} skelts;

typedef struct skid
{
  int num_dims;
  int num_elements;
  int num_buckets;
  skelts **buckets;
} skid;

/* A skid maps k-tuples of integers to counts.

   For example, if k=3, you could have a skid containing this
   information:

    (1,3,4) --> 7
    (1,6,7) --> 4
    (2,3,9) --> 8
    (8,9,11) --> 1

   A k-tuple of integers is called an "indexes" vector, and is
   implemented by an ivec of size k.

   In the code below, k is called "num_dims"

   Any k-tuple not stored in the skid is assumed to have a count of zero.

   The implementation is by a fast hash table.
*/

/* num_dims = k in the description above */
skid *mk_empty_skid(int num_dims);

void free_skid(skid *x);

void fprintf_skid(FILE *s,char *m1,skid *x,char *m2);

skid *mk_copy_skid(skid *old);

/* This is the hash-table lookup.

   We insist that ivec_size(indexes) == the "num_dims" that the skid was 
   build with. */
int skid_indexes_to_count(skid *ski,ivec *indexes);

/* Writes the count that is to be associated with the given indexes

   We insist that ivec_size(indexes) == the "num_dims" that the skid was 
   build with. */
void skid_set(skid *ski,ivec *indexes,int count);

/* Increments the count by 1 efficiently (more efficiently than
   via a call the skid_indexes_to_count followed by skid_set */
void skid_increment(skid *ski,ivec *indexes);

/* As above only decrements */
void skid_decrement(skid *ski,ivec *indexes);

/* The following can be used to iterate over all members
   of all buckets in the skid... */

/* Ask Andrew if you're curious about these */
int skid_num_buckets(skid *sk);
int skid_bucket_to_num_members(skid *sk,int bucket);
ivec *skid_bucket_member_to_indexes(skid *sk,int bucket,int member);
int skid_bucket_member_to_count(skid *sk,int bucket,int member);

#endif /* #ifndef SKID_H */
