00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00035 #include "stringhash.h"
00036 #include <cstring>
00037 #include <cstdlib>
00038
00039 StringHash::StringHash():
00040 base(HASH_BASE), matches(new vector < TagInfo * >[base]), free_index(0) {
00041 hash("ROOT");
00042 }
00043
00044 StringHash::~StringHash() {
00045 for (int i = 0; i < base; i++) {
00046 for (unsigned j = 0; j < matches[i].size(); j++) {
00047 delete matches[i][j];
00048 }
00049 }
00050
00051 delete[]matches;
00052 }
00053
00054 unsigned StringHash::hash(const char *s) {
00055 unsigned key = h(s);
00056
00057 if (matches[key].size() != 0) {
00058 for (unsigned i = 0; i < matches[key].size(); i++) {
00059 if (strcmp(matches[key][i]->tag, s) == 0) {
00060 return matches[key][i]->index;
00061 }
00062 }
00063 }
00064
00065 char *_s = new char[strlen(s) + 1];
00066
00067 strcpy(_s, s);
00068
00069 matches[key].push_back(new TagInfo(_s, free_index));
00070 return free_index++;
00071 }
00072
00073 unsigned StringHash::hash(const char *s, unsigned start_offset,
00074 unsigned end_offset) {
00075 unsigned key = h(s, start_offset, end_offset);
00076
00077
00078 if (matches[key].size() != 0) {
00079 for (unsigned i = 0; i < matches[key].size(); i++) {
00080 if (strncmp(s + start_offset, matches[key][i]->tag,
00081 strlen(s) - (start_offset + end_offset)) == 0) {
00082 return matches[key][i]->index;
00083 }
00084 }
00085 }
00086
00087 unsigned total_offset = start_offset + end_offset;
00088 char *_s = new char[strlen(s) - total_offset + 1];
00089
00090 strncpy(_s, s + start_offset, strlen(s) - total_offset);
00091 _s[strlen(s) - (start_offset + end_offset)] = '\0';
00092
00093 matches[key].push_back(new TagInfo(_s, free_index));
00094 return free_index++;
00095 }
00096
00097 unsigned StringHash::h(const char *s) {
00098 unsigned sum = 0;
00099
00100 for (unsigned i = 0; i < strlen(s); i++) {
00101 sum += s[i];
00102 }
00103 sum %= base;
00104
00105 return sum;
00106 }
00107
00108 unsigned StringHash::h(const char *s, unsigned start_offset,
00109 unsigned end_offset) {
00110 unsigned sum = 0;
00111
00112 for (unsigned i = start_offset; i < strlen(s) - end_offset; i++) {
00113 sum += s[i];
00114 }
00115 sum %= base;
00116
00117 return sum;
00118 }