File: igraph_hashtable.c

package info (click to toggle)
r-cran-igraph 1.0.1-1~bpo8%2B1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-backports
  • size: 18,160 kB
  • sloc: ansic: 173,529; cpp: 19,365; fortran: 4,550; yacc: 1,164; tcl: 931; lex: 484; makefile: 149; sh: 9
file content (128 lines) | stat: -rw-r--r-- 4,103 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* -*- mode: C -*-  */
/* 
   IGraph library.
   Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
   334 Harvard street, Cambridge, MA 02139 USA
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 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 General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA 
   02110-1301 USA

*/

#include "igraph_types.h"
#include "igraph_types_internal.h"
#include "igraph_memory.h"
#include "igraph_error.h"
#include "config.h"
#include <string.h>

int igraph_hashtable_init(igraph_hashtable_t *ht) {
  IGRAPH_CHECK(igraph_trie_init(&ht->keys, 1));
  IGRAPH_FINALLY(igraph_trie_destroy, &ht->keys);
  IGRAPH_CHECK(igraph_strvector_init(&ht->elements, 0));
  IGRAPH_FINALLY(igraph_trie_destroy, &ht->elements);
  IGRAPH_CHECK(igraph_strvector_init(&ht->defaults, 0));
  
  IGRAPH_FINALLY_CLEAN(2);
  return 0;
}

void igraph_hashtable_destroy(igraph_hashtable_t *ht) {
  igraph_trie_destroy(&ht->keys);
  igraph_strvector_destroy(&ht->elements);
  igraph_strvector_destroy(&ht->defaults);
}

/* Note: may leave the hash table in an inconsistent state if a new
   element is added, but this is not a big problem, since while the
   defaults, or the defaults plus the elements may contain more elements
   than the keys trie, but the data is always retrieved based on the trie
*/

int igraph_hashtable_addset(igraph_hashtable_t *ht,
			    const char *key, const char *def, 
			    const char *elem){
  long int size=igraph_trie_size(&ht->keys);
  long int newid;  
  IGRAPH_CHECK(igraph_trie_get(&ht->keys, key, &newid));

  if (newid==size) {
    /* this is a new element */
    IGRAPH_CHECK(igraph_strvector_resize(&ht->defaults, newid+1));
    IGRAPH_CHECK(igraph_strvector_resize(&ht->elements, newid+1));
    IGRAPH_CHECK(igraph_strvector_set(&ht->defaults, newid, def));
    IGRAPH_CHECK(igraph_strvector_set(&ht->elements, newid, elem));
  } else {
    /* set an already existing element */
    IGRAPH_CHECK(igraph_strvector_set(&ht->elements, newid, elem));
  }
  
  return 0;
}

/* Previous comment also applies here */

int igraph_hashtable_addset2(igraph_hashtable_t *ht,
			     const char *key, const char *def,
			     const char *elem, int elemlen) {
  long int size=igraph_trie_size(&ht->keys);
  long int newid;
  char *tmp;

  IGRAPH_CHECK(igraph_trie_get(&ht->keys, key, &newid));

  tmp=igraph_Calloc(elemlen+1, char);
  if (tmp==0) {
    IGRAPH_ERROR("cannot add element to hash table", IGRAPH_ENOMEM);
  }
  IGRAPH_FINALLY(free, tmp);
  strncpy(tmp, elem, elemlen);
  tmp[elemlen]='\0';

  if (newid==size) {
    IGRAPH_CHECK(igraph_strvector_resize(&ht->defaults, newid+1));
    IGRAPH_CHECK(igraph_strvector_resize(&ht->elements, newid+1));
    IGRAPH_CHECK(igraph_strvector_set(&ht->defaults, newid, def));
    IGRAPH_CHECK(igraph_strvector_set(&ht->elements, newid, tmp));    
  } else {
    IGRAPH_CHECK(igraph_strvector_set(&ht->elements, newid, tmp));    
  }

  igraph_Free(tmp);
  IGRAPH_FINALLY_CLEAN(1);

  return 0;
}

int igraph_hashtable_get(igraph_hashtable_t *ht,
			 const char *key, char **elem) {
  long int newid;
  IGRAPH_CHECK(igraph_trie_get(&ht->keys, key, &newid));
  
  igraph_strvector_get(&ht->elements, newid, elem);
  
  return 0;
}

int igraph_hashtable_reset(igraph_hashtable_t *ht) {
  igraph_strvector_destroy(&ht->elements);
  IGRAPH_CHECK(igraph_strvector_copy(&ht->elements, &ht->defaults));
  return 0;
}

int igraph_hashtable_getkeys(igraph_hashtable_t *ht, 
			     const igraph_strvector_t **sv) {
  return igraph_trie_getkeys(&ht->keys, sv);
}