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;
|
|
|
|
return IndexFile<BorderEntry>::Create(file, 2 * sizeof(Link));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool BorderServer::Load(const string &file, bool rdonly) {
|
|
|
|
ram_used = 0;
|
|
|
|
cerr << "Loading...\n";
|
|
|
|
return IndexFile<BorderEntry>::Load(file, rdonly);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BorderServer::Close() {
|
|
|
|
if(!Opened()) return;
|
|
|
|
Flush();
|
|
|
|
IndexFile<BorderEntry>::Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2004-10-09 13:09:13 +02:00
|
|
|
void BorderServer::AddBorder(unsigned short nbord, unsigned int used) {
|
|
|
|
BorderEntry entry;
|
2005-01-14 16:25:29 +01:00
|
|
|
assert((Length() % sizeof(Link)) == 0);
|
|
|
|
|
|
|
|
entry.start = Length()/ sizeof(Link);
|
|
|
|
entry.size = nbord;
|
|
|
|
entry.used = used;
|
|
|
|
entry.links = NULL;
|
|
|
|
push_back(entry);
|
|
|
|
Redim(entry.start * sizeof(Link) + nbord * sizeof(Link));
|
2004-10-09 13:09:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Border BorderServer::GetBorder(unsigned int border, bool flush) {
|
2005-01-14 16:25:29 +01:00
|
|
|
BorderEntry &entry = operator[](border);
|
|
|
|
if(index.count(border)) {
|
|
|
|
assert(entry.links);
|
|
|
|
list<unsigned int>::iterator &i = index[border];
|
|
|
|
pqueue.erase(i);
|
|
|
|
pqueue.push_front(border);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
while(flush && ram_used > ram_max) {
|
|
|
|
unsigned int to_flush = pqueue.back();
|
|
|
|
pqueue.pop_back();
|
|
|
|
index.erase(to_flush);
|
|
|
|
FlushBorder(to_flush);
|
|
|
|
}
|
|
|
|
assert(!entry.links);
|
|
|
|
entry.links = GetRegion(entry.start, entry.size);
|
|
|
|
pqueue.push_front(border);
|
|
|
|
list<unsigned int>::iterator i = pqueue.begin();
|
|
|
|
index[border] = i;
|
|
|
|
ram_used += entry.size;
|
|
|
|
}
|
|
|
|
return Border(entry.links, entry.used, entry.size);
|
2004-10-09 13:09:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool BorderServer::ResizeBorder(unsigned int border, unsigned int nbord) {
|
2004-11-28 02:23:26 +01:00
|
|
|
assert(nbord < 65500);
|
2005-01-14 16:25:29 +01:00
|
|
|
assert(border < size());
|
|
|
|
BorderEntry &entry = operator[](border);
|
|
|
|
if(nbord > entry.size) {
|
2004-10-09 16:46:47 +02:00
|
|
|
int capacity = nbord;
|
2005-01-14 16:25:29 +01:00
|
|
|
if(capacity < entry.size*2)
|
|
|
|
capacity = entry.size * 2;
|
2004-11-28 02:23:26 +01:00
|
|
|
if(capacity > 65500)
|
|
|
|
capacity = 65500;
|
2005-01-14 16:25:29 +01:00
|
|
|
unsigned int newstart = Length()/sizeof(Link);
|
|
|
|
Redim((newstart + capacity) * sizeof(Link));
|
|
|
|
if(entry.used > 0) {
|
|
|
|
Link *src = GetRegion(entry.start, entry.size);
|
|
|
|
Link *dst = GetRegion(newstart, capacity);
|
|
|
|
memcpy(dst, src, entry.used * sizeof(Link));
|
2004-12-01 17:00:35 +01:00
|
|
|
}
|
2005-01-14 16:25:29 +01:00
|
|
|
entry.start = newstart;
|
|
|
|
entry.size = capacity;
|
|
|
|
entry.used = nbord;
|
2004-10-09 13:09:13 +02:00
|
|
|
return true;
|
|
|
|
}
|
2005-01-14 16:25:29 +01:00
|
|
|
entry.used = nbord;
|
2004-10-09 13:09:13 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2005-01-14 16:25:29 +01:00
|
|
|
void BorderServer::FlushBorder(unsigned int border) {
|
|
|
|
BorderEntry &entry = operator[](border);
|
|
|
|
assert(entry.links);
|
|
|
|
if(!MFile::IsReadOnly()) { //write back patch
|
|
|
|
MFile::SetPosition((int64)entry.start * sizeof(Link));
|
|
|
|
MFile::WriteBuffer(entry.links, entry.used * sizeof(Link));
|
|
|
|
}
|
|
|
|
|
|
|
|
delete [](entry.links);
|
|
|
|
entry.links = NULL;
|
|
|
|
ram_used -= entry.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
Link *BorderServer::GetRegion(unsigned int start, unsigned int size) {
|
|
|
|
SetPosition(start * sizeof(Link));
|
|
|
|
Link *buf = new Link[size];
|
|
|
|
assert(buf);
|
|
|
|
ReadBuffer(buf, size * sizeof(Link));
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
ReadBuffer(&offset, sizeof(int64));
|
|
|
|
cerr << "Offset: " << offset << endl;
|
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));
|
|
|
|
}
|