Exemple #1
0
TEST(cht, make_hash) {
  string hash = make_hash("hage");
  string hash2 = make_hash("hage");
  string hash3 = make_hash("hoge");
  ASSERT_EQ(hash, hash2);
  ASSERT_NE(hash, hash3);
}
TEST(hashchain, genesis)
{
  tools::hashchain hashchain;
  hashchain.push_back(make_hash(1));
  ASSERT_EQ(hashchain.size(), 1);
  ASSERT_EQ(hashchain.genesis(), make_hash(1));
  hashchain.push_back(make_hash(2));
  ASSERT_EQ(hashchain.size(), 2);
  ASSERT_EQ(hashchain.genesis(), make_hash(1));
}
TEST(hashchain, clear_empty)
{
  tools::hashchain hashchain;
  ASSERT_TRUE(hashchain.empty());
  hashchain.push_back(make_hash(1));
  ASSERT_FALSE(hashchain.empty());
  hashchain.push_back(make_hash(2));
  ASSERT_FALSE(hashchain.empty());
  hashchain.clear();
  ASSERT_TRUE(hashchain.empty());
}
Exemple #4
0
// return at most n nodes, if theres nodes less than n, return size is also less
// than n.
// find(hash) :: lock_service -> key -> [node]
//   where hash(node0) <= hash(key) < hash(node1)
bool cht::find(
    const std::string& key,
    std::vector<std::pair<std::string, int> >& out,
    size_t n) {
  out.clear();
  std::vector<std::string> hlist;
  if (!get_hashlist_(key, hlist)) {
    throw JUBATUS_EXCEPTION(core::common::not_found(key));
  }
  std::string hash = make_hash(key);
  std::string path;
  build_actor_path(path, type_, name_);
  path += "/cht";

  std::vector<std::string>::iterator node0 = std::lower_bound(hlist.begin(),
                                                              hlist.end(),
                                                              hash);

  size_t idx = static_cast<int>(node0 - hlist.begin()) % hlist.size();
  std::string loc;
  for (size_t i = 0; i < n; ++i) {
    std::string ip;
    int port;
    if (lock_service_->read(path + "/" + hlist[idx], loc)) {
      revert(loc, ip, port);
      out.push_back(make_pair(ip, port));
    } else {
      // TODO(kuenishi): output log
      throw JUBATUS_EXCEPTION(core::common::not_found(path));
    }
    idx++;
    idx %= hlist.size();
  }
  return !hlist.size();
}
Exemple #5
0
bool CAdPlugDatabase::insert(CRecord *record)
{
  long index;

  // sanity checks
  if(!record) return false;			// null-pointer given
  if(linear_length == hash_radix) return false;	// max. db size exceeded
  if(lookup(record->key)) return false;		// record already in db

  // make bucket
  DB_Bucket *bucket = new DB_Bucket(linear_length, record);
  if(!bucket) return false;

  // add to linear list
  db_linear[linear_length] = bucket;
  linear_logic_length++; linear_length++;

  // add to hashed list
  index = make_hash(record->key);

  if(!db_hashed[index])	// First entry in hashtable
    db_hashed[index] = bucket;
  else {		// Add entry in chained list
    DB_Bucket *chain = db_hashed[index];

    while(chain->chain) chain = chain->chain;
    chain->chain = bucket;
  }

  return true;
}
Exemple #6
0
  // return at most n nodes, if theres nodes less than n, return size is also less than n.
  // find(hash)    :: lock_service -> key -> [node] where hash(node0) <= hash(key) < hash(node1)
  bool cht::find(const std::string& key, std::vector<std::pair<std::string,int> >& out, size_t n){
    out.clear();
    std::vector<std::string> hlist;
    if(! get_hashlist_(key, hlist)){
      throw JUBATUS_EXCEPTION(not_found(key));
    }
    std::string hash = make_hash(key);
    std::string path = ACTOR_BASE_PATH + "/" + name_ + "/cht";

    std::vector<std::string>::iterator node0 = std::lower_bound(hlist.begin(), hlist.end(), hash);
    size_t idx = int(node0 - hlist.begin()) % hlist.size();
    std::string loc;
    for(size_t i=0; i<n; ++i){
      std::string ip;
      int port;
      if(lock_service_->read(path + "/" + hlist[idx], loc)){
        revert(loc, ip, port);
        out.push_back(make_pair(ip,port));
      }else{
        // TODO: output log
        throw JUBATUS_EXCEPTION(not_found(path));
      }
      idx++;
      idx %= hlist.size();
    }
    return !hlist.size();
  }
Exemple #7
0
  // find(hash)    :: lock_service -> key -> [node] where hash(node0) <= hash(key) < hash(node1)
  bool cht::find(const std::string& key, std::vector<std::pair<std::string,int> >& out){
    out.clear();
    std::string path = ACTOR_BASE_PATH + "/" + name_ + "/cht";
    std::string hash = make_hash(key);
    std::vector<std::pair<std::string, int> > ret;
    std::vector<std::string> hlist;
    lock_service_->list(path, hlist);

    if(hlist.empty()) return false;
    std::sort(hlist.begin(), hlist.end());

    std::vector<std::string>::iterator node0 = std::lower_bound(hlist.begin(), hlist.end(), hash);
    size_t idx = int(node0 - hlist.begin()) % hlist.size();
    std::string loc;
    for(int i=0; i<2; ++i){
      std::string ip;
      int port;
      if(lock_service_->read(path + "/" + hlist[idx], loc)){
        revert(loc, ip, port);
        out.push_back(make_pair(ip,port));
      }else{
        // TODO: output log
      }
      idx++;
      idx %= hlist.size();
    }
    return !hlist.size();
  }
Exemple #8
0
std::pair<std::string, int> cht::find_predecessor(const std::string& key) {
  std::vector<std::string> hlist;
  get_hashlist_(key, hlist);

  std::string hash = make_hash(key);
  std::string path;
  build_actor_path(path, type_, name_);
  path += "/cht";

  std::vector<std::string>::iterator node0 = std::lower_bound(hlist.begin(),
                                                              hlist.end(),
                                                              hash);

  size_t idx = (static_cast<int>(node0 - hlist.begin()) + hlist.size() - 1)
    % hlist.size();

  std::string ip;
  int port;
  std::string loc;
  if (lock_service_->read(path + "/" + hlist[idx], loc)) {
    revert(loc, ip, port);
    return make_pair(ip, port);
  } else {
    throw JUBATUS_EXCEPTION(core::common::not_found(path));
    // TODO(kuenishi): output log and throw exception
  }
}
Exemple #9
0
static ERL_NIF_TERM mruby2erl(ErlNifEnv* env, mrb_state* mrb, mrb_value value) {
  if (mrb_nil_p(value)) {
    return enif_make_atom(env, "nil");
  } else {
    switch(value.tt) {
      case MRB_TT_TRUE:
        return enif_make_atom(env, "true");

      case MRB_TT_FALSE:
        return enif_make_atom(env, "false");

      case MRB_TT_SYMBOL:
        return enif_make_atom(env, _mrb_symbol(mrb, value));

      case MRB_TT_FIXNUM:
        return enif_make_int(env, _mrb_fixnum(value));

      case MRB_TT_FLOAT:
        return enif_make_double(env, _mrb_float(value));

      case MRB_TT_STRING:
        return make_binary(env, _mrb_string(mrb, value));

      case MRB_TT_ARRAY:
        return make_array(env, mrb, value);

      case MRB_TT_HASH:
        return make_hash(env, mrb, value);

      default :
        return enif_make_atom(env, "nil");
    }
  }
}
Exemple #10
0
DICT_T * DICT_Create( char * id )
{
    DICT_T * dict = calloc( 1, sizeof( DICT_T ) );

    if ( dict )
    {
        int hash = make_hash( id );

        /* Fill struct */

        dict->id = strdup( id );
        dict->hash = hash;

        /* Insert dict in table */

        dict->prev = NULL;
        dict->next = _DICT_table;
        if ( _DICT_table ) _DICT_table->prev = dict;
        _DICT_table = dict;

        /* Insert dict in hashed table */

        dict->prev_hashed = NULL;
        dict->next_hashed = _DICT_table_hashed[hash];
        if ( _DICT_table_hashed[ hash ] ) _DICT_table_hashed[ hash ]->prev_hashed = dict;
        _DICT_table_hashed[ hash ] = dict ;

        /* Cleanup entries structs */

        dict->entries = NULL;
        memset( dict->entries_hashed, '\0', sizeof( dict->entries_hashed ) );
    }

    return ( dict );
}
Exemple #11
0
bool CAdPlugDatabase::lookup(CKey const &key)
{
  unsigned long index = make_hash(key);
  if(!db_hashed[index]) return false;

  // immediate hit ?
  DB_Bucket *bucket = db_hashed[index];

  if(!bucket->deleted && bucket->record->key == key) {
    linear_index = bucket->index;
    return true;
  }

  // in-chain hit ?
  bucket = db_hashed[index]->chain;

  while(bucket) {
    if(!bucket->deleted && bucket->record->key == key) {
      linear_index = bucket->index;
      return true;
    }

    bucket = bucket->chain;
  }

  return false;
}
TEST(hashchain, trim)
{
  tools::hashchain hashchain;
  hashchain.push_back(make_hash(1));
  hashchain.push_back(make_hash(2));
  hashchain.push_back(make_hash(3));
  ASSERT_EQ(hashchain.offset(), 0);
  hashchain.trim(2);
  ASSERT_EQ(hashchain.offset(), 2);
  ASSERT_EQ(hashchain.size(), 3);
  ASSERT_EQ(hashchain[2], make_hash(3));
  hashchain.trim(3);
  ASSERT_EQ(hashchain.offset(), 2); // never gets it empty
  ASSERT_EQ(hashchain.size(), 3);
  ASSERT_FALSE(hashchain.empty());
  ASSERT_EQ(hashchain.genesis(), make_hash(1));
}
Exemple #13
0
 size_t operator()(const T& v) const
 {
     size_t h=0;
     for( auto& e : v ) {
         hash_combine(h, make_hash(e));
     }
     return h;
 }
Exemple #14
0
  // register_node :: node -> bool;
  // creates /jubatus/actors/<name>/cht/<hash(ip_port)> with contents ip_port
  void cht::register_node(const std::string& ip, int port){
    std::string path = ACTOR_BASE_PATH + "/" + name_ + "/cht";

    for(unsigned int i=0; i<NUM_VSERV; ++i){
      std::string hashpath = path+"/"+make_hash(build_loc_str(ip, port, i));
      lock_service_->create(hashpath, build_loc_str(ip,port), true);
      DLOG(INFO) << "created " << hashpath;
    }
  }
Exemple #15
0
inline
void connection_tracking(packetinfo *pi) {
    uint32_t hash;

    // add to packetinfo ? dont through int32 around :)
    hash = make_hash(pi);
    cxt_update(pi, hash);
    return;
}
Exemple #16
0
int DICT_AddEntry( DICT_T * dict, char * key, void * value, int len, int flags )
{
    DICT_ENTRY_T * entry;

    if ( dict && key )
    {
        int hash = make_hash( key );

        if ( ( entry = __DICT_FINDENTRY( dict, key, hash ) ) )
        {
            if ( !( entry->flags & DICT_ENTRY_FLAG_DONT_ALLOC ) && entry->val ) free( entry->val );

            __DICT_SET_DATA;

            return 0;
        }
        else
        {
            if ( ( entry = malloc( sizeof( DICT_ENTRY_T ) ) ) )
            {
                if ( flags & DICT_ENTRY_FLAG_DONT_ALLOC )
                {
                    entry->key = key;
                }
                else
                {
                    if ( !( entry->key = strdup( key ) ) )
                    {
                        free( entry );
                        return -1;
                    }
                }

                __DICT_SET_DATA;

                /* Insert entry in table */

                entry->prev = NULL;
                entry->next = dict->entries;
                if ( dict->entries ) dict->entries->prev = entry;
                dict->entries = entry;

                /* Insert entry in hashed table */

                entry->prev_hashed = NULL;
                entry->next_hashed = dict->entries_hashed[ hash ];
                if ( dict->entries_hashed[ hash ] ) dict->entries_hashed[ hash ]->prev_hashed = entry;
                dict->entries_hashed[ hash ] = entry ;

                return 0;
            }
        }
    }

    return -1;
}
static void
make_ssid_hashes (const char *ssid,
                  NM80211Mode mode,
                  char **open,
                  char **wep,
                  char **wpa,
                  char **rsn,
                  char **wpa_rsn)
{
	*open = make_hash (ssid, mode,
	                   NM_802_11_AP_FLAGS_NONE,
	                   NM_802_11_AP_SEC_NONE,
	                   NM_802_11_AP_SEC_NONE);

	*wep = make_hash (ssid, mode,
	                  NM_802_11_AP_FLAGS_PRIVACY,
	                  NM_802_11_AP_SEC_NONE,
	                  NM_802_11_AP_SEC_NONE);

	*wpa = make_hash (ssid, mode,
	                  NM_802_11_AP_FLAGS_PRIVACY,
	                  NM_802_11_AP_SEC_PAIR_TKIP |
	                      NM_802_11_AP_SEC_GROUP_TKIP |
	                      NM_802_11_AP_SEC_KEY_MGMT_PSK,
	                  NM_802_11_AP_SEC_NONE);

	*rsn = make_hash (ssid, mode,
	                  NM_802_11_AP_FLAGS_PRIVACY,
	                  NM_802_11_AP_SEC_NONE,
	                  NM_802_11_AP_SEC_PAIR_CCMP |
	                      NM_802_11_AP_SEC_GROUP_CCMP |
	                      NM_802_11_AP_SEC_KEY_MGMT_PSK);

	*wpa_rsn = make_hash (ssid, mode,
	                      NM_802_11_AP_FLAGS_PRIVACY,
	                      NM_802_11_AP_SEC_PAIR_TKIP |
	                          NM_802_11_AP_SEC_GROUP_TKIP |
	                          NM_802_11_AP_SEC_KEY_MGMT_PSK,
	                      NM_802_11_AP_SEC_PAIR_CCMP |
	                          NM_802_11_AP_SEC_GROUP_CCMP |
	                          NM_802_11_AP_SEC_KEY_MGMT_PSK);
}
TEST(hashchain, push_back)
{
  tools::hashchain hashchain;
  hashchain.push_back(make_hash(1));
  hashchain.push_back(make_hash(2));
  hashchain.push_back(make_hash(3));
  ASSERT_EQ(hashchain[0], make_hash(1));
  ASSERT_EQ(hashchain[1], make_hash(2));
  ASSERT_EQ(hashchain[2], make_hash(3));
}
Exemple #19
0
void * DICT_GetEntry( DICT_T * dict, char * key, int * len )
{
    DICT_ENTRY_T * entry;

    if ( dict && key )
    {
        int hash = make_hash( key );
        if (( entry = __DICT_FINDENTRY( dict, key, hash ) ) )
        {
            if ( len ) *len = entry->len ;
            return ( entry->val );
        }
    }

    return ( NULL );
}
Exemple #20
0
// register_node :: node -> bool;
// creates /jubatus/actors/<name>/cht/<hash(ip_port)> with contents ip_port
void cht::register_node(const std::string& ip, int port) {
  std::string path;
  build_actor_path(path, type_, name_);
  path += "/cht";

  for (unsigned int i = 0; i < NUM_VSERV; ++i) {
    std::string hashpath = path + "/" + make_hash(build_loc_str(ip, port, i));
    if (!lock_service_->create(hashpath, build_loc_str(ip, port), true)) {
      throw JUBATUS_EXCEPTION(
        core::common::exception::runtime_error("Failed to register cht node")
        << core::common::exception::error_api_func("lock_service::create")
        << core::common::exception::error_message("cht hashpash: " + hashpath));
    }

    DLOG(INFO) << "cht node created: " << hashpath;
  }
}
Exemple #21
0
/* this DOESNT add the key to the hashtable
 * TODO make it consistent with search_name_hashtable
 */
unsigned int search_status_hashtable(const char *key)
{
	unsigned int probe_address = 0;
	unsigned int probe_decrement = 0;

	make_hash(key, &probe_address, &probe_decrement, STATUS_HASH_PRIME);
	while(status_hashtable[probe_address] != NULL) {
		if (strcmp(key, name_hashtable[package_hashtable[status_hashtable[probe_address]->package]->name]) == 0) {
			break;
		} else {
			probe_address -= probe_decrement;
			if ((int)probe_address < 0) {
				probe_address += STATUS_HASH_PRIME;
			}
		}
	}
	return(probe_address);
}
Exemple #22
0
VALUE make_normal_type(VALUE name) {
	VALUE ret;
	NGS_TYPE *t;
	t = NGS_MALLOC(sizeof(*t));
	assert(t);

	SET_OBJ(ret, t);
	OBJ_TYPE_NUM(ret) = T_TYPE;

	NGS_TYPE_NAME(ret) = name;
	NGS_TYPE_FIELDS(ret) = make_hash(8); // Hash: name->index
	NGS_TYPE_CONSTRUCTORS(ret) = make_array(1);
	NGS_TYPE_PARENTS(ret) = make_array(0);

	VALUE ctr = make_normal_type_constructor(ret);
	ARRAY_ITEMS(NGS_TYPE_CONSTRUCTORS(ret))[0] = ctr;

	return ret;
}
Exemple #23
0
/* this adds the key to the hash table */
int search_name_hashtable(const char *key)
{
	unsigned int probe_address = 0;
	unsigned int probe_decrement = 0;
//	char *temp;

	make_hash(key, &probe_address, &probe_decrement, NAME_HASH_PRIME);
	while(name_hashtable[probe_address] != NULL) {
		if (strcmp(name_hashtable[probe_address], key) == 0) {
			return(probe_address);
		} else {
			probe_address -= probe_decrement;
			if ((int)probe_address < 0) {
				probe_address += NAME_HASH_PRIME;
			}
		}
	}
	name_hashtable[probe_address] = xstrdup(key);
	return(probe_address);
}
Exemple #24
0
  std::pair<std::string,int> cht::find_predecessor(const std::string& key){
    std::vector<std::string> hlist;
    get_hashlist_(key, hlist);

    std::string hash = make_hash(key);
    std::string path = ACTOR_BASE_PATH + "/" + name_ + "/cht";

    std::vector<std::string>::iterator node0 = std::lower_bound(hlist.begin(), hlist.end(), hash);
    size_t idx = (int(node0 - hlist.begin())+ hlist.size() -1) % hlist.size();

    std::string ip;
    int port;
    std::string loc;
    if(lock_service_->read(path + "/" + hlist[idx], loc)){
      revert(loc, ip, port);
      return make_pair(ip, port);
    }else{
      throw JUBATUS_EXCEPTION(not_found(path));
      // TODO: output log and throw exception
    }
  }
Exemple #25
0
int search_package_hashtable(const unsigned int name, const unsigned int version, const unsigned int operator)
{
	unsigned int probe_address = 0;
	unsigned int probe_decrement = 0;

	make_hash(name_hashtable[name], &probe_address, &probe_decrement, PACKAGE_HASH_PRIME);
	while(package_hashtable[probe_address] != NULL) {
		if (package_hashtable[probe_address]->name == name) {
			if (operator == VER_ANY) {
				return(probe_address);
			}
			if (test_version(package_hashtable[probe_address]->version, version, operator)) {
				return(probe_address);
			}
		}
		probe_address -= probe_decrement;
		if ((int)probe_address < 0) {
			probe_address += PACKAGE_HASH_PRIME;
		}
	}
	return(probe_address);
}
Exemple #26
0
void DICT_DelEntry( DICT_T * dict, char * key )
{
    int hash = make_hash( key );
    DICT_ENTRY_T * entry = __DICT_FINDENTRY( dict, key, hash ) ;

    if ( !entry ) return ;

    if ( !( entry->flags & DICT_ENTRY_FLAG_DONT_ALLOC ) && entry->val ) free( entry->val );

    /* Remove entry from table */

    if ( entry->next ) entry->next->prev = entry->prev ;
    if ( entry->prev ) entry->prev->next = entry->next ;
    else dict->entries = entry->next ; /* No prev */

    /* Remove entry from hashed table */

    if ( entry->next_hashed ) entry->next_hashed->prev_hashed = entry->prev_hashed ;
    if ( entry->prev_hashed ) entry->prev_hashed->next_hashed = entry->next_hashed ;
    else dict->entries_hashed[ hash ] = entry->next_hashed ; /* No prev */

    free( entry->key );
    free( entry );
}
Exemple #27
0
size_t hash_icase_t::operator()(wchar_t const Char) const
{
	return make_hash(upper(Char));
}
Exemple #28
0
size_t hash_icase_t::operator()(const string& Str) const
{
	return make_hash(upper(Str));
}
//FUNCTION: The 'match' function carries out pairwise PocketMatch scoring.
//It reads 2 <cabbage unit files> and directly prints a character string of results.
int match(char *file1_const, char *file2_const,
          FILE *OP_file1, FILE *OP_file2, 
          int FILE_address1, int FILE_address2)
{
/* Variable explanations:
  *file1: pointer for <cabbage unit file-1>. NOT a file-pointer
  *file1-const: input pointer, used to to keep track of the beginning of *file1
  *file2: pointer for <cabbage unit file-2>. NOT a file-pointer
  *file2-const: input pointer, used to to keep track of the beginning of *file2
  i, j: loop variables
  SUM_file1/valsum1: Total number of <distance-elements> in <cabbage unit file-1>
  SUM_file2/valsum2: Total number of <distance-elements> in <cabbage unit file-2>
  counter: counts the number of matching <distance-elements> between <cabbage unit files-1/2>

  frac1: P-min (PocketMatch minimum) score
  frac2: P-max (PocketMatch maximum) score
  bin_counter1: array[1x90] of no. of <pairwise distances> per <point-type-comparison> in <cabbage unit file-1>
  bin_counter2: array[1x90] of no. of <pairwise distances> per <point-type-comparison> in <cabbage unit file-2>
  num1end: Number of <pairwise distances> in a given <point-type-comparison> in <cabbage unit file-1>
           Extracted from val1 array[1x90]
  num2end: Number of <pairwise distances> in a given <point-type-comparison> in <cabbage unit file-2>
           Extracted from val1 array[1x90]
  num1: Incremental counter, counts from 0 to num1end
  num2: Incremental counter, counts from 0 to num2end
  name1: User-given file-name of <cabbage unit file-1>
  name2: User-given file-name of <cabbage unit file-2>
*/

int i, j;
int bin_counter1[90], bin_counter2[90];
char *file1=file1_const, *file2=file2_const;
char name1[OP_NAME_SIZE], name2[OP_NAME_SIZE];
UNION_int temp_intUNION;

//Read filename of <cabbage unit files-1/2>
for(i=0;i<OP_NAME_SIZE;++i)  {
  name1[i] = *(file1 +i +sizeof(int));
  name2[i] = *(file2 +i +sizeof(int));
  }

//Shift 'file-pointers' to appropriate location:
file1 = file1 +OP_NAME_SIZE +sizeof(int);
file2 = file2 +OP_NAME_SIZE +sizeof(int);

//Read number of <distance-elements>:
//Calculate total number of <distance-elements> for 'file1/2':
int SUM_file1=0, SUM_file2=0;
for(i=0;i<90;++i)  {
  bin_counter1[i] = *((int*)file1+i);
  SUM_file1 += bin_counter1[i];
  bin_counter2[i] = *((int*)file2+i);
  SUM_file2 += bin_counter2[i];
  }
//Shift 'file-pointers' to appropriate location:
file1 = file1+sizeof(int)*90;
file2 = file2+sizeof(int)*90;
//Declare 'element' file-pointers at start of <distance-elements> block:
element *file1_element=(element*)file1, *file1_element_const=(element*)file1;
element *file2_element=(element*)file2, *file2_element_const=(element*)file2;

//Initialise hash-table to store residues of <distance-elements> that pass CUTOFF threshold:
twin_int *hash_table1, *hash_table2;
int hash_size;
if(SUMA_TOGGLE==1)  {
  if(SUM_file1>SUM_file2) hash_size=SUM_file1;
  else hash_size=SUM_file2;
  hash_size = ((int)((sqrt(8*hash_size+1)+1)/2))+1;
  //Since 2-residue numbers accompany 1 <distance-element> the hash-table
  //size has to be a function of the largest number of <distance-elements>
  hash_table1 = make_hash(hash_size);
  hash_table2 = make_hash(hash_size);
  }

/*===================================\
|      PocketMatch Calculation       |
\===================================*/
int valsum1=0, valsum2=0, counter=0, num1end, num2end;
double frac1, frac2;
element num1, num2;
int IP_value1[3], IP_value2[3];

for(i=0;i<90;++i)  {
  valsum1 = valsum1+bin_counter1[i];
  valsum2 = valsum2+bin_counter2[i];
  if((bin_counter1[i]!=0)&&(bin_counter2[i]!=0))  {
    num1end = bin_counter1[i];
    num2end = bin_counter2[i];
    //Read <distance-elements> values, Increment file-pointers:
    num1 = *file1_element; ++file1_element;
    num2 = *file2_element; ++file2_element;

    while(1)  {
      //Count number of <distance-elements> that pass CUTOFF threshold:
      if(num1.distance.d-num2.distance.d<0.5 && num1.distance.d-num2.distance.d>-0.5)  {
        if(SUMA_TOGGLE==1)  {
          //Store 'residue-numbers' in 'hash_table1':
          IP_value1[0] = num1.residue1.i;
          IP_value1[1] = num2.residue1.i;
          IP_value1[2] = num2.residue2.i;
          IP_hash(hash_table1, IP_value1);

          IP_value1[0] = num1.residue2.i;
          IP_hash(hash_table1, IP_value1);

          //Store 'residue-numbers' in 'hash_table2':
          IP_value2[0] = num2.residue1.i;
          IP_value2[1] = num1.residue1.i;
          IP_value2[2] = num1.residue2.i;
          IP_hash(hash_table2, IP_value2);

          IP_value2[0] = num2.residue2.i;
          IP_hash(hash_table2, IP_value2);
          }
        ++counter;
        --num1end;
        --num2end;

        //Read <distance-elementse> values, Increment file-pointers:
        num1 = *file1_element; ++file1_element;
        num2 = *file2_element; ++file2_element;
        }
      else  {
        if(num1.distance.d<num2.distance.d)  {
          --num1end;
          //Read <distance-elements> value, Increment file-pointer:
          num1 = *file1_element; ++file1_element;
          }
        else  {
          --num2end;
          //Read <distance-elements> value, Increment file-pointer:
          num2 = *file2_element; ++file2_element;
          }
        }
      if(num1end<=0) break;
      if(num2end<=0) break;
      }
    }
  //Move onto another set of <point-type-comparisons>
  file1_element = file1_element_const+valsum1;
  file2_element = file2_element_const+valsum2;
  }

//Assign values to frac1 (P-min) and frac2 (P-max) based on 
//total number of <distance-elements> in <cabbage unit files-1/2>
if(valsum1<valsum2)  {
  frac1 = (double)counter/(double)valsum1;
  frac2 = (double)counter/(double)valsum2;
  }
else  {
  frac1 = (double)counter/(double)valsum2;
  frac2 = (double)counter/(double)valsum1;
  }

/*===================================\
|      SUMA-SCORE: Calculations      |
\===================================*/
int SUMA_score=0;
char SUMA_block[BLOCK_SIZE];

if(SUMA_TOGGLE==1)  {
  strncpy(SUMA_block, name1, 32);
  strncpy(SUMA_block+32, name2, 32);
  compare_hash(hash_table1, hash_table2, &SUMA_score, SUMA_block);
  }

/*===================================\
|           Output results           |
\===================================*/
//Print output string (1 line only):
//If one or more input pockets has no matches:
char *OP_string=malloc(LINE_LENGTH*sizeof(char));

if(valsum1==0||valsum2==0)  {
  if(SUMA_TOGGLE==1)  {
    sprintf(OP_string, "%.32s %.32s NULL____ NULL____ ________ ________ ________ ________\n", name1, name2);
    }
  else  {
    sprintf(OP_string, "%.32s %.32s NULL____ NULL____ ________ ________ ________\n", name1, name2);
    }
  }
//Standard output:
else  {
  if(SUMA_TOGGLE==1)  {
  sprintf(OP_string, "%.32s %.32s %8.6f %8.6f %8d %8d %8d %8d\n", name1, name2, frac1, frac2, valsum1, valsum2, counter, SUMA_score);
    }
  else  {
  sprintf(OP_string, "%.32s %.32s %8.6f %8.6f %8d %8d %8d\n", name1, name2, frac1, frac2, valsum1, valsum2, counter); 
    }
  }

//Write outputs to PM-score file, 'OP_file1':
fseek(OP_file1, FILE_address1, SEEK_SET);
for(i=0;i<LINE_LENGTH;++i) fputc(*(OP_string+i), OP_file1);

//Write outputs to SUMA-score file, 'OP_file2':
fseek(OP_file2, FILE_address2, SEEK_SET);
for(i=0;i<BLOCK_SIZE;++i) fputc(SUMA_block[i], OP_file2);

if(SUMA_TOGGLE==1)  {
  //Free the 2 hash-tables' allocated memory:
  free(hash_table1);
  free(hash_table2);
  }

//Free all allocated memory:
free(OP_string);
return 0;
}
TEST(hashchain, crop)
{
  tools::hashchain hashchain;
  hashchain.push_back(make_hash(1));
  hashchain.push_back(make_hash(2));
  hashchain.push_back(make_hash(3));
  ASSERT_EQ(hashchain.size(), 3);
  ASSERT_EQ(hashchain[0], make_hash(1));
  ASSERT_EQ(hashchain[1], make_hash(2));
  ASSERT_EQ(hashchain[2], make_hash(3));
  hashchain.crop(3);
  ASSERT_EQ(hashchain.size(), 3);
  hashchain.crop(2);
  ASSERT_EQ(hashchain.size(), 2);
  ASSERT_EQ(hashchain[0], make_hash(1));
  ASSERT_EQ(hashchain[1], make_hash(2));
  ASSERT_EQ(hashchain.genesis(), make_hash(1));
  hashchain.crop(0);
  ASSERT_TRUE(hashchain.empty());
  ASSERT_EQ(hashchain.size(), 0);
  hashchain.push_back(make_hash(5));
  ASSERT_EQ(hashchain.genesis(), make_hash(5));
  ASSERT_EQ(hashchain.size(), 1);
}