⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dictionary.cc

📁 早期freebsd实现
💻 CC
字号:
// -*- C++ -*-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.     Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING.  If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include "troff.h"#include "symbol.h"#include "dictionary.h"  // is `p' a good size for a hash tablestatic int is_good_size(int p){  const int SMALL = 10;  for (unsigned i = 2; i <= p/2; i++)    if (p % i == 0)      return 0;  for (i = 0x100; i != 0; i <<= 8)    if (i % p <= SMALL || i % p > p - SMALL)      return 0;  return 1;}dictionary::dictionary(int n) : threshold(0.5), factor(1.5), used(0), size(n){  table = new association[n];  for (int i = 0; i < n; i++)    table[i].v = 0;}// see Knuth, Sorting and Searching, p518, Algorithm L// we can't use double-hashing because we want a remove functionvoid *dictionary::lookup(symbol s, void *v){  for (int i = int(s.hash() % size);        table[i].v != 0;       i == 0 ? i = size - 1: --i)    if (s == table[i].s) {      if (v != 0) {	void *temp = table[i].v;	table[i].v = v;	return temp;      }      else	return table[i].v;    }  if (v == 0)    return 0;  ++used;  table[i].v = v;  table[i].s = s;  if ((double)used/(double)size >= threshold || used + 1 >= size) {    int old_size = size;    size = int(size*factor);    while (!is_good_size(size))      ++size;    association *old_table = table;    table = new association[size];    used = 0;    for (i = 0; i < old_size; i++)      if (old_table[i].v != 0)	(void)lookup(old_table[i].s, old_table[i].v);    a_delete old_table;  }  return 0;}void *dictionary::lookup(const char *p){  symbol s(p, MUST_ALREADY_EXIST);  if (s.is_null())    return 0;  else    return lookup(s);}// see Knuth, Sorting and Searching, p527, Algorithm R  void *dictionary::remove(symbol s){  // this relies on the fact that we are using linear probing  for (int i = int(s.hash() % size);       table[i].v != 0 && s != table[i].s;       i == 0 ? i = size - 1: --i)    ;  void *p = table[i].v;  while (table[i].v != 0) {    table[i].v = 0;    int j = i;    int r;    do {      --i;      if (i < 0)	i = size - 1;      if (table[i].v == 0)	break;      r = int(table[i].s.hash() % size);    } while ((i <= r && r < j) || (j < i && i <= r));    table[j] = table[i];  }  if (p != 0)    --used;  return p;}dictionary_iterator::dictionary_iterator(dictionary &d) : dict(&d), i(0){}int dictionary_iterator::get(symbol *sp, void **vp){  for (; i < dict->size; i++)    if (dict->table[i].v) {      *sp = dict->table[i].s;      *vp = dict->table[i].v;      i++;      return 1;    }  return 0;}object_dictionary_iterator::object_dictionary_iterator(object_dictionary &od)     : di(od.d){}object::object() : rcount(0){}object::~object(){}void object::add_reference(){  rcount += 1;}void object::remove_reference(){  if (--rcount == 0)    delete this;}object_dictionary::object_dictionary(int n) : d(n){}object *object_dictionary::lookup(symbol nm){  return (object *)d.lookup(nm);}void object_dictionary::define(symbol nm, object *obj){  obj->add_reference();  obj = (object *)d.lookup(nm, obj);  if (obj)    obj->remove_reference();}void object_dictionary::rename(symbol oldnm, symbol newnm){  object *obj = (object *)d.remove(oldnm);  if (obj) {    obj = (object *)d.lookup(newnm, obj);    if (obj)      obj->remove_reference();  }}void object_dictionary::remove(symbol nm){  object *obj = (object *)d.remove(nm);  if (obj)    obj->remove_reference();}// Return non-zero if oldnm was defined.int object_dictionary::alias(symbol newnm, symbol oldnm){  object *obj = (object *)d.lookup(oldnm);  if (obj) {    obj->add_reference();    obj = (object *)d.lookup(newnm, obj);    if (obj)      obj->remove_reference();    return 1;  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -