source: src/lib/symtab.cc

Last change on this file was 5f4d9c3, checked in by Maciej Prill <mprill@…>, 13 years ago

Rewritten the build system, added lem UTF-8 version.

  • Property mode set to 100644
File size: 3.8 KB
Line 
1#include "symtab.h"
2#include <limits> // numeric_limits
3#include <cstdio>
4#include <cstdlib>
5//---------------------------------------------------------------------------
6using namespace UTT;
7SymbolTable::SymbolTable(int n, int (*h)(const char*,int), const char* filename)
8             : _mx(n), _cnt(0), hash(h)
9{
10  _sz=first(n);
11  _key=new char*[_sz];
12  _defind=new int[_sz];
13  _hashind=new int[_sz];
14  _def=new char*[_mx];
15  for(int i=0; i<_sz; i++) _key[i]=NULL;
16  if(filename)
17    add_from_file(filename);
18}
19
20//---------------------------------------------------------------------------
21
22SymbolTable::SymbolTable(int n, const char* filename)
23             : _mx(n), _cnt(0), hash(hash1)
24{
25  _sz=first(n);
26  _key=new char*[_sz];
27  _defind=new int[_sz];
28  _hashind=new int[_sz];
29  _def=new char*[_mx];
30  for(int i=0; i<_sz; ++i) _key[i]=NULL;
31  if(filename)
32    add_from_file(filename);
33}
34
35//---------------------------------------------------------------------------
36
37SymbolTable::~SymbolTable()
38{
39  clear();
40  delete[] _key;
41  delete[] _defind;
42  delete[] _hashind;
43  delete[] _def;
44}
45
46//---------------------------------------------------------------------------
47
48void SymbolTable::clear()
49{
50  for(int i=0; i<_sz; ++i)
51    if(_key[i])
52      free(_key[i]);
53}
54
55//---------------------------------------------------------------------------
56
57bool SymbolTable::add_from_file(const char* filename)
58{
59  FILE* in=fopen(filename,"r");
60  char buf[MAXKEYLEN+1];
61
62  if(in)
63    while(fscanf(in,"%s",buf)==1)
64    {
65      if(strlen(buf)==MAXKEYLEN || add(buf)<0)
66        return false;
67    }
68  return true;
69}
70
71//---------------------------------------------------------------------------
72
73int SymbolTable::add(const char* s)
74{
75  if(_cnt<_mx)
76  {
77    int ind=hash(s,_sz);
78    while(_key[ind])
79      if(strcmp(_key[ind],s))
80        ind=++ind%_sz;
81      else
82        return _defind[ind];
83    _key[ind]=strdup(s);
84    _defind[ind]=_cnt;
85    _hashind[_cnt]=ind;
86    _def[_cnt]=_key[ind];
87    _cnt++;
88    return _cnt-1;
89  }
90  else
91    return -1;
92}
93
94//---------------------------------------------------------------------------
95
96int SymbolTable::operator[](const char* s)
97{
98  int ind=hash(s,_sz);
99  while(_key[ind])
100    if(strcmp(_key[ind],s)==0)
101      return _defind[ind];
102    else
103      ind=++ind % _sz;
104  return -1;
105}
106
107//---------------------------------------------------------------------------
108
109int SymbolTable::first(unsigned int n)
110{
111  int fi=n;
112  int bound=(n/2 < MAXKEYLEN)? n/2 : MAXKEYLEN;
113  bool found;
114  do
115  {
116    found=true;
117    if(fi++ == std::numeric_limits<int>::max) return -1;
118    for(int i=2; i<bound; i++)
119      if(fi%i==0) { found=false; break; }
120  } while(!found);
121  return fi;
122}
123
124float SymbolTable::search_rate()
125{
126  long s=0;
127  for(int i=0; i<_sz; i++)
128    if(_key[i])
129      s+=(i+_sz-hash(_key[i],_sz))%_sz+1;
130  return _cnt ? (float)s/(float)_cnt : 0;
131}
132
133//---------------------------------------------------------------------------
134
135int hash1(const char* s, int _sz)
136{
137  int l=strlen(s);
138  if(l>=4)
139    return abs((*((int*)(s+(l/2-2)))+(int)(*s * s[l-1])) % _sz);
140  else
141  {
142    int i=0;
143    strcpy((char*)&i,s);
144    return abs((i+(int)(*s * s[l-1])) % _sz);
145  }
146}
147
148//---------------------------------------------------------------------------
149
150int hash2(const char* s, int _sz)
151{
152  int l=strlen(s);
153  if(l>=6)
154  {
155    unsigned int i1,i2,i3;
156    strncpy((char*)&i1,s,sizeof(int));
157    strncpy((char*)&i2,s+(l/2-2),sizeof(int));
158    strncpy((char*)&i3,s+(l-4),sizeof(int));
159    return abs((i1+i2+i3) % _sz);
160  }
161  else
162  {
163    int i=0;
164    strncpy((char*)&i,s,sizeof(int));
165    return abs((i+(int)(*s * s[l-1])) % _sz);
166  }
167}
168
169//---------------------------------------------------------------------------
170
Note: See TracBrowser for help on using the repository browser.