forked from Mirrors/openclonk
Reduce the copies C4Set makes
Mostly by changing functions to take a const reference, but also by using move constructors. This helps with C4String leak debugging by reducing the reference count changes.floating-point
parent
576edc1e23
commit
91a6c309a9
|
@ -392,7 +392,7 @@ C4Effect * C4PropList::GetEffect()
|
|||
|
||||
|
||||
template<> template<>
|
||||
unsigned int C4Set<C4Property>::Hash<C4String *>(C4String * e)
|
||||
unsigned int C4Set<C4Property>::Hash<C4String *>(C4String * const & e)
|
||||
{
|
||||
assert(e);
|
||||
unsigned int hash = 4, tmp;
|
||||
|
@ -411,13 +411,13 @@ unsigned int C4Set<C4Property>::Hash<C4String *>(C4String * e)
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
bool C4Set<C4Property>::Equals<C4String *>(C4Property a, C4String * b)
|
||||
bool C4Set<C4Property>::Equals<C4String *>(C4Property const & a, C4String * const & b)
|
||||
{
|
||||
return a.Key == b;
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
unsigned int C4Set<C4Property>::Hash<C4Property>(C4Property p)
|
||||
unsigned int C4Set<C4Property>::Hash<C4Property>(C4Property const & p)
|
||||
{
|
||||
return C4Set<C4Property>::Hash(p.Key);
|
||||
}
|
||||
|
@ -589,8 +589,9 @@ void C4PropList::SetPropertyByS(C4String * k, const C4Value & to)
|
|||
}
|
||||
else
|
||||
{
|
||||
C4Property p(k, to);
|
||||
Properties.Add(p);
|
||||
//C4Property p(k, to);
|
||||
//Properties.Add(p);
|
||||
Properties.Add(C4Property(k, to));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -600,7 +601,7 @@ void C4PropList::ResetProperty(C4String * k)
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
unsigned int C4Set<C4PropListNumbered *>::Hash<int>(int e)
|
||||
unsigned int C4Set<C4PropListNumbered *>::Hash<int>(int const & e)
|
||||
{
|
||||
unsigned int hash = 4, tmp;
|
||||
hash += e >> 16;
|
||||
|
@ -617,31 +618,31 @@ unsigned int C4Set<C4PropListNumbered *>::Hash<int>(int e)
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
unsigned int C4Set<C4PropListNumbered *>::Hash<C4PropList *>(C4PropList * e)
|
||||
unsigned int C4Set<C4PropListNumbered *>::Hash<C4PropList *>(C4PropList * const & e)
|
||||
{
|
||||
return Hash(e->GetPropListNumbered()->Number);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
unsigned int C4Set<C4PropListNumbered *>::Hash<C4PropListNumbered *>(C4PropListNumbered * e)
|
||||
unsigned int C4Set<C4PropListNumbered *>::Hash<C4PropListNumbered *>(C4PropListNumbered * const & e)
|
||||
{
|
||||
return Hash(e->Number);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
bool C4Set<C4PropListNumbered *>::Equals<int>(C4PropListNumbered * a, int b)
|
||||
bool C4Set<C4PropListNumbered *>::Equals<int>(C4PropListNumbered * const & a, int const & b)
|
||||
{
|
||||
return a->Number == b;
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
bool C4Set<C4PropListNumbered *>::Equals<C4PropList *>(C4PropListNumbered * a, C4PropList * b)
|
||||
bool C4Set<C4PropListNumbered *>::Equals<C4PropList *>(C4PropListNumbered * const & a, C4PropList * const & b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
unsigned int C4Set<C4PropList *>::Hash<C4PropList *>(C4PropList * e)
|
||||
unsigned int C4Set<C4PropList *>::Hash<C4PropList *>(C4PropList * const & e)
|
||||
{
|
||||
return C4Set<C4PropListNumbered *>::Hash(static_cast<int>(reinterpret_cast<intptr_t>(e)));
|
||||
}
|
||||
|
|
|
@ -38,6 +38,11 @@ public:
|
|||
C4Property(const C4Property &o) : Key(o.Key), Value(o.Value) { if (Key) Key->IncRef(); }
|
||||
C4Property & operator = (const C4Property &o)
|
||||
{ assert(o.Key); o.Key->IncRef(); if (Key) Key->DecRef(); Key = o.Key; Value = o.Value; return *this; }
|
||||
#ifdef HAVE_RVALUE_REF
|
||||
C4Property(C4Property && o) : Key(o.Key), Value(std::move(o.Value)) { o.Key = 0; }
|
||||
C4Property & operator = (C4Property && o)
|
||||
{ assert(o.Key); if (Key) Key->DecRef(); Key = o.Key; o.Key = 0; Value = std::move(o.Value); return *this; }
|
||||
#endif
|
||||
~C4Property() { if (Key) Key->DecRef(); }
|
||||
void CompileFunc(StdCompiler *pComp, C4ValueNumbers *);
|
||||
C4String * Key;
|
||||
|
|
|
@ -24,17 +24,18 @@
|
|||
|
||||
// *** C4Set
|
||||
template<> template<>
|
||||
unsigned int C4Set<C4String *>::Hash<const char *>(const char * s)
|
||||
unsigned int C4Set<C4String *>::Hash<const char *>(const char * const & s)
|
||||
{
|
||||
// Fowler/Noll/Vo hash
|
||||
unsigned int h = 2166136261u;
|
||||
while (*s)
|
||||
h = (h ^ *(s++)) * 16777619;
|
||||
const char * p = s;
|
||||
while (*p)
|
||||
h = (h ^ *(p++)) * 16777619;
|
||||
return h;
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
bool C4Set<C4String *>::Equals<const char *>(C4String * a, const char * b)
|
||||
bool C4Set<C4String *>::Equals<const char *>(C4String * const & a, const char * const & b)
|
||||
{
|
||||
return a->GetData() == b;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ template<typename T> class C4Set
|
|||
unsigned int Capacity;
|
||||
unsigned int Size;
|
||||
T * Table;
|
||||
T * AddInternal(T e)
|
||||
T * GetPlaceFor(T const & e)
|
||||
{
|
||||
unsigned int h = Hash(e);
|
||||
T * p = &Table[h % Capacity];
|
||||
|
@ -112,13 +112,43 @@ template<typename T> class C4Set
|
|||
{
|
||||
p = &Table[++h % Capacity];
|
||||
}
|
||||
return p;
|
||||
}
|
||||
T * AddInternal(T const & e)
|
||||
{
|
||||
T * p = GetPlaceFor(e);
|
||||
*p = e;
|
||||
return p;
|
||||
}
|
||||
#ifdef HAVE_RVALUE_REF
|
||||
T * AddInternal(T && e)
|
||||
{
|
||||
T * p = GetPlaceFor(e);
|
||||
*p = std::move(e);
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
void MaintainCapacity()
|
||||
{
|
||||
if (Capacity - Size < Max(2u, Capacity / 4))
|
||||
{
|
||||
unsigned int OCapacity = Capacity;
|
||||
Capacity *= 2;
|
||||
T * OTable = Table;
|
||||
Table = new T[Capacity];
|
||||
Clear();
|
||||
for (unsigned int i = 0; i < OCapacity; ++i)
|
||||
{
|
||||
if (OTable[i])
|
||||
AddInternal(std::move(OTable[i]));
|
||||
}
|
||||
delete [] OTable;
|
||||
}
|
||||
}
|
||||
public:
|
||||
template<typename H> static unsigned int Hash(H);
|
||||
template<typename H> static bool Equals(T, H);
|
||||
static bool Equals(T a, T b) { return a == b; }
|
||||
template<typename H> static unsigned int Hash(const H &);
|
||||
template<typename H> static bool Equals(const T &, const H &);
|
||||
static bool Equals(const T & a, const T & b) { return a == b; }
|
||||
C4Set(): Capacity(2), Size(0), Table(new T[Capacity])
|
||||
{
|
||||
Clear();
|
||||
|
@ -167,26 +197,22 @@ public:
|
|||
return !!*r;
|
||||
}
|
||||
unsigned int GetSize() const { return Size; }
|
||||
T * Add(T e)
|
||||
T * Add(T const & e)
|
||||
{
|
||||
if (Capacity - Size < Max(2u, Capacity / 4))
|
||||
{
|
||||
unsigned int OCapacity = Capacity;
|
||||
Capacity *= 2;
|
||||
T * OTable = Table;
|
||||
Table = new T[Capacity];
|
||||
Clear();
|
||||
for (unsigned int i = 0; i < OCapacity; ++i)
|
||||
{
|
||||
if (OTable[i])
|
||||
AddInternal(OTable[i]);
|
||||
}
|
||||
delete [] OTable;
|
||||
}
|
||||
MaintainCapacity();
|
||||
T * r = AddInternal(e);
|
||||
++Size;
|
||||
return r;
|
||||
}
|
||||
#ifdef HAVE_RVALUE_REF
|
||||
T * Add(T && e)
|
||||
{
|
||||
MaintainCapacity();
|
||||
T * r = AddInternal(std::move(e));
|
||||
++Size;
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
template<typename H> void Remove(H e)
|
||||
{
|
||||
unsigned int h = Hash(e);
|
||||
|
@ -203,7 +229,7 @@ public:
|
|||
{
|
||||
T m = *r;
|
||||
*r = 0;
|
||||
AddInternal(m);
|
||||
AddInternal(std::move(m));
|
||||
}
|
||||
}
|
||||
T const * First() const { return Next(Table - 1); }
|
||||
|
@ -230,12 +256,12 @@ public:
|
|||
};
|
||||
|
||||
template<> template<>
|
||||
inline unsigned int C4Set<C4String *>::Hash<const C4String *>(const C4String * e)
|
||||
inline unsigned int C4Set<C4String *>::Hash<const C4String *>(const C4String * const & e)
|
||||
{
|
||||
return e->Hash;
|
||||
}
|
||||
template<> template<>
|
||||
inline unsigned int C4Set<C4String *>::Hash<C4String *>(C4String * e)
|
||||
inline unsigned int C4Set<C4String *>::Hash<C4String *>(C4String * const & e)
|
||||
{
|
||||
return e->Hash;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue