vcglib/apps/nexus/borderserver.cpp

140 lines
3.8 KiB
C++
Raw Normal View History

2004-10-09 13:09:13 +02:00
#include "borderserver.h"
#include <iostream>
using namespace std;
using namespace nxs;
2005-01-14 16:25:29 +01:00
bool BorderServer::Create(const string &file) {
ram_used = 0;
2005-01-21 18:09:13 +01:00
return IndexFile<Border>::Create(file, 2 * sizeof(Link));
2005-01-14 16:25:29 +01:00
}
bool BorderServer::Load(const string &file, bool rdonly) {
2005-01-21 18:09:13 +01:00
ram_used = 0;
bool success = IndexFile<Border>::Load(file, rdonly);
if(!success) return false;
for(unsigned int i = 0; i < size(); i++)
operator[](i).links = NULL;
return true;
2005-01-14 16:25:29 +01:00
}
void BorderServer::Close() {
if(!Opened()) return;
Flush();
2005-01-21 18:09:13 +01:00
IndexFile<Border>::Close();
2005-01-14 16:25:29 +01:00
}
void BorderServer::Flush() {
std::map<unsigned int, list<unsigned int>::iterator>::iterator i;
for(i = index.begin(); i != index.end(); i++) {
unsigned int patch = (*i).first;
FlushBorder(patch);
}
pqueue.clear();
index.clear();
}
2005-01-21 18:09:13 +01:00
void BorderServer::AddBorder(unsigned short _size, unsigned int used) {
Border entry;
2005-01-14 16:25:29 +01:00
assert((Length() % sizeof(Link)) == 0);
entry.start = Length()/ sizeof(Link);
2005-01-21 18:09:13 +01:00
entry.size = _size;
2005-01-14 16:25:29 +01:00
entry.used = used;
entry.links = NULL;
push_back(entry);
2005-01-25 16:40:33 +01:00
Redim((int64)entry.start * (int64)sizeof(Link) + (int64)_size * (int64)sizeof(Link));
2004-10-09 13:09:13 +02:00
}
2005-01-21 18:09:13 +01:00
Border &BorderServer::GetBorder(unsigned int border, bool flush) {
Border &entry = operator[](border);
2005-01-18 23:24:23 +01:00
//assert(entry.size != 0);
2005-01-14 16:25:29 +01:00
if(index.count(border)) {
2005-01-18 23:24:23 +01:00
//assert(entry.links);
list<unsigned int>::iterator i = index[border];
2005-01-14 16:25:29 +01:00
pqueue.erase(i);
pqueue.push_front(border);
2005-01-18 23:24:23 +01:00
index[border] = pqueue.begin();
2005-01-14 16:25:29 +01:00
} else {
2005-01-18 23:24:23 +01:00
while(flush && ram_used > ram_max) {
assert(pqueue.size());
2005-01-14 16:25:29 +01:00
unsigned int to_flush = pqueue.back();
pqueue.pop_back();
index.erase(to_flush);
FlushBorder(to_flush);
2005-01-21 18:09:13 +01:00
}
entry.links = GetRegion(entry.start, entry.size);
2005-01-18 23:24:23 +01:00
pqueue.push_front(border);
index[border] = pqueue.begin();
2005-01-14 16:25:29 +01:00
ram_used += entry.size;
}
2005-01-21 18:09:13 +01:00
return entry;
2004-10-09 13:09:13 +02:00
}
2005-01-18 23:24:23 +01:00
//TODO Change when remving borderentry class.
2005-01-21 18:09:13 +01:00
void BorderServer::ResizeBorder(unsigned int border, unsigned int used) {
assert(border < size());
Border &entry = GetBorder(border);
if(used <= entry.size) {
entry.used = used;
return;
}
int capacity = used;
if(capacity < entry.size * 2)
capacity = entry.size * 2;
unsigned int newstart = Length()/sizeof(Link);
2005-01-25 16:40:33 +01:00
Redim((int64)(newstart + capacity) * (int64)sizeof(Link));
2005-01-21 18:09:13 +01:00
Link *newlinks = new Link[capacity];
if(entry.used > 0) {
assert(entry.links);
memcpy(newlinks, entry.links, entry.used * sizeof(Link));
delete []entry.links;
entry.links = NULL;
2004-10-09 13:09:13 +02:00
}
2005-01-21 18:09:13 +01:00
assert(entry.links == NULL);
entry.links = newlinks;
entry.start = newstart;
entry.size = capacity;
entry.used = used;
2004-10-09 13:09:13 +02:00
}
2005-01-14 16:25:29 +01:00
void BorderServer::FlushBorder(unsigned int border) {
2005-01-21 18:09:13 +01:00
Border &entry = operator[](border);
2005-01-18 23:24:23 +01:00
//assert(entry.links);
if(entry.size && !MFile::IsReadOnly()) { //write back patch
2005-01-25 16:40:33 +01:00
MFile::SetPosition((int64)entry.start * (int64)sizeof(Link));
MFile::WriteBuffer(entry.links, entry.used * (int64)sizeof(Link));
2005-01-14 16:25:29 +01:00
}
2005-01-21 18:09:13 +01:00
if(entry.links)
2005-01-18 23:24:23 +01:00
delete [](entry.links);
2005-01-14 16:25:29 +01:00
entry.links = NULL;
ram_used -= entry.size;
}
Link *BorderServer::GetRegion(unsigned int start, unsigned int size) {
2005-01-21 18:09:13 +01:00
if(size == 0) return NULL;
2005-01-25 16:40:33 +01:00
SetPosition((int64)start * (int64)sizeof(Link));
2005-01-14 16:25:29 +01:00
Link *buf = new Link[size];
assert(buf);
2005-01-25 16:40:33 +01:00
ReadBuffer(buf, (int64)size * (int64)sizeof(Link));
2005-01-14 16:25:29 +01:00
return buf;
2004-10-09 13:09:13 +02:00
}
2005-01-14 16:25:29 +01:00
bool BorderServer::LoadHeader() {
unsigned int magic;
ReadBuffer(&magic, sizeof(unsigned int));
if(magic != 0x3042584e) { //NXB0
cerr << "Invalid magic. Not a nxs file\n";
return false;
}
2005-01-24 16:45:00 +01:00
ReadBuffer(&offset, sizeof(int64));
2004-10-09 13:09:13 +02:00
return true;
}
2005-01-14 16:25:29 +01:00
void BorderServer::SaveHeader() {
unsigned int magic = 0x3042584e; // NXB0
WriteBuffer(&magic, sizeof(unsigned int));
WriteBuffer(&offset, sizeof(int64));
}