Index: src/lib/symtab.cc
===================================================================
--- src/lib/symtab.cc	(revision 5f4d9c3b32eea7b6643a751aa75bdb05b7d41576)
+++ src/lib/symtab.cc	(revision 5f4d9c3b32eea7b6643a751aa75bdb05b7d41576)
@@ -0,0 +1,170 @@
+#include "symtab.h"
+#include <limits> // numeric_limits
+#include <cstdio>
+#include <cstdlib>
+//---------------------------------------------------------------------------
+using namespace UTT;
+SymbolTable::SymbolTable(int n, int (*h)(const char*,int), const char* filename)
+             : _mx(n), _cnt(0), hash(h)
+{
+  _sz=first(n);
+  _key=new char*[_sz];
+  _defind=new int[_sz];
+  _hashind=new int[_sz];
+  _def=new char*[_mx];
+  for(int i=0; i<_sz; i++) _key[i]=NULL;
+  if(filename)
+    add_from_file(filename);
+}
+
+//---------------------------------------------------------------------------
+
+SymbolTable::SymbolTable(int n, const char* filename)
+             : _mx(n), _cnt(0), hash(hash1)
+{
+  _sz=first(n);
+  _key=new char*[_sz];
+  _defind=new int[_sz];
+  _hashind=new int[_sz];
+  _def=new char*[_mx];
+  for(int i=0; i<_sz; ++i) _key[i]=NULL;
+  if(filename)
+    add_from_file(filename);
+}
+
+//---------------------------------------------------------------------------
+
+SymbolTable::~SymbolTable()
+{
+  clear();
+  delete[] _key;
+  delete[] _defind;
+  delete[] _hashind;
+  delete[] _def;
+}
+
+//---------------------------------------------------------------------------
+
+void SymbolTable::clear()
+{
+  for(int i=0; i<_sz; ++i)
+    if(_key[i])
+      free(_key[i]);
+}
+
+//---------------------------------------------------------------------------
+
+bool SymbolTable::add_from_file(const char* filename)
+{
+  FILE* in=fopen(filename,"r");
+  char buf[MAXKEYLEN+1];
+
+  if(in)
+    while(fscanf(in,"%s",buf)==1)
+    {
+      if(strlen(buf)==MAXKEYLEN || add(buf)<0)
+        return false;
+    }
+  return true;
+}
+
+//---------------------------------------------------------------------------
+
+int SymbolTable::add(const char* s)
+{
+  if(_cnt<_mx)
+  {
+    int ind=hash(s,_sz);
+    while(_key[ind])
+      if(strcmp(_key[ind],s))
+        ind=++ind%_sz;
+      else
+        return _defind[ind];
+    _key[ind]=strdup(s);
+    _defind[ind]=_cnt;
+    _hashind[_cnt]=ind;
+    _def[_cnt]=_key[ind];
+    _cnt++;
+    return _cnt-1;
+  }
+  else
+    return -1;
+}
+
+//---------------------------------------------------------------------------
+
+int SymbolTable::operator[](const char* s)
+{
+  int ind=hash(s,_sz);
+  while(_key[ind])
+    if(strcmp(_key[ind],s)==0)
+      return _defind[ind];
+    else
+      ind=++ind % _sz;
+  return -1;
+}
+
+//---------------------------------------------------------------------------
+
+int SymbolTable::first(unsigned int n)
+{
+  int fi=n;
+  int bound=(n/2 < MAXKEYLEN)? n/2 : MAXKEYLEN;
+  bool found;
+  do
+  {
+    found=true;
+    if(fi++ == std::numeric_limits<int>::max) return -1;
+    for(int i=2; i<bound; i++)
+      if(fi%i==0) { found=false; break; }
+  } while(!found);
+  return fi;
+}
+
+float SymbolTable::search_rate()
+{
+  long s=0;
+  for(int i=0; i<_sz; i++)
+    if(_key[i])
+      s+=(i+_sz-hash(_key[i],_sz))%_sz+1;
+  return _cnt ? (float)s/(float)_cnt : 0;
+}
+
+//---------------------------------------------------------------------------
+
+int hash1(const char* s, int _sz)
+{
+  int l=strlen(s);
+  if(l>=4)
+    return abs((*((int*)(s+(l/2-2)))+(int)(*s * s[l-1])) % _sz);
+  else
+  {
+    int i=0;
+    strcpy((char*)&i,s);
+    return abs((i+(int)(*s * s[l-1])) % _sz);
+  }
+}
+
+//---------------------------------------------------------------------------
+
+int hash2(const char* s, int _sz)
+{
+  int l=strlen(s);
+  if(l>=6)
+  {
+    unsigned int i1,i2,i3;
+    strncpy((char*)&i1,s,sizeof(int));
+    strncpy((char*)&i2,s+(l/2-2),sizeof(int));
+    strncpy((char*)&i3,s+(l-4),sizeof(int));
+    return abs((i1+i2+i3) % _sz);
+  }
+  else
+  {
+    int i=0;
+    strncpy((char*)&i,s,sizeof(int));
+    return abs((i+(int)(*s * s[l-1])) % _sz);
+  }
+}
+
+//---------------------------------------------------------------------------
+
