Core: InVector fix

git-svn-id: svn://ultimatepp.org/upp/trunk@5789 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2013-02-10 20:43:56 +00:00
parent 873861b2ef
commit 3cdce8bf67
2 changed files with 64 additions and 23 deletions

View file

@ -22,10 +22,10 @@ private:
void SetBlkPar();
template <class L>
int FindUpperBound(const T& val, const L& less, int& off, int& pos);
int FindUpperBound(const T& val, const L& less, int& off, int& pos) const;
template <class L>
int FindLowerBound(const T& val, const L& less, int& off, int& pos);
int FindLowerBound(const T& val, const L& less, int& off, int& pos) const;
bool JoinSmall(int blki);
T *Insert0(int ii, int blki, int pos, int off, const T *val);
@ -39,6 +39,10 @@ private:
void Chk() const { ASSERT_(!IsPicked(), "Broken pick semantics"); }
#ifdef flagIVTEST
void Check(int blki, int offset) const;
#endif
public:
T& Insert(int i) { return *Insert0(i, NULL); }
T& Insert(int i, const T& x) { return *Insert0(i, &x); }
@ -74,20 +78,20 @@ public:
T Pop() { T h = Top(); Drop(); return h; }
template <class L>
int FindUpperBound(const T& val, const L& less) { int off, pos; FindUpperBound(val, less, off, pos); return off + pos; }
int FindUpperBound(const T& val) { return FindUpperBound(val, StdLess<T>()); }
int FindUpperBound(const T& val, const L& less) const { int off, pos; FindUpperBound(val, less, off, pos); return off + pos; }
int FindUpperBound(const T& val) const { return FindUpperBound(val, StdLess<T>()); }
template <class L>
int FindLowerBound(const T& val, const L& less) { int off, pos; FindLowerBound(val, less, off, pos); return off + pos; }
int FindLowerBound(const T& val) { return FindLowerBound(val, StdLess<T>()); }
int FindLowerBound(const T& val, const L& less) const { int off, pos; FindLowerBound(val, less, off, pos); return off + pos; }
int FindLowerBound(const T& val) const { return FindLowerBound(val, StdLess<T>()); }
template <class L>
int InsertUpperBound(const T& val, const L& less);
int InsertUpperBound(const T& val) { return InsertUpperBound(val, StdLess<T>()); }
int InsertUpperBound(const T& val) { return InsertUpperBound(val, StdLess<T>()); }
template <class L>
int Find(const T& val, const L& less);
int Find(const T& val) { return Find(val, StdLess<T>()); }
int Find(const T& val, const L& less) const;
int Find(const T& val) const { return Find(val, StdLess<T>()); }
typedef T ValueType;
@ -264,20 +268,20 @@ public:
T Pop() { T h = Top(); Drop(); return h; }
template <class L>
int FindUpperBound(const T& val, const L& less) { return iv.FindUpperBound((T*)&val, ALess<L>(less)); }
int FindUpperBound(const T& val) { return FindUpperBound(val, StdLess<T>()); }
int FindUpperBound(const T& val, const L& less) const { return iv.FindUpperBound((T*)&val, ALess<L>(less)); }
int FindUpperBound(const T& val) const { return FindUpperBound(val, StdLess<T>()); }
template <class L>
int FindLowerBound(const T& val, const L& less) { return iv.FindLowerBound((T*)&val, ALess<L>(less)); }
int FindLowerBound(const T& val) { return FindLowerBound(val, StdLess<T>()); }
int FindLowerBound(const T& val, const L& less) const { return iv.FindLowerBound((T*)&val, ALess<L>(less)); }
int FindLowerBound(const T& val) const { return FindLowerBound(val, StdLess<T>()); }
template <class L>
int InsertUpperBound(const T& val, const L& lss){ return iv.InsertUpperBound(new T(val), ALess<L>(lss)); }
int InsertUpperBound(const T& val) { return InsertUpperBound(val, StdLess<T>()); }
int InsertUpperBound(const T& val, const L& lss) { return iv.InsertUpperBound(new T(val), ALess<L>(lss)); }
int InsertUpperBound(const T& val) { return InsertUpperBound(val, StdLess<T>()); }
template <class L>
int Find(const T& val, const L& less) { return iv.Find((T*)&val, ALess<L>(less)); }
int Find(const T& val) { return Find(val, StdLess<T>()); }
int Find(const T& val, const L& less) const { return iv.Find((T*)&val, ALess<L>(less)); }
int Find(const T& val) const { return Find(val, StdLess<T>()); }
typedef T ValueType;

View file

@ -31,6 +31,9 @@ extern thread__ int invector_cache_end_;
template <class T>
force_inline void InVector<T>::SetCache(int blki, int offset) const
{
#ifdef flagIVTEST
Check(0, 0);
#endif
invector_cache_serial_ = serial;
invector_cache_blki_ = blki;
invector_cache_offset_ = offset;
@ -158,6 +161,9 @@ void InVector<T>::Reindex()
end = w.End();
n = w.GetCount();
}
#ifdef flagIVTEST
Check(0, 0);
#endif
}
template <class T>
@ -299,15 +305,18 @@ void InVector<T>::InsertN(int ii, int n)
ASSERT(n == 0);
Reindex();
}
#ifdef flagIVTEST
Check(0, 0);
#endif
}
template <class T>
void InVector<T>::Remove(int pos, int n)
{
ASSERT(pos >= 0 && pos + n <= GetCount());
count -= n;
int off;
int blki = FindBlock(pos, off);
count -= n;
if(pos + n < data[blki].GetCount()) {
data[blki].Remove(pos, n);
if(JoinSmall(blki))
@ -325,16 +334,20 @@ void InVector<T>::Remove(int pos, int n)
data[b1++].Remove(pos, nn);
n -= nn;
int b2 = b1;
while(n >= data[b2].GetCount()) {
while(b2 < data.GetCount() && n >= data[b2].GetCount()) {
n -= min(n, data[b2].GetCount());
b2++;
}
data.Remove(b1, b2 - b1);
data[b1].Remove(0, n);
if(b1 < data.GetCount())
data[b1].Remove(0, n);
JoinSmall(blki + 1);
JoinSmall(blki);
Reindex();
}
#ifdef flagIVTEST
Check(0, 0);
#endif
}
template <class T>
@ -379,7 +392,7 @@ InVector<T>::InVector(const InVector<T>& v, int)
template <class T>
template <class L>
int InVector<T>::FindUpperBound(const T& val, const L& less, int& off, int& pos)
int InVector<T>::FindUpperBound(const T& val, const L& less, int& off, int& pos) const
{
if(data.GetCount() == 0) {
pos = off = 0;
@ -399,6 +412,9 @@ int InVector<T>::FindUpperBound(const T& val, const L& less, int& off, int& pos)
ii += ii;
half >>= 1;
}
#ifdef flagIVTEST
Check(blki, offset);
#endif
if(blki < data.GetCount()) {
if(!less(val, data[blki].Top()))
offset += data[blki++].GetCount();
@ -412,12 +428,13 @@ int InVector<T>::FindUpperBound(const T& val, const L& less, int& off, int& pos)
pos = data.Top().GetCount();
off = count - pos;
blki--;
SetCache(blki, off);
return blki;
}
template <class T>
template <class L>
int InVector<T>::FindLowerBound(const T& val, const L& less, int& off, int& pos)
int InVector<T>::FindLowerBound(const T& val, const L& less, int& off, int& pos) const
{
if(data.GetCount() == 0) {
pos = off = 0;
@ -437,6 +454,9 @@ int InVector<T>::FindLowerBound(const T& val, const L& less, int& off, int& pos)
ii += ii;
half >>= 1;
}
#ifdef flagIVTEST
Check(blki, offset);
#endif
if(blki < data.GetCount()) {
if(blki + 1 < data.GetCount() && less(data[blki + 1][0], val))
offset += data[blki++].GetCount();
@ -450,6 +470,7 @@ int InVector<T>::FindLowerBound(const T& val, const L& less, int& off, int& pos)
pos = data.Top().GetCount();
off = count - pos;
blki--;
SetCache(blki, off);
return blki;
}
@ -472,7 +493,7 @@ int InVector<T>::InsertUpperBound(const T& val, const L& less)
template <class T>
template <class L>
int InVector<T>::Find(const T& val, const L& less)
int InVector<T>::Find(const T& val, const L& less) const
{
int i = FindLowerBound(val, less);
return i < GetCount() && !less(val, (*this)[i]) ? i : -1;
@ -594,6 +615,22 @@ void InVector<T>::DumpIndex()
}
#endif
#ifdef flagIVTEST
template <class T>
void InVector<T>::Check(int blki, int offset) const
{
int off = 0;
int all = 0;
for(int i = 0; i < data.GetCount(); i++) {
if(i < blki)
off += data[i].GetCount();
all += data[i].GetCount();
}
ASSERT(off == offset);
ASSERT(all == count);
}
#endif
template <class T>
void InArray<T>::Delete(IVIter it, int count)
{