Mastrini a video!
git-svn-id: svn://10.65.10.50/trunk@3893 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
8d5d6540be
commit
5ace216fda
287
cg/cg3600.cpp
Executable file
287
cg/cg3600.cpp
Executable file
@ -0,0 +1,287 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <array.h>
|
||||
|
||||
#include "cg3.h"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TList
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TList : public TContainer
|
||||
{
|
||||
enum { MAX_SKIP = 8192 };
|
||||
|
||||
struct TList_object : public TObject
|
||||
{
|
||||
TObject* _obj;
|
||||
TList_object* _next;
|
||||
TList_object* _prev;
|
||||
};
|
||||
|
||||
TList_object** _skip;
|
||||
long _items, _current;
|
||||
long _step, _last_skip;
|
||||
|
||||
protected:
|
||||
// @cmember Ritorna un puntatore al primo oggetto del contenitore
|
||||
virtual TObject* first_item( );
|
||||
// @cmember Ritorna un puntatore all'ultimo oggetto del contenitore
|
||||
virtual TObject* last_item( );
|
||||
// @cmember Ritorna un puntatore all'oggetto successivo all'oggetto corrente
|
||||
virtual TObject* succ_item( );
|
||||
// @cmember Ritorna un puntatore all'oggetto che precede l'oggetto corrente
|
||||
virtual TObject* pred_item( );
|
||||
// @cmember Ritorna il numero di oggetti nel contenitore
|
||||
virtual long objects( );
|
||||
|
||||
protected:
|
||||
TList_object* detach_lstobj(long index);
|
||||
TList_object* lstobjptr(long index);
|
||||
void change_step(long step);
|
||||
|
||||
public:
|
||||
|
||||
TObject* TList::objptr(long index);
|
||||
|
||||
void destroy();
|
||||
long insert(TObject* obj, long pos);
|
||||
long add(TObject* obj, long pos = -1);
|
||||
|
||||
TObject* detach(long pos);
|
||||
bool remove(long pos);
|
||||
|
||||
TList(long expected_size);
|
||||
virtual ~TList();
|
||||
};
|
||||
|
||||
TList::TList(long expected_size)
|
||||
: _items(0), _current(0)
|
||||
{
|
||||
_step = expected_size / MAX_SKIP + 1;
|
||||
_last_skip = 0;
|
||||
|
||||
_skip = new TList_object*[MAX_SKIP];
|
||||
_skip[0] = NULL;
|
||||
}
|
||||
|
||||
TList::~TList()
|
||||
{
|
||||
destroy();
|
||||
delete [] _skip;
|
||||
}
|
||||
|
||||
long TList::objects( )
|
||||
{
|
||||
return _items;
|
||||
}
|
||||
|
||||
TObject* TList::first_item()
|
||||
{
|
||||
return objptr(_current = 0);
|
||||
}
|
||||
|
||||
TObject* TList::succ_item()
|
||||
{
|
||||
return objptr(++_current);
|
||||
}
|
||||
|
||||
TObject* TList::pred_item()
|
||||
{
|
||||
return objptr(_current++);
|
||||
}
|
||||
|
||||
TObject* TList::last_item()
|
||||
{
|
||||
return objptr(_current = _items-1);
|
||||
}
|
||||
|
||||
void TList::destroy()
|
||||
{
|
||||
TList_object* head = _skip[0];
|
||||
while (head)
|
||||
{
|
||||
TList_object* next = head->_next;
|
||||
if (head->_obj)
|
||||
delete head->_obj;
|
||||
delete head;
|
||||
head = next;
|
||||
}
|
||||
_items = _current = _last_skip = 0;
|
||||
_skip[0] = NULL;
|
||||
}
|
||||
|
||||
TList::TList_object* TList::lstobjptr(long index)
|
||||
{
|
||||
TList_object* lstobj = NULL;
|
||||
const ldiv_t p = ldiv(index, _step);
|
||||
if (p.quot >= 0 && p.quot < _last_skip)
|
||||
{
|
||||
TList_object* lo = _skip[p.quot];
|
||||
for (long s = p.rem; lo && s > 0; s--)
|
||||
lo = lo->_next;
|
||||
|
||||
lstobj = lo;
|
||||
}
|
||||
return lstobj;
|
||||
}
|
||||
|
||||
TObject* TList::objptr(long index)
|
||||
{
|
||||
TList_object* lo = lstobjptr(index);
|
||||
return lo ? lo->_obj : NULL;
|
||||
}
|
||||
|
||||
void TList::change_step(long step)
|
||||
{
|
||||
CHECKD(step > 0 && step <= 16384, "Bad list step ", step);
|
||||
_step = step;
|
||||
_last_skip = 0;
|
||||
|
||||
step = 0;
|
||||
for (TList_object* lo = _skip[0]; lo; lo = lo->_next, step--)
|
||||
{
|
||||
if (step == 0)
|
||||
{
|
||||
CHECK(_last_skip < MAX_SKIP, "Too many items");
|
||||
_skip[_last_skip++] = lo;
|
||||
step = _step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long TList::insert(TObject* obj, long index)
|
||||
{
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
else
|
||||
{
|
||||
if (index > _items)
|
||||
index = _items;
|
||||
}
|
||||
const long pred = index-1;
|
||||
|
||||
TList_object* newobj = new TList_object;
|
||||
newobj->_obj = obj;
|
||||
|
||||
if (pred < 0)
|
||||
{
|
||||
newobj->_prev = NULL;
|
||||
newobj->_next = _skip[0];
|
||||
if (_skip[0])
|
||||
_skip[0]->_prev = newobj;
|
||||
}
|
||||
else
|
||||
{
|
||||
TList_object* lo = lstobjptr(pred);
|
||||
CHECK(lo, "NULL insertion point");
|
||||
newobj->_next = lo->_next;
|
||||
newobj->_prev = lo;
|
||||
if (lo->_next)
|
||||
lo->_next->_prev = newobj;
|
||||
lo->_next = newobj;
|
||||
}
|
||||
_items++;
|
||||
|
||||
ldiv_t p = ldiv(index, _step);
|
||||
if (p.rem == 0 && p.quot < MAX_SKIP) // Cambia il capolista
|
||||
_skip[p.quot] = newobj;
|
||||
|
||||
for (long i = p.quot + 1; i < _last_skip; i++)
|
||||
_skip[i] = _skip[i]->_prev; // Aggiorna capilista successivi
|
||||
|
||||
// Siamo andati oltre l'ultimo skip
|
||||
const long s = (_items - 1) / _step + 1;
|
||||
if (s > _last_skip)
|
||||
{
|
||||
if (s > MAX_SKIP)
|
||||
change_step(_step+1);
|
||||
else
|
||||
_last_skip++;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
long TList::add(TObject* obj, long index)
|
||||
{
|
||||
if (index < 0 || index >= _items)
|
||||
{
|
||||
index = insert(obj, _items);
|
||||
}
|
||||
else
|
||||
{
|
||||
TList_object* lo = lstobjptr(index);
|
||||
CHECK(lo, "NULL list object");
|
||||
delete lo->_obj;
|
||||
lo->_obj = obj;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
TList::TList_object* TList::detach_lstobj(long index)
|
||||
{
|
||||
TList_object* lo = lstobjptr(index);
|
||||
if (lo)
|
||||
{
|
||||
if (lo->_prev)
|
||||
lo->_prev->_next = lo->_next;
|
||||
if (lo->_next)
|
||||
lo->_next->_prev = lo->_prev;
|
||||
ldiv_t res = ldiv(index, _step);
|
||||
if (res.rem == 0)
|
||||
_skip[res.quot] = lo->_next;
|
||||
long p;
|
||||
for (p = res.quot + 1; p < _last_skip; p++)
|
||||
_skip[p] = _skip[p]->_next;
|
||||
|
||||
_items--;
|
||||
|
||||
p = (_items - 1) / _step + 1;
|
||||
if (p < _last_skip)
|
||||
{
|
||||
_last_skip--;
|
||||
_skip[_last_skip] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return lo;
|
||||
}
|
||||
|
||||
TObject* TList::detach(long index)
|
||||
{
|
||||
TList_object* lo = detach_lstobj(index);
|
||||
TObject* obj;
|
||||
if (lo)
|
||||
{
|
||||
obj = lo->_obj;
|
||||
delete lo;
|
||||
}
|
||||
else
|
||||
obj = NULL;
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool TList::remove(long index)
|
||||
{
|
||||
TObject* o = detach(index);
|
||||
if (o)
|
||||
delete o;
|
||||
return o != NULL;
|
||||
}
|
||||
|
||||
#include <time.h>
|
||||
|
||||
int cg3600(int argc, char* argv[])
|
||||
{
|
||||
long max = 100000L;
|
||||
TList l(max);
|
||||
const clock_t start = clock();
|
||||
|
||||
for (long i = 0; i < max; i++)
|
||||
l.add(NULL);
|
||||
|
||||
const clock_t end = clock()-start;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user