mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Core: InVector moved to Core, fixed MemoryProfile
git-svn-id: svn://ultimatepp.org/upp/trunk@5780 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
c34ed46eb7
commit
8617797a98
6 changed files with 783 additions and 3 deletions
|
|
@ -278,6 +278,7 @@ class JsonIO;
|
|||
#include "BiCont.h"
|
||||
#include "Index.h"
|
||||
#include "Map.h"
|
||||
#include "InVector.h"
|
||||
#include "Tuple.h"
|
||||
#include "Other.h"
|
||||
#include "Algo.h"
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ file
|
|||
Index.h,
|
||||
Map.h,
|
||||
Index.hpp,
|
||||
InVector.h,
|
||||
InVector.hpp,
|
||||
Tuple.h,
|
||||
Other.h,
|
||||
Hash.cpp optimize_speed,
|
||||
|
|
|
|||
184
uppsrc/Core/InVector.h
Normal file
184
uppsrc/Core/InVector.h
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
template <class T>
|
||||
class InVector : public MoveableAndDeepCopyOption< InVector<T> > {
|
||||
public:
|
||||
class ConstIterator;
|
||||
class Iterator;
|
||||
|
||||
private:
|
||||
Vector< Vector<T> > data;
|
||||
Vector< Vector<int> > index;
|
||||
int count;
|
||||
int hcount;
|
||||
int64 serial;
|
||||
int blk_high;
|
||||
int blk_low;
|
||||
|
||||
void SetCache(int blki, int offset) const;
|
||||
void ClearCache() const;
|
||||
int FindBlock0(int& pos, int& off) const;
|
||||
int FindBlock(int& pos, int& off) const;
|
||||
int FindBlock(int& pos) const;
|
||||
void Reindex();
|
||||
void SetBlkPar();
|
||||
|
||||
template <class L>
|
||||
int FindUpperBound(const T& val, const L& less, int& off, int& pos);
|
||||
|
||||
template <class L>
|
||||
int FindLowerBound(const T& val, const L& less, int& off, int& pos);
|
||||
|
||||
bool JoinSmall(int blki);
|
||||
T *Insert0(int ii, int blki, int pos, int off, const T *val);
|
||||
T *Insert0(int ii, const T *val);
|
||||
|
||||
void Reset();
|
||||
|
||||
void SetIter(ConstIterator& it, int ii);
|
||||
void SetBegin(ConstIterator& it);
|
||||
void SetEnd(ConstIterator& it);
|
||||
|
||||
void Chk() const { ASSERT_(!IsPicked(), "Broken pick semantics"); }
|
||||
|
||||
public:
|
||||
T& Insert(int i) { return *Insert0(i, NULL); }
|
||||
T& Insert(int i, const T& x) { return *Insert0(i, &x); }
|
||||
void InsertN(int i, int count);
|
||||
void Remove(int i, int count = 1);
|
||||
|
||||
const T& operator[](int i) const;
|
||||
T& operator[](int i);
|
||||
|
||||
T& Add() { return Insert(GetCount()); }
|
||||
T& Add(const T& x) { return Insert(GetCount(), x); }
|
||||
void AddN(int n) { Insert(GetCount(), n); }
|
||||
|
||||
int GetCount() const { Chk(); return count; }
|
||||
bool IsEmpty() const { return GetCount() == 0; }
|
||||
|
||||
void Trim(int n) { Remove(GetCount() - n); }
|
||||
void SetCount(int n);
|
||||
void Clear();
|
||||
|
||||
T& At(int i) { if(i >= items) SetCount(i + 1); return (*this)[i]; }
|
||||
|
||||
void Shrink();
|
||||
|
||||
void Set(int i, const T& x, int count);
|
||||
T& Set(int i, const T& x) { Set(i, x, 1); return Get(i); }
|
||||
|
||||
void Swap(int i1, int i2) { UPP::Swap((*this)[i1], (*this)[i2]); }
|
||||
|
||||
void Drop(int n = 1) { ASSERT(n <= GetCount()); Trim(GetCount() - n); }
|
||||
T& Top() { ASSERT(GetCount()); return (*this)[GetCount() - 1]; }
|
||||
const T& Top() const { ASSERT(GetCount()); return (*this)[GetCount() - 1]; }
|
||||
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>()); }
|
||||
|
||||
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>()); }
|
||||
|
||||
template <class L> int InsertUpperBound(const T& val, const L& less);
|
||||
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>()); }
|
||||
|
||||
typedef T ValueType;
|
||||
|
||||
ConstIterator Begin() const { ConstIterator it; SetBegin(it); return it; }
|
||||
ConstIterator End() const { ConstIterator it; SetEnd(it); return it; }
|
||||
ConstIterator GetIter(int pos) const { ConstIterator it; SetIter(it, pos); return it; }
|
||||
|
||||
Iterator Begin() { Iterator it; SetBegin(it); return it; }
|
||||
Iterator End() { Iterator it; SetEnd(it); return it; }
|
||||
Iterator GetIter(int pos) { Iterator it; SetIter(it, pos); return it; }
|
||||
|
||||
InVector();
|
||||
bool IsPicked() const { return data.IsPicked(); }
|
||||
|
||||
InVector(const InVector& v, int);
|
||||
|
||||
STL_VECTOR_COMPATIBILITY(InVector<T>)
|
||||
|
||||
#ifdef _DEBUG
|
||||
void DumpIndex();
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class InVector<T>::ConstIterator {
|
||||
T *ptr;
|
||||
T *begin;
|
||||
T *end;
|
||||
InVector *v;
|
||||
int offset;
|
||||
int blki;
|
||||
|
||||
friend class InVector;
|
||||
|
||||
void NextBlk();
|
||||
void PrevBlk();
|
||||
|
||||
public:
|
||||
force_inline int GetIndex() const { return ptr - begin + offset; }
|
||||
|
||||
force_inline ConstIterator& operator++() { ASSERT(ptr); if(++ptr == end) NextBlk(); return *this; }
|
||||
force_inline ConstIterator& operator--() { ASSERT(ptr); if(ptr == begin) PrevBlk(); --ptr; return *this; }
|
||||
force_inline ConstIterator operator++(int) { ConstIterator t = *this; ++*this; return t; }
|
||||
force_inline ConstIterator operator--(int) { ConstIterator t = *this; --*this; return t; }
|
||||
|
||||
force_inline ConstIterator& operator+=(int d);
|
||||
ConstIterator& operator-=(int d) { return operator+=(-d); }
|
||||
|
||||
ConstIterator operator+(int d) const { ConstIterator t = *this; t += d; return t; }
|
||||
ConstIterator operator-(int d) const { return operator+(-d); }
|
||||
|
||||
int operator-(const ConstIterator& x) const { return GetIndex() - x.GetIndex(); }
|
||||
|
||||
bool operator==(const ConstIterator& b) const { return ptr == b.ptr; }
|
||||
bool operator!=(const ConstIterator& b) const { return ptr != b.ptr; }
|
||||
bool operator<(const ConstIterator& b) const { return blki == b.blki ? ptr < b.ptr : blki < b.blki; }
|
||||
bool operator>(const ConstIterator& b) const { return blki == b.blki ? ptr > b.ptr : blki > b.blki; }
|
||||
bool operator<=(const ConstIterator& b) const { return blki == b.blki ? ptr <= b.ptr : blki <= b.blki; }
|
||||
bool operator>=(const ConstIterator& b) const { return blki == b.blki ? ptr >= b.ptr : blki >= b.blki; }
|
||||
|
||||
operator bool() const { return ptr; }
|
||||
|
||||
const T& operator*() const { return *ptr; }
|
||||
const T *operator->() const { return ptr; }
|
||||
const T& operator[](int i) const { ConstIterator h = *this; h += i; return *h; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class InVector<T>::Iterator : public InVector<T>::ConstIterator {
|
||||
typedef ConstIterator B;
|
||||
public:
|
||||
Iterator& operator++() { ConstIterator::operator++(); return *this; }
|
||||
Iterator& operator--() { ConstIterator::operator--(); return *this; }
|
||||
Iterator operator++(int) { Iterator t = *this; ++*this; return t; }
|
||||
Iterator operator--(int) { Iterator t = *this; --*this; return t; }
|
||||
|
||||
Iterator& operator+=(int d) { ConstIterator::operator+=(d); return *this; }
|
||||
Iterator& operator-=(int d) { return operator+=(-d); }
|
||||
|
||||
Iterator operator+(int d) const { Iterator t = *this; t += d; return t; }
|
||||
Iterator operator-(int d) const { return operator+(-d); }
|
||||
|
||||
int operator-(const Iterator& x) const { return B::GetIndex() - x.GetIndex(); }
|
||||
|
||||
T& operator*() { return *B::ptr; }
|
||||
T *operator->() { return B::ptr; }
|
||||
T& operator[](int i) { Iterator h = *this; h += i; return *h; }
|
||||
|
||||
const T& operator*() const { return *B::ptr; }
|
||||
const T *operator->() const { return B::ptr; }
|
||||
const T& operator[](int i) const { ConstIterator h = *this; h += i; return *h; }
|
||||
};
|
||||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
#include "InVector.hpp"
|
||||
#undef LLOG
|
||||
578
uppsrc/Core/InVector.hpp
Normal file
578
uppsrc/Core/InVector.hpp
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
int64 NewInVectorSerial();
|
||||
|
||||
template <class T>
|
||||
InVector<T>::InVector()
|
||||
{
|
||||
serial = NewInVectorSerial();
|
||||
Reset();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::Reset()
|
||||
{
|
||||
hcount = count = 0;
|
||||
SetBlkPar();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::Clear()
|
||||
{
|
||||
data.Clear();
|
||||
index.Clear();
|
||||
Reset();
|
||||
}
|
||||
|
||||
extern thread__ int64 invector_cache_serial_;
|
||||
extern thread__ int invector_cache_blki_;
|
||||
extern thread__ int invector_cache_offset_;
|
||||
extern thread__ int invector_cache_end_;
|
||||
|
||||
template <class T>
|
||||
force_inline void InVector<T>::SetCache(int blki, int offset) const
|
||||
{
|
||||
invector_cache_serial_ = serial;
|
||||
invector_cache_blki_ = blki;
|
||||
invector_cache_offset_ = offset;
|
||||
invector_cache_end_ = offset + data[blki].GetCount();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
force_inline void InVector<T>::ClearCache() const
|
||||
{
|
||||
invector_cache_serial_ = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
force_inline int InVector<T>::FindBlock(int& pos, int& off) const
|
||||
{
|
||||
Chk();
|
||||
if(invector_cache_serial_ == serial && pos >= invector_cache_offset_ &&
|
||||
pos < invector_cache_end_) {
|
||||
LLOG("Found in cache, serial: " << invector_cache_serial_ << ", offset: " << invector_cache_offset_ << ", end: " << invector_cache_end_);
|
||||
off = invector_cache_offset_;
|
||||
pos -= off;
|
||||
return invector_cache_blki_;
|
||||
}
|
||||
return FindBlock0(pos, off);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int InVector<T>::FindBlock0(int& pos, int& off) const
|
||||
{
|
||||
LLOG("FindBlock " << pos);
|
||||
ASSERT(pos >= 0 && pos <= count);
|
||||
if(pos == count) {
|
||||
LLOG("Found last");
|
||||
pos = data.Top().GetCount();
|
||||
off = count - pos;
|
||||
return data.GetCount() - 1;
|
||||
}
|
||||
int blki = 0;
|
||||
int offset = 0;
|
||||
for(int i = index.GetCount(); --i >= 0;) {
|
||||
int n = index[i][blki];
|
||||
if(pos >= n) {
|
||||
blki++;
|
||||
pos -= n;
|
||||
offset += n;
|
||||
}
|
||||
blki += blki;
|
||||
}
|
||||
int n = data[blki].GetCount();
|
||||
if(pos >= n) {
|
||||
blki++;
|
||||
pos -= n;
|
||||
offset += n;
|
||||
}
|
||||
|
||||
SetCache(blki, offset);
|
||||
|
||||
off = offset;
|
||||
return blki;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
force_inline int InVector<T>::FindBlock(int& pos) const
|
||||
{
|
||||
int h;
|
||||
return FindBlock(pos, h);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T& InVector<T>::operator[](int i) const
|
||||
{
|
||||
LLOG("operator[] " << i);
|
||||
ASSERT(i >= 0 && i < count);
|
||||
int blki = FindBlock(i);
|
||||
return data[blki][i];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T& InVector<T>::operator[](int i)
|
||||
{
|
||||
LLOG("operator[] " << i);
|
||||
ASSERT(i >= 0 && i < count);
|
||||
int blki = FindBlock(i);
|
||||
return data[blki][i];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::Reindex()
|
||||
{
|
||||
LLOG("--- Reindexing");
|
||||
ClearCache();
|
||||
SetBlkPar();
|
||||
index.Clear();
|
||||
hcount = 0;
|
||||
Vector<T> *ds = data.Begin();
|
||||
Vector<T> *dend = data.End();
|
||||
int n = data.GetCount();
|
||||
if(n <= 2)
|
||||
return;
|
||||
Vector<int>& w = index.Add();
|
||||
hcount = 2;
|
||||
w.SetCount((n + 1) >> 1);
|
||||
int *t = w.Begin();
|
||||
while(ds != dend) {
|
||||
*t = (ds++)->GetCount();
|
||||
if(ds == dend)
|
||||
break;
|
||||
*t++ += (ds++)->GetCount();
|
||||
}
|
||||
int *s = w.Begin();
|
||||
int *end = w.End();
|
||||
n = w.GetCount();
|
||||
while(n > 2) {
|
||||
Vector<int>& w = index.Add();
|
||||
hcount += hcount;
|
||||
w.SetCount((n + 1) >> 1);
|
||||
t = w.Begin();
|
||||
while(s != end) {
|
||||
*t = *s++;
|
||||
if(s == end)
|
||||
break;
|
||||
*t++ += *s++;
|
||||
}
|
||||
s = w.Begin();
|
||||
end = w.End();
|
||||
n = w.GetCount();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::SetBlkPar()
|
||||
{
|
||||
#if defined(_DEBUG) && defined(flagIVTEST)
|
||||
blk_high = 11;
|
||||
blk_low = 5;
|
||||
#else
|
||||
int n = 2500 + data.GetCount() / 4;
|
||||
blk_high = max(n / (int)sizeof(T), 16);
|
||||
blk_low = max(n / 3 / (int)sizeof(T), 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T *InVector<T>::Insert0(int ii, int blki, int pos, int off, const T *val)
|
||||
{
|
||||
if(data[blki].GetCount() > blk_high) {
|
||||
Vector<T>& x = data.Insert(blki + 1);
|
||||
x.InsertSplit(0, data[blki], data[blki].GetCount() / 2);
|
||||
Reindex();
|
||||
pos = ii;
|
||||
blki = FindBlock(pos, off);
|
||||
}
|
||||
LLOG("blki: " << blki << ", pos: " << pos);
|
||||
count++;
|
||||
int q = blki;
|
||||
for(int i = 0; i < index.GetCount(); i++)
|
||||
index[i].At(q >>= 1, 0)++;
|
||||
if(val)
|
||||
data[blki].Insert(pos, *val);
|
||||
else
|
||||
data[blki].Insert(pos);
|
||||
SetCache(blki, off);
|
||||
return &data[blki][pos];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
force_inline bool InVector<T>::JoinSmall(int blki)
|
||||
{
|
||||
if(blki < data.GetCount()) {
|
||||
int n = data[blki].GetCount();
|
||||
if(n == 0) {
|
||||
data.Remove(blki);
|
||||
return true;
|
||||
}
|
||||
if(n < blk_low) {
|
||||
if(blki > 0 && data[blki - 1].GetCount() + n <= blk_high) {
|
||||
data[blki - 1].AppendPick(data[blki]);
|
||||
data.Remove(blki);
|
||||
return true;
|
||||
}
|
||||
if(blki + 1 < data.GetCount() && n + data[blki + 1].GetCount() <= blk_high) {
|
||||
data[blki].AppendPick(data[blki + 1]);
|
||||
data.Remove(blki + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T *InVector<T>::Insert0(int ii, const T *val)
|
||||
{
|
||||
ASSERT(ii >= 0 && ii <= GetCount());
|
||||
if(data.GetCount() == 0) {
|
||||
count++;
|
||||
ClearCache();
|
||||
if(val) {
|
||||
data.Add().Add(*val);
|
||||
return &data[0][0];
|
||||
}
|
||||
return &data.Add().Insert(0);
|
||||
}
|
||||
int pos = ii;
|
||||
int off;
|
||||
int blki = FindBlock(pos, off);
|
||||
return Insert0(ii, blki, pos, off, val);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::InsertN(int ii, int n)
|
||||
{
|
||||
ASSERT(ii >= 0 && ii <= GetCount() && n >= 0);
|
||||
|
||||
if(n == 0)
|
||||
return;
|
||||
|
||||
if(data.GetCount() == 0 && n > 0) {
|
||||
count++;
|
||||
data.Add().Add();
|
||||
if(--n == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
int pos = ii;
|
||||
int off;
|
||||
int blki = FindBlock(pos, off);
|
||||
int bc = data[blki].GetCount();
|
||||
|
||||
count += n;
|
||||
|
||||
if(bc + n < blk_high) {
|
||||
data[blki].InsertN(pos, n);
|
||||
int q = blki;
|
||||
for(int i = 0; i < index.GetCount(); i++)
|
||||
index[i].At(q >>= 1, 0) += n;
|
||||
SetCache(blki, off);
|
||||
}
|
||||
else
|
||||
if(bc - pos + n < blk_high) {
|
||||
Vector<T>& t = data.Insert(blki + 1);
|
||||
t.InsertN(0, n);
|
||||
t.InsertSplit(n, data[blki], pos);
|
||||
data[blki].Shrink();
|
||||
Reindex();
|
||||
}
|
||||
else {
|
||||
int m = (blk_high + blk_low) / 2;
|
||||
int bn = (n + m - 1) / m;
|
||||
int ti;
|
||||
if(pos) {
|
||||
ti = blki + 1;
|
||||
data.InsertN(ti, bn + 1);
|
||||
data[ti + bn].InsertSplit(0, data[blki], pos);
|
||||
data[blki].Shrink();
|
||||
}
|
||||
else {
|
||||
ti = blki;
|
||||
data.InsertN(ti, bn);
|
||||
}
|
||||
for(int i = 0; i < bn; i++) {
|
||||
int q = min(m, n);
|
||||
data[ti + i].SetCount(q);
|
||||
n -= q;
|
||||
}
|
||||
ASSERT(n == 0);
|
||||
Reindex();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if(pos + n < data[blki].GetCount()) {
|
||||
data[blki].Remove(pos, n);
|
||||
if(JoinSmall(blki))
|
||||
Reindex();
|
||||
else {
|
||||
int q = blki;
|
||||
for(int i = 0; i < index.GetCount(); i++)
|
||||
index[i].At(q >>= 1, 0) -= n;
|
||||
SetCache(blki, off);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int b1 = blki;
|
||||
int nn = min(n, data[b1].GetCount() - pos);
|
||||
data[b1++].Remove(pos, nn);
|
||||
n -= nn;
|
||||
int b2 = b1;
|
||||
while(n >= data[b2].GetCount()) {
|
||||
n -= min(n, data[b2].GetCount());
|
||||
b2++;
|
||||
}
|
||||
data.Remove(b1, b2 - b1);
|
||||
data[b1].Remove(0, n);
|
||||
JoinSmall(blki + 1);
|
||||
JoinSmall(blki);
|
||||
Reindex();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::SetCount(int n)
|
||||
{
|
||||
if(n < GetCount())
|
||||
Trim(n);
|
||||
else
|
||||
Insert(GetCount(), n - GetCount());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::Shrink()
|
||||
{
|
||||
for(int i = 0; i < data.GetCount(); i++)
|
||||
data[i].Shrink();
|
||||
data.Shrink();
|
||||
for(int i = 0; i < index.GetCount(); i++)
|
||||
index[i].Shrink();
|
||||
index.Shrink();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::Set(int i, const T& x, int count)
|
||||
{
|
||||
Iterator it = GetIter(i);
|
||||
while(count-- > 0)
|
||||
*it++ = x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
InVector<T>::InVector(const InVector<T>& v, int)
|
||||
{
|
||||
data <<= v.data;
|
||||
index <<= v.index;
|
||||
count = v.count;
|
||||
hcount = v.hcount;
|
||||
blk_high = v.blk_high;
|
||||
blk_low = v.blk_low;
|
||||
serial = NewInVectorSerial();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class L>
|
||||
int InVector<T>::FindUpperBound(const T& val, const L& less, int& off, int& pos)
|
||||
{
|
||||
if(data.GetCount() == 0) {
|
||||
pos = off = 0;
|
||||
return 0;
|
||||
}
|
||||
int blki = 0;
|
||||
int ii = 0;
|
||||
int offset = 0;
|
||||
int half = hcount;
|
||||
for(int i = index.GetCount(); --i >= 0;) {
|
||||
int m = blki + half;
|
||||
if(m - 1 < data.GetCount() && !less(val, data[m - 1].Top())) {
|
||||
blki = m;
|
||||
offset += index[i][ii];
|
||||
ii++;
|
||||
}
|
||||
ii += ii;
|
||||
half >>= 1;
|
||||
}
|
||||
if(blki < data.GetCount()) {
|
||||
if(!less(val, data[blki].Top()))
|
||||
offset += data[blki++].GetCount();
|
||||
if(blki < data.GetCount()) {
|
||||
pos = Upp::FindUpperBound(data[blki], val, less);
|
||||
off = offset;
|
||||
SetCache(blki, offset);
|
||||
return blki;
|
||||
}
|
||||
}
|
||||
pos = data.Top().GetCount();
|
||||
off = count - pos;
|
||||
blki--;
|
||||
return blki;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class L>
|
||||
int InVector<T>::FindLowerBound(const T& val, const L& less, int& off, int& pos)
|
||||
{
|
||||
if(data.GetCount() == 0) {
|
||||
pos = off = 0;
|
||||
return 0;
|
||||
}
|
||||
int blki = 0;
|
||||
int ii = 0;
|
||||
int offset = 0;
|
||||
int half = hcount;
|
||||
for(int i = index.GetCount(); --i >= 0;) {
|
||||
int m = blki + half;
|
||||
if(m < data.GetCount() && less(data[m][0], val)) {
|
||||
blki = m;
|
||||
offset += index[i][ii];
|
||||
ii++;
|
||||
}
|
||||
ii += ii;
|
||||
half >>= 1;
|
||||
}
|
||||
if(blki < data.GetCount()) {
|
||||
if(blki + 1 < data.GetCount() && less(data[blki + 1][0], val))
|
||||
offset += data[blki++].GetCount();
|
||||
if(blki < data.GetCount()) {
|
||||
pos = Upp::FindLowerBound(data[blki], val, less);
|
||||
off = offset;
|
||||
SetCache(blki, offset);
|
||||
return blki;
|
||||
}
|
||||
}
|
||||
pos = data.Top().GetCount();
|
||||
off = count - pos;
|
||||
blki--;
|
||||
return blki;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class L>
|
||||
int InVector<T>::InsertUpperBound(const T& val, const L& less)
|
||||
{
|
||||
if(data.GetCount() == 0) {
|
||||
count++;
|
||||
ClearCache();
|
||||
data.Add().Insert(0) = val;
|
||||
return 0;
|
||||
}
|
||||
int off;
|
||||
int pos;
|
||||
int blki = FindUpperBound(val, less, off, pos);
|
||||
Insert0(off + pos, blki, pos, off, &val);
|
||||
return off + pos;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class L>
|
||||
int InVector<T>::Find(const T& val, const L& less)
|
||||
{
|
||||
int i = FindLowerBound(val, less);
|
||||
return i < GetCount() && !less(val, (*this)[i]) ? i : -1;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::SetIter(ConstIterator& it, int ii)
|
||||
{
|
||||
it.v = this;
|
||||
it.blki = FindBlock(ii, it.offset);
|
||||
it.begin = data[it.blki].Begin();
|
||||
it.end = data[it.blki].End();
|
||||
it.ptr = it.begin + ii;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::SetBegin(ConstIterator& it)
|
||||
{
|
||||
if(count) {
|
||||
it.v = this;
|
||||
it.blki = 0;
|
||||
it.ptr = it.begin = data[0].Begin();
|
||||
it.end = data[0].End();
|
||||
it.offset = 0;
|
||||
}
|
||||
else
|
||||
SetEnd(it);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void InVector<T>::SetEnd(ConstIterator& it)
|
||||
{
|
||||
if(count) {
|
||||
it.v = this;
|
||||
it.blki = data.GetCount() - 1;
|
||||
it.begin = data.Top().Begin();
|
||||
it.ptr = it.end = data.Top().End();
|
||||
it.offset = count - data.Top().GetCount();
|
||||
}
|
||||
else {
|
||||
it.v = this;
|
||||
it.blki = 0;
|
||||
it.ptr = it.begin = it.end = NULL;
|
||||
it.offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
force_inline typename InVector<T>::ConstIterator& InVector<T>::ConstIterator::operator+=(int d)
|
||||
{
|
||||
if(d >= 0 ? d < end - ptr : -d < ptr - begin)
|
||||
ptr += d;
|
||||
else
|
||||
v->SetIter(*this, GetIndex() + d);
|
||||
ASSERT(end - begin == v->data[blki].GetCount());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void InVector<T>::ConstIterator::NextBlk()
|
||||
{
|
||||
ASSERT(end - begin == v->data[blki].GetCount());
|
||||
if(blki + 1 < v->data.GetCount()) {
|
||||
offset += v->data[blki].GetCount();
|
||||
++blki;
|
||||
ptr = begin = v->data[blki].Begin();
|
||||
end = v->data[blki].End();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void InVector<T>::ConstIterator::PrevBlk()
|
||||
{
|
||||
--blki;
|
||||
begin = v->data[blki].Begin();
|
||||
ptr = end = v->data[blki].End();
|
||||
offset -= v->data[blki].GetCount();
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
template <class T>
|
||||
void InVector<T>::DumpIndex()
|
||||
{
|
||||
String h;
|
||||
DLOG("------- InVector dump, " << index.GetCount());
|
||||
for(int i = 0; i < data.GetCount(); i++) {
|
||||
if(i)
|
||||
h << ", ";
|
||||
h << data[i].GetCount();
|
||||
}
|
||||
DLOG(h);
|
||||
for(int j = 0; j < index.GetCount(); j++) {
|
||||
h.Clear();
|
||||
for(int k = 0; k < index[j].GetCount(); k++) {
|
||||
if(k)
|
||||
h << ", ";
|
||||
h << index[j][k];
|
||||
}
|
||||
DLOG(h);
|
||||
}
|
||||
DLOG(".");
|
||||
}
|
||||
#endif
|
||||
|
|
@ -68,4 +68,19 @@ void VectorGrowF_(void *v_, int sizeofT)
|
|||
MemoryFree(prev);
|
||||
}
|
||||
|
||||
|
||||
int64 NewInVectorSerial()
|
||||
{
|
||||
static int64 x;
|
||||
INTERLOCKED {
|
||||
++x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
thread__ int64 invector_cache_serial_;
|
||||
thread__ int invector_cache_blki_;
|
||||
thread__ int invector_cache_offset_;
|
||||
thread__ int invector_cache_end_;
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ void Heap::Make(MemoryProfile& f)
|
|||
size_t sz = ((BigHdr *)((byte *)m + BIGHDRSZ - sizeof(Header)))->size;
|
||||
f.large_count++;
|
||||
f.large_total += sz;
|
||||
if(ii < 4096)
|
||||
if(ii < 1024)
|
||||
f.large_size[ii++] = sz;
|
||||
m = m->next;
|
||||
}
|
||||
|
|
@ -211,13 +211,13 @@ void Heap::Make(MemoryProfile& f)
|
|||
if(h->free) {
|
||||
f.large_free_count++;
|
||||
f.large_free_total += h->size;
|
||||
if(fi < 4096)
|
||||
if(fi < 1024)
|
||||
f.large_free_size[fi++] = h->size;
|
||||
}
|
||||
else {
|
||||
f.large_count++;
|
||||
f.large_total += h->size;
|
||||
if(ii < 4096)
|
||||
if(ii < 1024)
|
||||
f.large_size[ii++] = h->size;
|
||||
}
|
||||
h = h->Next();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue