亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? gen_perf.cpp

?? 一個開源的網絡開發庫ACE
?? CPP
字號:
// -*- C++ -*-

// Gen_Perf.cpp,v 4.17 2000/02/23 00:27:54 schmidt Exp

// Copyright (C) 1989 Free Software Foundation, Inc.
// written by Douglas C. Schmidt (schmidt@cs.wustl.edu)

// This file is part of GNU GPERF.

// 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include "Gen_Perf.h"

ACE_RCSID(src, Gen_Perf, "Gen_Perf.cpp,v 4.17 2000/02/23 00:27:54 schmidt Exp")

#if defined (ACE_HAS_GPERF)

#include "Vectors.h"

// Current release version.
extern const char *version_string;

// Reads input keys, possibly applies the reordering heuristic, sets
// the maximum associated value size (rounded up to the nearest power
// of 2), may initialize the associated values array, and determines
// the maximum hash table size.  Note: using the random numbers is
// often helpful, though not as deterministic, of course!

Gen_Perf::Gen_Perf (void)
  : fewest_collisions (0),
    num_done (1)
{
}

// Merge two disjoint hash key multisets to form the ordered disjoint
// union of the sets.  (In a multiset, an element can occur multiple
// times).  Precondition: both set1 and set2 must be
// ordered. Returns the length of the combined set.

int
Gen_Perf::compute_disjoint_union (char *set1, char *set2, char *set3)
{
  char *base = set3;

  while (*set1 && *set2)
    if (*set1 == *set2)
      set1++, set2++;
    else
      {
        *set3 = *set1 < *set2 ? *set1++ : *set2++;
        if (set3 == base || *set3 != *(set3 - 1))
          set3++;
      }

  while (*set1)
    {
      *set3 = *set1++;
      if (set3 == base || *set3 != *(set3 - 1))
        set3++;
    }

  while (*set2)
    {
      *set3 = *set2++;
      if (set3 == base || *set3 != *(set3 - 1))
        set3++;
    }
  *set3 = '\0';
  return set3 - base;
}

// Sort the UNION_SET in increasing frequency of occurrence.  This
// speeds up later processing since we may assume the resulting set
// (Set_3, in this case), is ordered. Uses insertion sort, since the
// UNION_SET is typically short.

void
Gen_Perf::sort_set (char *union_set, int len)
{
  for (int i = 0, j = len - 1; i < j; i++)
    {
      char curr, tmp;

      for (curr = i + 1, tmp = union_set[curr];
           curr > 0
           && Vectors::occurrences[tmp] < Vectors::occurrences[union_set[curr-1]];
           curr--)
        union_set[curr] = union_set[curr - 1];

      union_set[curr] = tmp;
    }
}

// Generate a keysig's hash value.

int
Gen_Perf::hash (List_Node *key_node)
{
  int sum = option[NOLENGTH] ? 0 : key_node->length;

  for (char *ptr = key_node->keysig; *ptr; ptr++)
      sum += Vectors::asso_values[*ptr];

  key_node->hash_value = sum;
  return sum;
}

// Find out how character value change affects successfully hash
// items.  Returns FALSE if no other hash values are affected, else
// returns TRUE.  Note that because Option.Get_Asso_Max is a power of
// two we can guarantee that all legal Vectors::Asso_Values are
// visited without repetition since Option.Get_Jump was forced to be
// an odd value!

inline int
Gen_Perf::affects_prev (char c, List_Node *curr)
{
  int original_char = Vectors::asso_values[c];
  int total_iterations;

  if (!option[FAST])
    total_iterations = option.asso_max ();
  else
    {
      total_iterations = option.iterations ();

      if (total_iterations == 0)
        total_iterations = this->key_list.keyword_list_length ();
    }

  // Try all legal associated values.

  for (int i = total_iterations - 1; i >= 0; i--)
    {
      int collisions = 0;

      Vectors::asso_values[c] = Vectors::asso_values[c] +
        (option.jump () ? option.jump () : ACE_OS::rand ()) & option.asso_max () - 1;

      // Iteration Number array is a win, O(1) intialization time!
      this->char_search.reset ();

      // See how this asso_value change affects previous keywords.  If
      // it does better than before we'll take it!

      for (List_Node *ptr = this->key_list.head;
           this->char_search.find (this->hash (ptr)) == 0
             || ++collisions < fewest_collisions;
           ptr = ptr->next)
        if (ptr == curr)
          {
            fewest_collisions = collisions;
            if (option[DEBUGGING])
              ACE_DEBUG ((LM_DEBUG,
                          "- resolved after %d iterations",
                          total_iterations - i));
            return 0;
          }
    }

  // Restore original values, no more tries.
  Vectors::asso_values[c] = original_char;
  // If we're this far it's time to try the next character....
  return 1;
}

// Change a character value, try least-used characters first.

int
Gen_Perf::change (List_Node *prior, List_Node *curr)
{
  if (option[DEBUGGING])
    ACE_DEBUG ((LM_DEBUG,
                "collision on keyword #%d, prior = \"%s\", curr = \"%s\" hash = %d\n",
                num_done,
                prior->key,
                curr->key,
                curr->hash_value));
  Gen_Perf::sort_set (this->union_set,
                      compute_disjoint_union (prior->keysig,
                                              curr->keysig,
                                              this->union_set));

  // Try changing some values, if change doesn't alter other values
  // continue normal action.
  fewest_collisions++;

  for (char *temp = union_set; *temp != '\0'; temp++)
    if (affects_prev (*temp, curr) == 0)
      {
        if (option[DEBUGGING])
          ACE_DEBUG ((LM_DEBUG,
                      " by changing asso_value['%c'] (char #%d) to %d\n",
                      *temp,
                      temp - union_set + 1,
                      Vectors::asso_values[*temp]));
        // Good, doesn't affect previous hash values, we'll take it.
        return 0;
      }

  for (List_Node *ptr = this->key_list.head;
       ptr != curr;
       ptr = ptr->next)
    this->hash (ptr);

  this->hash (curr);

  if (option[DEBUGGING])
    ACE_DEBUG ((LM_DEBUG,
                "** collision not resolved after %d iterations, %d duplicates remain, continuing...\n",
               !option[FAST] ? option.asso_max () : option.iterations () ? option.iterations () : this->key_list.keyword_list_length (),
                fewest_collisions + this->key_list.total_duplicates));
  return 0;
}

int
Gen_Perf::open (void)
{
  if (this->key_list.read_keys () == -1)
    return -1;

  if (option[ORDER])
    this->key_list.reorder ();

  int asso_value_max = option.asso_max ();
  int non_linked_length = this->key_list.keyword_list_length ();

  if (asso_value_max == 0)
    asso_value_max = non_linked_length;
  else if (asso_value_max > 0)
    asso_value_max *= non_linked_length;
  else // if (asso_value_max < 0)
    asso_value_max = non_linked_length / -asso_value_max;

  option.asso_max (ACE_POW (asso_value_max));

  if (option[RANDOM])
    {
      ACE_OS::srand (ACE_OS::time (0));

      for (int i = 0; i < ACE_STANDARD_CHARACTER_SET_SIZE; i++)
        Vectors::asso_values[i] = (ACE_OS::rand () & asso_value_max - 1);
    }
  else
    {
      int asso_value = option.initial_value ();

      // Initialize array if user requests non-zero default.
      if (asso_value)
        for (int i = ACE_STANDARD_CHARACTER_SET_SIZE - 1; i >= 0; i--)
          Vectors::asso_values[i] = asso_value & option.asso_max () - 1;
    }

  this->max_hash_value = this->key_list.max_key_length ()
    + option.asso_max ()
    * option.max_keysig_size ();

  ACE_NEW_RETURN (this->union_set,
                  char[2 * option.max_keysig_size () + 1],
                  -1);
  printf ("/* ");

  if (option[C])
    printf ("C");

  else if (option[CPLUSPLUS])
    printf ("C++");

  printf (" code produced by gperf version %s */\n",
          version_string);
  Options::print_options ();

  if (option[DEBUGGING])
    ACE_DEBUG ((LM_DEBUG,
                "total non-linked keys = %d\n"
                "total duplicates = %d\n"
                "maximum associated value is %d\n"
                "maximum size of generated hash table is %d\n",
                non_linked_length,
                this->key_list.total_duplicates,
                asso_value_max,
                max_hash_value));
  if (this->char_search.open (max_hash_value + 1) == -1)
    return -1;
  return 0;
}

// For binary search, do normal string sort on the keys, and then
// assign hash values from 0 to N-1. Then go ahead with the normal
// logic that is there for perfect hashing.
int
Gen_Perf::compute_binary_search (void)
{
  // Do a string sort.
  this->key_list.string_sort ();

  // Assign hash values.
  List_Node *curr;
  int hash_value;
  for (hash_value = 0, curr = this->key_list.head;
       curr != 0;
       curr = curr->next, hash_value++)
    {
      curr->hash_value = hash_value;
    }

  return 0;
}

int
Gen_Perf::compute_linear_search (void)
{
  // Convert the list of keys to a linear list without
  // equivalence classes.
  this->key_list.string_sort ();

  // Assign hash values.
  List_Node *curr;
  int hash_value;
  for (hash_value = 0, curr = this->key_list.head;
       curr != 0;
       curr = curr->next, hash_value++)
    {
      curr->hash_value = hash_value;
    }
  return 0;
}

int
Gen_Perf::compute_perfect_hash (void)
{
  List_Node *curr;

  for (curr = this->key_list.head;
       curr != 0;
       curr = curr->next)
    {
      this->hash (curr);

      for (List_Node *ptr = this->key_list.head;
	   ptr != curr;
	   ptr = ptr->next)
        if (ptr->hash_value == curr->hash_value)
          {
            if (this->change (ptr, curr) == -1)
              return -1;
            break;
          }
      num_done++;
    }

  // Make one final check, just to make sure nothing weird happened...

  this->char_search.reset ();

  for (curr = this->key_list.head;
       curr;
       curr = curr->next)
    if (this->char_search.find (this->hash (curr)) != 0)
      if (option[DUP])
        // Keep track of the number of "dynamic" links (i.e., keys
        // that hash to the same value) so that we can use it later
        // when generating the output.
        this->key_list.total_duplicates++;
      else
        {
          // Yow, big problems.  we're outta here!
          ACE_ERROR ((LM_ERROR,
                      "\nInternal error, duplicate value %d:\n"
                      "try options -D or -r, or use new key positions.\n\n",
                      this->hash (curr)));
          return -1;
        }

  return 0;
}

// Does the hard stuff....  Initializes the Bool Array, and attempts
// to find a perfect function that will hash all the key words without
// getting any duplications.  This is made much easier since we aren't
// attempting to generate *minimum* functions, only perfect ones.  If
// we can't generate a perfect function in one pass *and* the user
// hasn't enabled the DUP option, we'll inform the user to try the
// randomization option, use -D, or choose alternative key positions.
// The alternatives (e.g., back-tracking) are too time-consuming, i.e,
// exponential in the number of keys.

int
Gen_Perf::run (void)
{
  if (this->open () == -1)
    return 1;

  if (option[BINARYSEARCH])
    {
      if (this->compute_binary_search () == -1)
        return 1;
    }
  else if (option[LINEARSEARCH])
    {
      if (this->compute_linear_search () == -1)
	return 1;
    }
  else
    {
      if (this->compute_perfect_hash () == -1)
	return 1;

      // Sorts the key word list by hash value, and then outputs the
      // list.  The generated hash table code is only output if the
      // early stage of processing turned out O.K.
      this->key_list.sort ();
    }

  this->key_list.output ();
  return 0;
}

// Prints out some diagnostics upon completion.

Gen_Perf::~Gen_Perf (void)
{
  if (option[DEBUGGING])
    {
      ACE_DEBUG ((LM_DEBUG,
                  "\ndumping occurrence and associated values tables\n"));
      for (int i = 0; i < ACE_STANDARD_CHARACTER_SET_SIZE; i++)
        if (Vectors::occurrences[i])
          ACE_DEBUG ((LM_DEBUG,
                      "Vectors::asso_values[%c] = %6d, Vectors::occurrences[%c] = %6d\n",
                      i,
                      Vectors::asso_values[i],
                      i,
                      Vectors::occurrences[i]));
      ACE_DEBUG ((LM_DEBUG,
                  "end table dumping\n"));
    }

  delete [] this->union_set;
}

#endif /* ACE_HAS_GPERF */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
粉嫩aⅴ一区二区三区四区五区| 亚洲精品欧美综合四区| 久久综合九色综合97婷婷| 日韩欧美一区二区视频| 国产嫩草影院久久久久| 亚洲国产一区在线观看| 精品综合久久久久久8888| 免费观看一级特黄欧美大片| 成人国产免费视频| 欧美精品1区2区| 欧美国产日韩一二三区| 午夜精品福利一区二区三区蜜桃| 国产精品综合一区二区| 欧美性猛交xxxxxxxx| 欧美精品在线观看一区二区| 国产三级一区二区三区| 亚洲成人中文在线| 午夜婷婷国产麻豆精品| 日韩精品视频网站| 欧美最猛性xxxxx直播| 亚洲日本在线看| 成人性生交大合| 久久婷婷久久一区二区三区| 美女www一区二区| 日韩欧美国产一区二区在线播放 | 国产精品美女久久久久av爽李琼| 日韩成人免费在线| 一本大道久久精品懂色aⅴ| 《视频一区视频二区| 99久久免费国产| 国产精品国产三级国产有无不卡| 国产99久久久精品| 欧美韩国日本综合| 99精品久久只有精品| 国产精品少妇自拍| 春色校园综合激情亚洲| 国产精品久久夜| 91美女精品福利| 亚洲一区影音先锋| 欧美日韩国产精品成人| 视频在线在亚洲| 精品久久久久一区二区国产| 狠狠色狠狠色综合| 国产亚洲一区二区三区四区| 国产一区二区三区免费看| 久久尤物电影视频在线观看| 国内外精品视频| 中文字幕一区二区在线播放| 色狠狠av一区二区三区| 婷婷激情综合网| www精品美女久久久tv| 成人午夜在线视频| 一区二区三区四区五区视频在线观看 | 亚洲三级在线看| 欧美亚洲国产bt| 免费成人在线播放| 中文字幕一区二区三区在线播放| 成人av免费在线| 五月激情六月综合| 久久久欧美精品sm网站| 色哟哟精品一区| 久久99精品久久久久婷婷| 国产欧美综合在线观看第十页| 95精品视频在线| 秋霞电影网一区二区| 亚洲国产精品精华液ab| 欧美日本在线看| 福利视频网站一区二区三区| 亚洲国产精品久久久男人的天堂| 欧美一区二区三区四区久久| 成人小视频在线| 青青草原综合久久大伊人精品 | 五月综合激情日本mⅴ| 久久夜色精品国产欧美乱极品| 99精品国产91久久久久久 | 日韩精品专区在线影院观看| 成人国产精品视频| 免费成人你懂的| 亚洲资源在线观看| 国产农村妇女精品| 日韩欧美色电影| 欧美三片在线视频观看| av一区二区久久| 久久精品理论片| 婷婷一区二区三区| 亚洲靠逼com| 国产精品视频一区二区三区不卡| 欧美日韩精品一区视频| 99精品欧美一区二区三区小说| 久久99精品久久久久久动态图 | 制服丝袜亚洲精品中文字幕| caoporm超碰国产精品| 国模一区二区三区白浆| 天堂久久一区二区三区| 亚洲欧美一区二区三区久本道91| 久久久国产精华| 日韩精品中文字幕一区| 欧美高清视频一二三区 | av电影在线不卡| 国产一区二区中文字幕| 麻豆精品国产91久久久久久| 亚洲成av人片一区二区梦乃| 亚洲女女做受ⅹxx高潮| 亚洲欧洲av色图| 国产精品麻豆视频| 中文字幕欧美三区| 国产日韩亚洲欧美综合| 精品国产99国产精品| 日韩色在线观看| 日韩欧美在线影院| 制服丝袜亚洲精品中文字幕| 91精品久久久久久久久99蜜臂| 欧美日韩免费电影| 欧美精品v国产精品v日韩精品| 欧美日韩一二三| 欧美精品自拍偷拍| 精品噜噜噜噜久久久久久久久试看| 91精品国产综合久久久久| 欧美日韩色一区| 欧美日韩成人在线| 欧美一区在线视频| 久久一区二区三区四区| 欧美精品一区二区蜜臀亚洲| 精品国产免费一区二区三区香蕉| 日韩一级二级三级精品视频| 欧美xxxxx牲另类人与| 久久久久久久久久久久久夜| 国产日产欧美精品一区二区三区| 中文成人综合网| 亚洲精品一卡二卡| 性做久久久久久久免费看| 亚洲18色成人| 激情文学综合网| jiyouzz国产精品久久| 欧美日韩一区三区| 亚洲精品一区二区三区福利| 日本一区二区三区在线不卡| 亚洲女厕所小便bbb| 日本特黄久久久高潮| 国产美女在线精品| 色香色香欲天天天影视综合网| 欧美日韩精品系列| 久久久亚洲精品石原莉奈| 亚洲女人****多毛耸耸8| 奇米影视一区二区三区小说| 国产高清视频一区| 91蜜桃免费观看视频| 91精品国产综合久久精品麻豆| 国产亚洲欧美日韩在线一区| 亚洲你懂的在线视频| 开心九九激情九九欧美日韩精美视频电影 | 国产精品午夜春色av| 一区二区三区四区中文字幕| 久久99精品久久久久久动态图| av电影在线观看不卡| 日韩一区二区三区在线观看| 国产精品你懂的在线| 日本欧美一区二区三区| 99热这里都是精品| 欧美成人精品高清在线播放| 1区2区3区欧美| 国产在线精品一区在线观看麻豆| 在线观看国产精品网站| 久久蜜臀中文字幕| 日韩中文字幕麻豆| 91美女片黄在线| 欧美激情一区在线观看| 日韩二区三区在线观看| 99re66热这里只有精品3直播 | 高清国产午夜精品久久久久久| 欧美在线看片a免费观看| 欧美激情一区在线观看| 麻豆精品久久久| 欧美美女喷水视频| 亚洲一区影音先锋| 99麻豆久久久国产精品免费| 久久免费精品国产久精品久久久久| 午夜av一区二区三区| 一本色道久久综合精品竹菊| 国产欧美一区二区精品久导航 | 亚洲线精品一区二区三区八戒| 国产aⅴ综合色| 久久亚洲捆绑美女| 六月丁香婷婷色狠狠久久| 欧美高清激情brazzers| 亚洲国产精品一区二区久久 | 国产91在线观看| 欧美mv和日韩mv的网站| 日韩福利电影在线观看| 欧美精品久久99久久在免费线| 亚洲激情网站免费观看| 99久久综合国产精品| 国产精品少妇自拍| 99久久婷婷国产综合精品| 国产精品久久久久婷婷二区次| 粉嫩绯色av一区二区在线观看| 久久久不卡网国产精品二区| 久久成人羞羞网站| 久久久久国产精品麻豆ai换脸| 国产一区二区三区av电影|