Merge branch 'hasharchive' into 'master'

Hasharchive

See merge request jschoeberl/netgen!334
This commit is contained in:
Joachim Schöberl 2020-08-29 15:16:21 +00:00
commit c0a3cd0ff9
3 changed files with 91 additions and 20 deletions

View File

@ -910,6 +910,54 @@ namespace ngcore
} }
}; };
// HashArchive =================================================================
// This class enables to easily create hashes for archivable objects by xoring
// threw its data
class NGCORE_API HashArchive : public Archive
{
size_t hash_value;
char* h;
int offset;
public:
HashArchive() : Archive(true)
{ h = (char*)&hash_value; }
using Archive::operator&;
Archive & operator & (double & d) override { return ApplyHash(d); }
Archive & operator & (int & i) override { return ApplyHash(i); }
Archive & operator & (short & i) override { return ApplyHash(i); }
Archive & operator & (long & i) override { return ApplyHash(i); }
Archive & operator & (size_t & i) override { return ApplyHash(i); }
Archive & operator & (unsigned char & i) override { return ApplyHash(i); }
Archive & operator & (bool & b) override { return ApplyHash(b); }
Archive & operator & (std::string & str) override
{ for(auto c : str) ApplyHash(c); return *this; }
Archive & operator & (char *& str) override
{ char* s = str; while(*s != '\0') ApplyHash(*(s++)); return *this; }
// HashArchive can be used in const context
template<typename T>
Archive & operator& (const T& val) const
{ return (*this) & const_cast<T&>(val); }
size_t GetHash() const { return hash_value; }
private:
template<typename T>
Archive& ApplyHash(T val)
{
auto n = sizeof(T);
char* pval = (char*)&val;
for(int i = 0; i < n; i++)
{
h[offset++] ^= pval[i];
offset %= 8;
}
return *this;
}
};
} // namespace ngcore } // namespace ngcore
#endif // NETGEN_CORE_ARCHIVE_HPP #endif // NETGEN_CORE_ARCHIVE_HPP

View File

@ -83,6 +83,18 @@ namespace ngcore
return *this; return *this;
} }
bool BitArray :: operator==(const BitArray& other) const
{
if(size != other.Size())
return false;
for(auto i : Range(size/CHAR_BIT))
if(data[i] != other.data[i])
return false;
for(auto i : Range(size%CHAR_BIT))
if(Test(i + size * (size/CHAR_BIT)) != other.Test(i + size * (size/CHAR_BIT)))
return false;
return true;
}
BitArray & BitArray :: operator= (const BitArray & ba2) BitArray & BitArray :: operator= (const BitArray & ba2)
{ {
@ -115,29 +127,39 @@ namespace ngcore
return cnt; return cnt;
} }
Archive & operator & (Archive & archive, BitArray & ba) void BitArray :: DoArchive(Archive& archive)
{
if(archive.GetVersion("netgen") >= "v6.2.2007-62")
{
archive.NeedsVersion("netgen", "v6.2.2007-62");
auto size = Size();
archive & size;
if(archive.Input())
SetSize(size);
archive.Do(data, size/CHAR_BIT+1);
}
else
{ {
if (archive.Output()) if (archive.Output())
{ {
archive << ba.Size(); throw Exception("should not get here");
for (size_t i = 0; i < ba.Size(); i++) archive << Size();
archive << ba[i]; for (size_t i = 0; i < Size(); i++)
archive << (*this)[i];
} }
else else
{ {
size_t size; size_t size;
archive & size; archive & size;
ba.SetSize (size); SetSize (size);
ba.Clear(); Clear();
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
{ {
bool b; bool b;
archive & b; archive & b;
if (b) ba.SetBit(i); if (b) SetBit(i);
} }
} }
return archive;
} }
} }
} // namespace ngcore

View File

@ -131,6 +131,7 @@ public:
return Test(i); return Test(i);
} }
NGCORE_API bool operator==(const BitArray& other) const;
/// invert all bits /// invert all bits
NGCORE_API BitArray & Invert (); NGCORE_API BitArray & Invert ();
@ -145,6 +146,9 @@ public:
NGCORE_API BitArray & operator= (const BitArray & ba2); NGCORE_API BitArray & operator= (const BitArray & ba2);
NGCORE_API size_t NumSet () const; NGCORE_API size_t NumSet () const;
NGCORE_API void DoArchive(Archive& archive);
private: private:
/// ///
unsigned char Mask (size_t i) const unsigned char Mask (size_t i) const
@ -190,11 +194,8 @@ private:
return res; return res;
} }
NGCORE_API std::ostream & operator<<(std::ostream & s, const BitArray & ba); NGCORE_API std::ostream & operator<<(std::ostream & s, const BitArray & ba);
NGCORE_API Archive & operator & (Archive & archive, BitArray & ba);
} // namespace ngcore } // namespace ngcore
#endif // NETGEN_CORE_BITARRAY #endif // NETGEN_CORE_BITARRAY