*** empty log message ***

This commit is contained in:
David Rose 2001-03-22 22:54:25 +00:00
parent 192dbfe946
commit c47d83286d
16 changed files with 331 additions and 17 deletions

View File

@ -26,5 +26,8 @@ main(int argc, char *argv[]) {
return (1);
}
long hash = file.get_hash();
cout << "File hash is " << hash << "\n";
return (0);
}

View File

@ -12,10 +12,13 @@
#define SOURCES \
dcAtomicField.cxx dcAtomicField.h dcClass.cxx dcClass.h \
dcField.cxx dcField.h dcFile.cxx dcFile.h dcLexer.lxx dcLexerDefs.h \
dcField.cxx dcField.h dcFile.cxx dcFile.h \
dcLexer.lxx dcLexerDefs.h \
dcMolecularField.cxx dcMolecularField.h dcParser.yxx \
dcParserDefs.h dcSubatomicType.cxx dcSubatomicType.h dcbase.h \
dcindent.cxx dcindent.h
dcindent.cxx dcindent.h \
hashGenerator.cxx hashGenerator.h \
primeNumberGenerator.h primeNumberGenerator.cxx
#define IGATESCAN all
#end lib_target

View File

@ -4,6 +4,7 @@
////////////////////////////////////////////////////////////////////
#include "dcAtomicField.h"
#include "hashGenerator.h"
#include "dcindent.h"
@ -213,3 +214,23 @@ write(ostream &out, int indent_level) const {
out << "; // field " << _number << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: DCAtomicField::generate_hash
// Access: Public, Virtual
// Description: Accumulates the properties of this field into the
// hash.
////////////////////////////////////////////////////////////////////
void DCAtomicField::
generate_hash(HashGenerator &hash) const {
DCField::generate_hash(hash);
hash.add_int(_elements.size());
Elements::const_iterator ei;
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
const ElementType &element = (*ei);
hash.add_int(element._type);
hash.add_int(element._divisor);
}
hash.add_int(_flags);
}

View File

@ -39,6 +39,7 @@ PUBLISHED:
public:
DCAtomicField();
virtual void write(ostream &out, int indent_level = 0) const;
virtual void generate_hash(HashGenerator &hash) const;
public:
// These members define the primary interface to the atomic field

View File

@ -4,6 +4,7 @@
////////////////////////////////////////////////////////////////////
#include "dcClass.h"
#include "hashGenerator.h"
#include "dcindent.h"
////////////////////////////////////////////////////////////////////
@ -162,9 +163,9 @@ DCClass() {
////////////////////////////////////////////////////////////////////
DCClass::
~DCClass() {
Fields::iterator ai;
for (ai = _fields.begin(); ai != _fields.end(); ++ai) {
delete (*ai);
Fields::iterator fi;
for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
delete (*fi);
}
}
@ -190,14 +191,37 @@ write(ostream &out, int indent_level) const {
}
out << " { // index " << _number << "\n";
Fields::const_iterator ai;
for (ai = _fields.begin(); ai != _fields.end(); ++ai) {
(*ai)->write(out, indent_level + 2);
Fields::const_iterator fi;
for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
(*fi)->write(out, indent_level + 2);
}
indent(out, indent_level) << "};\n";
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::generate_hash
// Access: Public, Virtual
// Description: Accumulates the properties of this class into the
// hash.
////////////////////////////////////////////////////////////////////
void DCClass::
generate_hash(HashGenerator &hash) const {
hash.add_string(_name);
hash.add_int(_parents.size());
Parents::const_iterator pi;
for (pi = _parents.begin(); pi != _parents.end(); ++pi) {
hash.add_int((*pi)->get_number());
}
hash.add_int(_fields.size());
Fields::const_iterator fi;
for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
(*fi)->generate_hash(hash);
}
}
////////////////////////////////////////////////////////////////////
// Function: DCClass::add_field
// Access: Public

View File

@ -12,6 +12,8 @@
#include <vector>
#include <map>
class HashGenerator;
////////////////////////////////////////////////////////////////////
// Class : DCClass
// Description : Defines a particular DistributedClass as read from an
@ -37,6 +39,8 @@ public:
~DCClass();
void write(ostream &out, int indent_level = 0) const;
void generate_hash(HashGenerator &hash) const;
bool add_field(DCField *field);
public:

View File

@ -4,6 +4,7 @@
////////////////////////////////////////////////////////////////////
#include "dcField.h"
#include "hashGenerator.h"
////////////////////////////////////////////////////////////////////
// Function: DCField::get_number
@ -59,3 +60,18 @@ as_molecular_field() {
DCField::
~DCField() {
}
////////////////////////////////////////////////////////////////////
// Function: DCField::generate_hash
// Access: Public, Virtual
// Description: Accumulates the properties of this field into the
// hash.
////////////////////////////////////////////////////////////////////
void DCField::
generate_hash(HashGenerator &hash) const {
// It shouldn't be necessary to explicitly add _number to the
// hash--this is computed based on the relative position of this
// field with the other fields, so adding it explicitly will be
// redundant. However, the field name is significant.
hash.add_string(_name);
}

View File

@ -10,6 +10,7 @@
class DCAtomicField;
class DCMolecularField;
class HashGenerator;
////////////////////////////////////////////////////////////////////
// Class : DCField
@ -27,6 +28,7 @@ PUBLISHED:
public:
virtual ~DCField();
virtual void write(ostream &out, int indent_level = 0) const=0;
virtual void generate_hash(HashGenerator &hash) const;
public:
int _number;

View File

@ -6,6 +6,7 @@
#include "dcFile.h"
#include "dcParserDefs.h"
#include "dcLexerDefs.h"
#include "hashGenerator.h"
#ifdef WITHIN_PANDA
#include <filename.h>
@ -14,7 +15,7 @@
////////////////////////////////////////////////////////////////////
// Function: DCFile::Constructor
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
DCFile::
@ -23,7 +24,7 @@ DCFile() {
////////////////////////////////////////////////////////////////////
// Function: DCFile::Destructor
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
DCFile::
@ -36,7 +37,7 @@ DCFile::
////////////////////////////////////////////////////////////////////
// Function: DCFile::read
// Access: Public
// Access: Published
// Description: Opens and reads the indicated .dc file by name. The
// distributed classes defined in the file will be
// appended to the set of distributed classes already
@ -67,7 +68,7 @@ read(Filename filename) {
////////////////////////////////////////////////////////////////////
// Function: DCFile::read
// Access: Public
// Access: Published
// Description: Parses the already-opened input stream for
// distributed class descriptions. The filename
// parameter is optional and is only used when reporting
@ -92,7 +93,7 @@ read(istream &in, const string &filename) {
////////////////////////////////////////////////////////////////////
// Function: DCFile::write
// Access: Public
// Access: Published
// Description: Opens the indicated filename for output and writes a
// parseable description of all the known distributed
// classes to the file.
@ -120,7 +121,7 @@ write(Filename filename) const {
////////////////////////////////////////////////////////////////////
// Function: DCFile::write
// Access: Public
// Access: Published
// Description: Writes a parseable description of all the known
// distributed classes to the file. The filename
// parameter is optional and is only used when reporting
@ -147,7 +148,7 @@ write(ostream &out, const string &filename) const {
////////////////////////////////////////////////////////////////////
// Function: DCFile::get_num_classes
// Access: Public
// Access: Published
// Description: Returns the number of classes read from the .dc
// file(s).
////////////////////////////////////////////////////////////////////
@ -158,7 +159,7 @@ get_num_classes() {
////////////////////////////////////////////////////////////////////
// Function: DCFile::get_class
// Access: Public
// Access: Published
// Description: Returns the nth class read from the .dc file(s).
////////////////////////////////////////////////////////////////////
DCClass *DCFile::
@ -169,7 +170,7 @@ get_class(int n) {
////////////////////////////////////////////////////////////////////
// Function: DCFile::get_class_by_name
// Access: Public
// Access: Published
// Description: Returns the class that has the indicated name, or
// NULL if there is no such class.
////////////////////////////////////////////////////////////////////
@ -184,6 +185,37 @@ get_class_by_name(const string &name) {
return (DCClass *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: DCFile::get_hash
// Access: Published
// Description: Returns a 32-bit hash index associated with this
// file. This number is guaranteed to be consistent if
// the contents of the file have not changed, and it is
// very likely to be different if the contents of the
// file do change.
////////////////////////////////////////////////////////////////////
long DCFile::
get_hash() const {
HashGenerator hash;
generate_hash(hash);
return hash.get_hash();
}
////////////////////////////////////////////////////////////////////
// Function: DCFile::generate_hash
// Access: Public, Virtual
// Description: Accumulates the properties of this file into the
// hash.
////////////////////////////////////////////////////////////////////
void DCFile::
generate_hash(HashGenerator &hash) const {
hash.add_int(_classes.size());
Classes::const_iterator ci;
for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
(*ci)->generate_hash(hash);
}
}
////////////////////////////////////////////////////////////////////
// Function: DCFile::add_class
// Access: Public

View File

@ -12,6 +12,8 @@
#include <vector>
#include <map>
class HashGenerator;
////////////////////////////////////////////////////////////////////
// Class : DCFile
// Description : Represents the complete list of Distributed Class
@ -33,7 +35,10 @@ PUBLISHED:
DCClass *get_class_by_name(const string &name);
long get_hash() const;
public:
void generate_hash(HashGenerator &hash) const;
bool add_class(DCClass *dclass);
public:

View File

@ -5,6 +5,7 @@
#include "dcMolecularField.h"
#include "dcAtomicField.h"
#include "hashGenerator.h"
#include "dcindent.h"
@ -79,3 +80,20 @@ write(ostream &out, int indent_level) const {
out << "; // field " << _number << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: DCMolecularField::generate_hash
// Access: Public, Virtual
// Description: Accumulates the properties of this field into the
// hash.
////////////////////////////////////////////////////////////////////
void DCMolecularField::
generate_hash(HashGenerator &hash) const {
DCField::generate_hash(hash);
hash.add_int(_fields.size());
Fields::const_iterator fi;
for (fi = _fields.begin(); fi != _fields.end(); ++fi) {
(*fi)->generate_hash(hash);
}
}

View File

@ -30,6 +30,7 @@ PUBLISHED:
public:
DCMolecularField();
virtual void write(ostream &out, int indent_level = 0) const;
virtual void generate_hash(HashGenerator &hash) const;
public:
// These members define the primary interface to the molecular field

View File

@ -0,0 +1,69 @@
// Filename: hashGenerator.cxx
// Created by: drose (22Mar01)
//
////////////////////////////////////////////////////////////////////
#include "hashGenerator.h"
#include "primeNumberGenerator.h"
// We multiply each consecutive integer by the next prime number and
// add it to the total, so in theory we will truly generate a unique
// hash number for each unique sequence of ints, as long as the number
// of ints does not exceed the number of prime numbers we have, and we
// do not overflow the limits of a 32-bit integer.
// We do recycle the prime number table at some point, just to keep it
// from growing insanely large, however, and we also truncate
// everything to the low-order 32 bits, so we introduce ambiguity in
// this way.
static const int max_prime_numbers = 10000;
static PrimeNumberGenerator primes;
////////////////////////////////////////////////////////////////////
// Function: HashGenerator::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
HashGenerator::
HashGenerator() {
_hash = 0;
_index = 0;
}
////////////////////////////////////////////////////////////////////
// Function: HashGenerator::add_int
// Access: Public
// Description: Adds another integer to the hash so far.
////////////////////////////////////////////////////////////////////
void HashGenerator::
add_int(int num) {
nassertv(_index >= 0 && _index < max_prime_numbers);
_hash += (int)primes[_index] * num;
_index = (_index + 1) % max_prime_numbers;
}
////////////////////////////////////////////////////////////////////
// Function: HashGenerator::add_string
// Access: Public
// Description: Adds a string to the hash, by breaking it down into a
// sequence of integers.
////////////////////////////////////////////////////////////////////
void HashGenerator::
add_string(const string &str) {
add_int(str.length());
string::const_iterator si;
for (si = str.begin(); si != str.end(); ++si) {
add_int(*si);
}
}
////////////////////////////////////////////////////////////////////
// Function: HashGenerator::get_hash
// Access: Public
// Description: Returns the hash number generated.
////////////////////////////////////////////////////////////////////
long HashGenerator::
get_hash() const {
return _hash & 0xffffffff;
}

View File

@ -0,0 +1,30 @@
// Filename: hashGenerator.h
// Created by: drose (22Mar01)
//
////////////////////////////////////////////////////////////////////
#ifndef DCHASHGENERATOR_H
#define DCHASHGENERATOR_H
#include "dcbase.h"
////////////////////////////////////////////////////////////////////
// Class : HashGenerator
// Description : This class generates an arbitrary hash number from a
// sequence of ints.
////////////////////////////////////////////////////////////////////
class HashGenerator {
public:
HashGenerator();
void add_int(int num);
void add_string(const string &str);
long get_hash() const;
private:
long _hash;
int _index;
};
#endif

View File

@ -0,0 +1,55 @@
// Filename: primeNumberGenerator.cxx
// Created by: drose (22Mar01)
//
////////////////////////////////////////////////////////////////////
#include "primeNumberGenerator.h"
////////////////////////////////////////////////////////////////////
// Function: PrimeNumberGenerator::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
PrimeNumberGenerator::
PrimeNumberGenerator() {
_primes.push_back(2);
}
////////////////////////////////////////////////////////////////////
// Function: PrimeNumberGenerator::Indexing operator
// Access: Public
// Description: Returns the nth prime number. this[0] returns 2,
// this[1] returns 3; successively larger values of n
// return larger prime numbers, up to the largest prime
// number that can be represented in an int.
////////////////////////////////////////////////////////////////////
int PrimeNumberGenerator::
operator [] (int n) {
nassertr(n >= 0, 0);
// Compute the prime numbers between the last-computed prime number
// and n.
int candidate = _primes.back() + 1;
while ((int)_primes.size() <= n) {
// Is candidate prime? It is not if any one of the already-found
// prime numbers (up to its square root) divides it evenly.
bool maybe_prime = true;
int j = 0;
while (maybe_prime && _primes[j] * _primes[j] <= candidate) {
if ((_primes[j] * (candidate / _primes[j])) == candidate) {
// This one is not prime.
maybe_prime = false;
}
j++;
nassertr(j < (int)_primes.size(), 0)
}
if (maybe_prime) {
// Hey, we found a prime!
_primes.push_back(candidate);
}
candidate++;
}
return _primes[n];
}

View File

@ -0,0 +1,30 @@
// Filename: primeNumberGenerator.h
// Created by: drose (22Mar01)
//
////////////////////////////////////////////////////////////////////
#ifndef PRIMENUMBERGENERATOR_H
#define PRIMENUMBERGENERATOR_H
#include "dcbase.h"
////////////////////////////////////////////////////////////////////
// Class : PrimeNumberGenerator
// Description : This class generates a table of prime numbers, up to
// the limit of an int. For a given integer n, it will
// return the nth prime number. This will involve a
// recompute step only if n is greater than any previous
// n.
////////////////////////////////////////////////////////////////////
class PrimeNumberGenerator {
public:
PrimeNumberGenerator();
int operator [] (int n);
private:
typedef vector<int> Primes;
Primes _primes;
};
#endif