예제 #1
0
int phg_map_GIDs_to_processes(ZZ *zz, ZOLTAN_ID_PTR eid, int size, 
                             int lenGID, int **hashedProc, int nprocs)
{
int i, j;
int *procList;
static char *yo = "map_GIDs_to_processes";

  *hashedProc = NULL;

  if (size < 1){
    return ZOLTAN_OK;
  }

  procList = (int *)ZOLTAN_MALLOC(sizeof(int) * size);

  if (!procList){
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error."); 
    return ZOLTAN_MEMERR;
  }

  for (i=0; i<size; i++){
    j = Zoltan_Hash(eid, lenGID, nprocs);
    procList[i] = j;
    eid += lenGID;
  }

  *hashedProc = procList;

  return ZOLTAN_OK;
}
예제 #2
0
int Zoltan_G2LHash_Insert(G2LHash *hash, ZOLTAN_GNO_TYPE gno)
{
    int i, lno;
    G2LHashNode *ptr;

    if (gno<hash->base || gno>hash->baseend) {
        i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&gno, hash->num_gid_entries, (unsigned int) hash->maxsize);
        for (ptr=hash->table[i]; ptr && ptr->gno!=gno; ptr = ptr->next);
        if (!ptr) {
            if (hash->size >= hash->maxsize) {
                char st[2048];
                sprintf(st, "Hash is full! #entries=%d  maxsize=%d", hash->size, hash->maxsize);
                ZOLTAN_PRINT_ERROR(-1, "Zoltan_G2LHash_G2L", st);
                return -1;
            }
            ptr = &(hash->nodes[hash->size]);
            ptr->gno = gno;
            lno = ptr->lno = hash->nlvtx + hash->size;
            ptr->next = hash->table[i];
            hash->table[i] = ptr;
            ++hash->size;
        } else
            lno = ptr->lno;
    } else
        return gno-hash->base;

    return lno;
}
예제 #3
0
void remove_from_hash(
    int globalID
)
{
    int idx, hidx, prev;

    ZOLTAN_ID_TYPE tmp;
    tmp = globalID;
    hidx = Zoltan_Hash(&tmp, 1, New_Elem_Index_Size);
    idx = New_Elem_Hash_Table[hidx];
    prev = -1;
    while (idx != -1 && New_Elem_Hash_Nodes[idx].globalID != globalID) {
        prev = idx;
        idx = New_Elem_Hash_Nodes[idx].next;
    }

    if (prev == -1)
        New_Elem_Hash_Table[hidx] = New_Elem_Hash_Nodes[idx].next;
    else
        New_Elem_Hash_Nodes[prev].next = New_Elem_Hash_Nodes[idx].next;

    New_Elem_Hash_Nodes[idx].globalID = -1;
    New_Elem_Hash_Nodes[idx].localID = -1;
    New_Elem_Hash_Nodes[idx].next = -1;
}
예제 #4
0
int Zoltan_Map_Find(ZZ *zz, ZOLTAN_MAP* map, int *key, int *data)
{
  char *yo = "Zoltan_Map_Find";
  int index, match;
  ZOLTAN_ENTRY *element;
  ZOLTAN_ID_PTR zkey = (ZOLTAN_ID_PTR)key;

  *data = ZOLTAN_NOT_FOUND;

  if (!map){
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Map specified does not exist\n");
    return ZOLTAN_FATAL;
  }

  index = Zoltan_Hash(zkey, map->id_size, map->max_index);

  element = map->entries[index];
  match = 0;

  while (element != NULL){
    match = key_match(map->id_size, element->key, key);
    if (match){
      *data = element->data;
      break;
    }
    element = element->next;
  }
  return ZOLTAN_OK;
}
예제 #5
0
void Zoltan_Reftree_Hash_Remove (ZZ *zz, ZOLTAN_REFTREE *reftree_node,
                             struct Zoltan_Reftree_hash_node **hashtab, int n)
{
  int i;
  struct Zoltan_Reftree_hash_node *ptr, *prev, *next;

  i = Zoltan_Hash(reftree_node->global_id, zz->Num_GID, (unsigned int)n);
  ptr = hashtab[i];
  prev = NULL;
  while (ptr != NULL) {
    if (ZOLTAN_EQ_GID(zz, ptr->gid, reftree_node->global_id)) {
      next = ptr->next;
      ZOLTAN_FREE(&(ptr->gid));
      ZOLTAN_FREE(&ptr);
      if (prev == NULL) {
        hashtab[i] = next;
      } else {
        prev->next = next;
      }
      ptr = NULL;
    } else {
      prev = ptr;
      ptr = ptr->next;
    }
  }
}
예제 #6
0
int Zoltan_KVHash_Insert(KVHash *hash, ZOLTAN_GNO_TYPE key, int value)
{
    int i;
    
    G2LHashNode *ptr;

    i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&key, hash->num_gid_entries, (unsigned int) hash->maxsize);
    for (ptr=hash->table[i]; ptr && ptr->gno!=key; ptr = ptr->next);
    if (!ptr) {
        if (hash->size >= hash->maxsize) {
            ZOLTAN_PRINT_ERROR(-1, "Zoltan_KVHash_Insert", "Hash is full!");
            return -1;
        }
        
        ptr = &(hash->nodes[hash->size]);
        ptr->gno = key;
        ptr->lno = value;
        ptr->next = hash->table[i];
        hash->table[i] = ptr;
        ++hash->size;
    } else
        value = ptr->lno;

    return value;   
}
예제 #7
0
phg_GID_lookup *phg_create_GID_lookup_table2(ZOLTAN_ID_PTR gids, int ngids, int lenGID)
{
  int i, j, k, tsize, found;
  struct Hash_Node *hn;
  ZOLTAN_ID_PTR nextGID, nextUniqueGID;
  phg_GID_lookup *lu = NULL;

  tsize = ngids;    /* actually may be larger than number of unique ids */
  
  nextGID = nextUniqueGID = gids;

  lu = (phg_GID_lookup *)ZOLTAN_MALLOC(sizeof(phg_GID_lookup));
  if (!lu){
    return NULL;
  }

  lu->ht = (struct Hash_Node **)ZOLTAN_CALLOC(sizeof(struct Hash_Node*) , tsize);
  hn = lu->htTop = (struct Hash_Node *)ZOLTAN_MALLOC(sizeof(struct Hash_Node) * ngids);

  if (tsize && (!lu->htTop || !lu->ht)){
    ZOLTAN_FREE(&lu);
    ZOLTAN_FREE(&lu->htTop);
    ZOLTAN_FREE(&lu->ht);
    return NULL;
  }

  lu->lenGID = lenGID;
  lu->table_size = tsize;
  lu->numGIDs = 0;

  for (i=0; i<ngids; i++, nextGID += lenGID){

    found = phg_lookup_GID(lu, nextGID);

    if (found >= 0) continue;

    hn->gid = nextUniqueGID;
    hn->gno = lu->numGIDs;

    if (nextUniqueGID < nextGID){
      for (k=0; k<lenGID; k++){
        nextUniqueGID[k] = nextGID[k]; 
      }
    }

    j = Zoltan_Hash(nextGID, lenGID, tsize);

    hn->next = lu->ht[j];
    lu->ht[j] = hn;
   
    hn++;
    nextUniqueGID += lenGID;
    lu->numGIDs++;
  }

  return lu;
}
예제 #8
0
int Zoltan_KVHash_GetValue(KVHash *hash, ZOLTAN_GNO_TYPE key)    
{
    int i;
    G2LHashNode *ptr;

    i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *) &key, hash->num_gid_entries, (unsigned int) hash->maxsize);
    for (ptr=hash->table[i]; ptr && ptr->gno!=key; ptr = ptr->next);
    if (!ptr)
        return -1;
    else
        return ptr->lno;
}
예제 #9
0
void insert_in_hash(
    int globalID,
    int localID
)
{
    int j;
    New_Elem_Hash_Nodes[localID].globalID = globalID;
    New_Elem_Hash_Nodes[localID].localID = localID;
    j = Zoltan_Hash((ZOLTAN_ID_PTR) &globalID,1,New_Elem_Index_Size);
    New_Elem_Hash_Nodes[localID].next = New_Elem_Hash_Table[j];
    New_Elem_Hash_Table[j] = localID;
}
예제 #10
0
int find_in_hash(
    ZOLTAN_ID_TYPE globalID
)
{
    int idx;

    idx = Zoltan_Hash(&globalID, 1, New_Elem_Index_Size);
    idx = New_Elem_Hash_Table[idx];
    while (idx != -1 && New_Elem_Hash_Nodes[idx].globalID != globalID) {
        idx = New_Elem_Hash_Nodes[idx].next;
    }

    return idx;
}
예제 #11
0
int Zoltan_G2LHash_G2L(G2LHash *hash, ZOLTAN_GNO_TYPE gno)
{
    int i;
    G2LHashNode *ptr;

    if (gno<hash->base || gno>hash->baseend) {
        i = Zoltan_Hash((ZOLTAN_ID_PTR) (void *)&gno, hash->num_gid_entries, (unsigned int) hash->maxsize);
        for (ptr=hash->table[i]; ptr && ptr->gno!=gno; ptr = ptr->next);
        if (!ptr)
            return -1;
        else
            return ptr->lno;
    } else
        return gno-hash->base;
}
예제 #12
0
int Zoltan_Reftree_inthash_lookup (ZZ *zz, 
                                   struct Zoltan_Reftree_inthash_node **hashtab,
                                   ZOLTAN_ID_PTR key, int n)
{
  int i;
  struct Zoltan_Reftree_inthash_node *ptr;

  i = Zoltan_Hash(key, zz->Num_GID, (unsigned int)n);
  for (ptr=hashtab[i]; ptr != NULL; ptr = ptr->next){
    if (ZOLTAN_EQ_GID(zz, ptr->gid, key))
      return (ptr->lid);
  }
  /* Key not in hash table */
  return -1;
}
예제 #13
0
void Zoltan_Reftree_Hash_Insert(ZZ *zz, ZOLTAN_REFTREE *reftree_node,
                            struct Zoltan_Reftree_hash_node **hashtab, int size)
{
int i;
struct Zoltan_Reftree_hash_node *new_entry;

  i = Zoltan_Hash(reftree_node->global_id, zz->Num_GID, (unsigned int)size);

  new_entry = (struct Zoltan_Reftree_hash_node *)
              ZOLTAN_MALLOC(sizeof(struct Zoltan_Reftree_hash_node));
  new_entry->gid = ZOLTAN_MALLOC_GID(zz);
  ZOLTAN_SET_GID(zz, new_entry->gid,reftree_node->global_id);
  new_entry->reftree_node = reftree_node;
  new_entry->next = hashtab[i];
  hashtab[i] = new_entry;
}
예제 #14
0
void Zoltan_Reftree_IntHash_Insert(ZZ *zz, ZOLTAN_ID_PTR gid, int lid,
                                   struct Zoltan_Reftree_inthash_node **hashtab,
                                   int size)
{
int i;
struct Zoltan_Reftree_inthash_node *new_entry;

  i = Zoltan_Hash(gid, zz->Num_GID, (unsigned int)size);

  new_entry = (struct Zoltan_Reftree_inthash_node *)
              ZOLTAN_MALLOC(sizeof(struct Zoltan_Reftree_inthash_node));
  new_entry->gid = ZOLTAN_MALLOC_GID(zz);
  ZOLTAN_SET_GID(zz, new_entry->gid,gid);
  new_entry->lid = lid;
  new_entry->next = hashtab[i];
  hashtab[i] = new_entry;
}
예제 #15
0
static int search_hash_table(ZZ *zz, ZOLTAN_ID_PTR gid,
                         struct Hash_Node **ht, int tableSize)
{
int j, found;
struct Hash_Node *hn;

  found = -1;

  j = Zoltan_Hash(gid, zz->Num_GID, tableSize);
 
  hn = ht[j];

  while (hn){

    if (ZOLTAN_EQ_GID(zz, gid, hn->gid)){
      found = hn->gno;
      break;
    }
    hn = hn->next;
  }
  return found; 
}
예제 #16
0
phg_GID_lookup *phg_create_GID_lookup_table(ZOLTAN_ID_PTR gids, int size, int lenGID)
{
  int i, j, tsize;
  phg_GID_lookup *lu = NULL;

  lu = (phg_GID_lookup *)ZOLTAN_MALLOC(sizeof(phg_GID_lookup));
  if (!lu){
    return NULL;
  }

  tsize = size * 1.25;

  lu->htTop = (struct Hash_Node *)ZOLTAN_MALLOC(sizeof(struct Hash_Node)*size);
  lu->ht = (struct Hash_Node **)ZOLTAN_CALLOC(sizeof(struct Hash_Node*), tsize);

  if (tsize && (!lu->htTop || !lu->ht)){
    ZOLTAN_FREE(&lu->htTop);
    ZOLTAN_FREE(&lu->ht);
    ZOLTAN_FREE(&lu);
    return NULL;
  }

  lu->table_size = tsize;
  lu->numGIDs = size;
  lu->lenGID = lenGID;

  for (i=0; i<size; i++){
    lu->htTop[i].gid = gids + (i * lenGID);
    lu->htTop[i].gno = i;

    j = Zoltan_Hash(lu->htTop[i].gid, lenGID, tsize);
    
    lu->htTop[i].next = lu->ht[j];
    lu->ht[j] = lu->htTop + i;
  }
 
  return lu;
}
예제 #17
0
int phg_lookup_GID(phg_GID_lookup *lu, ZOLTAN_ID_PTR gid)
{
  struct Hash_Node *hn;
  int i, k, match;

  if (lu->table_size < 1) return -1;
  if (lu->numGIDs < 1) return -1;

  i = Zoltan_Hash(gid, lu->lenGID, (unsigned int) lu->table_size);
  
  for (hn=lu->ht[i]; hn != NULL; hn = hn->next){
    match = 1;
    for (k=0; k<lu->lenGID; k++){
      if (hn->gid[k] != gid[k]){
        match = 0;
        break;
      }
    }
    if (match){
      return (hn->gno);
    }
  }
  return -1;
}
예제 #18
0
void read_input_file(int me , int nproc, char *fname, GRAPH_DATA *graph)
{
char buf[512];
int bufsize;
int numGlobalVertices, numGlobalNeighbors;
int num, nnbors, ack=0;
int vGID;
int i, j, procID;
int vals[128], send_count[2];
int *idx;
ZOLTAN_ID_TYPE id;
FILE *fp;
MPI_Status status;
int ack_tag = 5, count_tag = 10, id_tag = 15;
GRAPH_DATA *send_graph;

  if (me == 0){

    bufsize = 512;

    fp = fopen(fname, "r");

    /* Get the number of vertices */

    num = get_next_line(fp, buf, bufsize);
    if (num == 0) input_file_error(nproc, count_tag, 1);
    num = sscanf(buf, "%d", &numGlobalVertices);
    if (num != 1) input_file_error(nproc, count_tag, 1);

    /* Get the number of vertex neighbors  */

    num = get_next_line(fp, buf, bufsize);
    if (num == 0) input_file_error(nproc, count_tag, 1);
    num = sscanf(buf, "%d", &numGlobalNeighbors);
    if (num != 1) input_file_error(nproc, count_tag, 1);

    /* Allocate arrays to read in entire graph */

    graph->vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalVertices);
    graph->nborIndex = (int *)malloc(sizeof(int) * (numGlobalVertices + 1));
    graph->nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * numGlobalNeighbors);
    graph->nborPart = (int *)malloc(sizeof(int) * numGlobalNeighbors);

    graph->vertex_capacity = numGlobalVertices;
    graph->nbor_capacity = numGlobalNeighbors;

    graph->nborIndex[0] = 0;

    for (i=0; i < numGlobalVertices; i++){

      num = get_next_line(fp, buf, bufsize);
      if (num == 0) input_file_error(nproc, count_tag, 1);

      num = get_line_ints(buf, bufsize, vals);

      if (num < 2) input_file_error(nproc, count_tag, 1);

      vGID = vals[0];
      nnbors = vals[1];

      if (num < (nnbors + 2)) input_file_error(nproc, count_tag, 1);

      graph->vertexGID[i] = (ZOLTAN_ID_TYPE)vGID;

      for (j=0; j < nnbors; j++){
        graph->nborGID[graph->nborIndex[i] + j] = (ZOLTAN_ID_TYPE)vals[2 + j];
      }

      graph->nborIndex[i+1] = graph->nborIndex[i] + nnbors;
    }

    fclose(fp);

    /* Assign each vertex to a process using a hash function */

    for (i=0; i <numGlobalNeighbors; i++){
      id = graph->nborGID[i];
      graph->nborPart[i] = Zoltan_Hash(&id, 1, nproc);
    } 

    /* Create a sub graph for each process */

    send_graph = (GRAPH_DATA *)calloc(sizeof(GRAPH_DATA) , nproc);

    for (i=0; i < numGlobalVertices; i++){
      id = graph->vertexGID[i];
      procID = Zoltan_Hash(&id, 1, nproc);
      send_graph[procID].numMyVertices++;
    }

    for (i=0; i < nproc; i++){
      num = send_graph[i].numMyVertices;
      send_graph[i].vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * num);
      send_graph[i].nborIndex = (int *)calloc(sizeof(int) , (num + 1));
    }

    idx = (int *)calloc(sizeof(int), nproc);

    for (i=0; i < numGlobalVertices; i++){

      id = graph->vertexGID[i];
      nnbors = graph->nborIndex[i+1] - graph->nborIndex[i];
      procID = Zoltan_Hash(&id, 1, nproc);

      j = idx[procID];
      send_graph[procID].vertexGID[j] = id;
      send_graph[procID].nborIndex[j+1] = send_graph[procID].nborIndex[j] + nnbors;

      idx[procID] = j+1;
    }

    for (i=0; i < nproc; i++){

      num = send_graph[i].nborIndex[send_graph[i].numMyVertices];

      send_graph[i].nborGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * num);
      send_graph[i].nborPart= (int *)malloc(sizeof(int) * num);
    }

    memset(idx, 0, sizeof(int) * nproc);

    for (i=0; i < numGlobalVertices; i++){

      id = graph->vertexGID[i];
      nnbors = graph->nborIndex[i+1] - graph->nborIndex[i];
      procID = Zoltan_Hash(&id, 1, nproc);
      j = idx[procID];

      if (nnbors > 0){
        memcpy(send_graph[procID].nborGID + j, graph->nborGID + graph->nborIndex[i],
               nnbors * sizeof(ZOLTAN_ID_TYPE));
  
        memcpy(send_graph[procID].nborPart + j, graph->nborPart + graph->nborIndex[i],
               nnbors * sizeof(int));
  
        idx[procID] = j + nnbors;
      }
    }

    free(idx);

    /* Process zero sub-graph */

    free(graph->vertexGID);
    free(graph->nborIndex);
    free(graph->nborGID);
    free(graph->nborPart);

    *graph = send_graph[0];

    /* Send other processes their subgraph */

    for (i=1; i < nproc; i++){
      send_count[0] = send_graph[i].numMyVertices;
      send_count[1] = send_graph[i].nborIndex[send_graph[i].numMyVertices];

      MPI_Send(send_count, 2, MPI_INT, i, count_tag, MPI_COMM_WORLD);
      MPI_Recv(&ack, 1, MPI_INT, i, ack_tag, MPI_COMM_WORLD, &status);

      if (send_count[0] > 0){

        MPI_Send(send_graph[i].vertexGID, send_count[0], ZOLTAN_ID_MPI_TYPE , i, id_tag, MPI_COMM_WORLD);
        free(send_graph[i].vertexGID);

        MPI_Send(send_graph[i].nborIndex, send_count[0] + 1, MPI_INT, i, id_tag + 1, MPI_COMM_WORLD);
        free(send_graph[i].nborIndex);

        if (send_count[1] > 0){
          MPI_Send(send_graph[i].nborGID, send_count[1], ZOLTAN_ID_MPI_TYPE , i, id_tag + 2, MPI_COMM_WORLD);
          free(send_graph[i].nborGID);

          MPI_Send(send_graph[i].nborPart, send_count[1], MPI_INT, i, id_tag + 3, MPI_COMM_WORLD);
          free(send_graph[i].nborPart);
        }
      }
    }

    free(send_graph);

    /* signal all procs it is OK to go on */
    ack = 0;
    for (i=1; i < nproc; i++){
      MPI_Send(&ack, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
    }
  }
  else{

    MPI_Recv(send_count, 2, MPI_INT, 0, count_tag, MPI_COMM_WORLD, &status);

    if (send_count[0] < 0){
      MPI_Finalize();
      exit(1);
    }

    ack = 0;

    graph->numMyVertices = send_count[0];

    if (send_count[0] > 0){

      graph->vertexGID = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[0]);
      graph->nborIndex = (int *)malloc(sizeof(int) * (send_count[0] + 1));

      if (send_count[1] > 0){
        graph->nborGID  = (ZOLTAN_ID_TYPE *)malloc(sizeof(ZOLTAN_ID_TYPE) * send_count[1]);
        graph->nborPart = (int *)malloc(sizeof(int) * send_count[1]);
      }
    }

    MPI_Send(&ack, 1, MPI_INT, 0, ack_tag, MPI_COMM_WORLD);

    if (send_count[0] > 0){
      MPI_Recv(graph->vertexGID,send_count[0], ZOLTAN_ID_MPI_TYPE, 0, id_tag, MPI_COMM_WORLD, &status);
      MPI_Recv(graph->nborIndex,send_count[0] + 1, MPI_INT, 0, id_tag + 1, MPI_COMM_WORLD, &status);

      if (send_count[1] > 0){
        MPI_Recv(graph->nborGID,send_count[1], ZOLTAN_ID_MPI_TYPE, 0, id_tag + 2, MPI_COMM_WORLD, &status);
        MPI_Recv(graph->nborPart,send_count[1], MPI_INT, 0, id_tag + 3, MPI_COMM_WORLD, &status);
      }
    }

    /* ok to go on? */

    MPI_Recv(&ack, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
    if (ack < 0){
      MPI_Finalize();
      exit(1);
    }
    graph->vertex_capacity = send_count[0];
    graph->nbor_capacity = send_count[1];
  }
}
예제 #19
0
int Zoltan_Map_Find_Add(ZZ *zz, ZOLTAN_MAP* map, int *key, int datain, int *dataout)
{
  char *yo = "Zoltan_Map_Add";
  int index, match, i;
  ZOLTAN_ENTRY *element;
  ZOLTAN_ID_PTR zkey = (ZOLTAN_ID_PTR)key;

  if (!map){
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Map specified does not exist\n");
    return ZOLTAN_FATAL;
  }

  index = Zoltan_Hash(zkey, map->id_size, map->max_index);

  /* If this key is not found in the map, then add it */

  element = map->entries[index];
  match = 0;

  while (element != NULL){
    match = key_match(map->id_size, element->key, key);
    if (match){
      break;
    }
    element = element->next;
  }

  if (!match){
    i = map->entry_count;

    if (!map->dynamicEntries && (i == map->max_entries)){
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Fixed size map overflow\n");
      return ZOLTAN_FATAL;
    }

    if (map->dynamicEntries){
      element = (ZOLTAN_ENTRY *)ZOLTAN_MALLOC(sizeof(ZOLTAN_ENTRY));
      if (!element)
	return ZOLTAN_MEMERR;
    }
    else{
      element = map->top + i;
    }

    if (map->copyKeys){
      if(map->dynamicEntries) {
	element->key = (int *)ZOLTAN_MALLOC(sizeof(int) * map->id_size);
	if (!element->key)
	  return ZOLTAN_MEMERR;
      }
      else
	element->key = map->keys + map->entry_count;
      memcpy(element->key, key, sizeof(int)*map->id_size);
    }
    else{
      element->key = key;
    }

    element->data = datain;
    element->next = map->entries[index];

    map->entries[index] = element;

    map->entry_count++;
  }
  if (dataout != NULL) {
    *dataout = element->data;
  }

  return ZOLTAN_OK;
}