Created.
This commit is contained in:
parent
92bba49538
commit
bcbccb7801
|
@ -0,0 +1,61 @@
|
||||||
|
#include "borderserver.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace nxs;
|
||||||
|
|
||||||
|
void BorderServer::AddBorder(unsigned short nbord, unsigned int used) {
|
||||||
|
BorderEntry entry;
|
||||||
|
entry.border_start = Size();
|
||||||
|
entry.border_size = nbord;
|
||||||
|
entry.border_used = used;
|
||||||
|
borders.push_back(entry);
|
||||||
|
Resize(entry.border_start + nbord);
|
||||||
|
}
|
||||||
|
|
||||||
|
Border BorderServer::GetBorder(unsigned int border, bool flush) {
|
||||||
|
assert(border < borders.size());
|
||||||
|
BorderEntry &entry = borders[border];
|
||||||
|
Link *start = GetRegion(entry.border_start, entry.border_size, flush);
|
||||||
|
return Border(start, entry.border_used, entry.border_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BorderServer::ResizeBorder(unsigned int border, unsigned int nbord) {
|
||||||
|
|
||||||
|
assert(border < borders.size());
|
||||||
|
BorderEntry &entry = borders[border];
|
||||||
|
if(nbord > entry.border_size) {
|
||||||
|
unsigned int capacity = nbord;
|
||||||
|
if(capacity < entry.border_size*2)
|
||||||
|
capacity = entry.border_size * 2;
|
||||||
|
unsigned int newstart = Size();
|
||||||
|
Resize(newstart + capacity);
|
||||||
|
|
||||||
|
Link *src = GetRegion(entry.border_start, entry.border_size);
|
||||||
|
Link *dst = GetRegion(newstart, capacity, false);
|
||||||
|
memcpy(dst, src, entry.border_used * sizeof(Link));
|
||||||
|
entry.border_start = newstart;
|
||||||
|
entry.border_size = capacity;
|
||||||
|
entry.border_used = nbord;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
entry.border_used = nbord;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BorderServer::ReadEntries(FILE *fp) {
|
||||||
|
unsigned int n;
|
||||||
|
fread(&n, 1, sizeof(int), fp);
|
||||||
|
borders.resize(n);
|
||||||
|
fread(&*borders.begin(), n, sizeof(BorderEntry), fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BorderServer::WriteEntries(FILE *fp) {
|
||||||
|
unsigned int n = borders.size();
|
||||||
|
fwrite(&n, 1, sizeof(int), fp);
|
||||||
|
fwrite(&*borders.begin(), n, sizeof(BorderEntry), fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef NXS_BORDERSERVER_H
|
||||||
|
#define NXS_BORDERSERVER_H
|
||||||
|
|
||||||
|
#include "vfile.h"
|
||||||
|
#include "border.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace nxs {
|
||||||
|
|
||||||
|
struct BorderEntry {
|
||||||
|
unsigned int border_start; //granuralita' Link
|
||||||
|
unsigned short border_size; //in Links
|
||||||
|
unsigned short border_used; //in Links
|
||||||
|
};
|
||||||
|
|
||||||
|
class BorderServer: public VFile<Link> {
|
||||||
|
public:
|
||||||
|
void AddBorder(unsigned short nbord, unsigned int used = 0);
|
||||||
|
Border GetBorder(unsigned int border, bool flush = true);
|
||||||
|
//return true if you need to reread border as it changed location
|
||||||
|
bool ResizeBorder(unsigned int border, unsigned int nbord);
|
||||||
|
|
||||||
|
bool ReadEntries(FILE *fp);
|
||||||
|
bool WriteEntries(FILE *fp);
|
||||||
|
|
||||||
|
unsigned int BorderSize(unsigned int i) {
|
||||||
|
return borders[i].border_used;
|
||||||
|
}
|
||||||
|
unsigned int BorderCapacity(unsigned int i) {
|
||||||
|
return borders[i].border_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<BorderEntry> borders;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,162 @@
|
||||||
|
#include "patchserver.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace nxs;
|
||||||
|
|
||||||
|
//TODO support compression!
|
||||||
|
|
||||||
|
|
||||||
|
bool PatchServer::Create(const std::string &filename,
|
||||||
|
Signature sig,
|
||||||
|
unsigned int csize,
|
||||||
|
unsigned int rsize) {
|
||||||
|
signature = sig;
|
||||||
|
chunk_size = csize;
|
||||||
|
ram_size = rsize;
|
||||||
|
ram_used = 0;
|
||||||
|
lru.clear();
|
||||||
|
return File::Create(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PatchServer::Load(const std::string &filename, Signature sig,
|
||||||
|
unsigned int csize, bool readonly,
|
||||||
|
unsigned int rsize) {
|
||||||
|
signature = sig;
|
||||||
|
chunk_size = csize;
|
||||||
|
ram_size = rsize;
|
||||||
|
ram_used = 0;
|
||||||
|
lru.clear();
|
||||||
|
return File::Load(filename, readonly);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PatchServer::Close() {
|
||||||
|
cerr << "Closing!" << endl;
|
||||||
|
FlushAll();
|
||||||
|
File::Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO add error checking.
|
||||||
|
bool PatchServer::ReadEntries(FILE *fp) {
|
||||||
|
unsigned int n;
|
||||||
|
fread(&n, 1, sizeof(int), fp);
|
||||||
|
patches.resize(n);
|
||||||
|
for(unsigned int i = 0; i < n; i++) {
|
||||||
|
patches[i].patch = NULL;
|
||||||
|
fread(&(patches[i].patch_start), 1, sizeof(unsigned int), fp);
|
||||||
|
fread(&(patches[i].patch_size), 1, sizeof(unsigned short), fp);
|
||||||
|
fread(&(patches[i].ram_used), 1, sizeof(unsigned short), fp);
|
||||||
|
patches[i].lru_pos = 0xffffffff;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PatchServer::WriteEntries(FILE *fp) {
|
||||||
|
unsigned int n = patches.size();
|
||||||
|
fwrite(&n, 1, sizeof(int), fp);
|
||||||
|
for(unsigned int i = 0; i < patches.size(); i++) {
|
||||||
|
fwrite(&(patches[i].patch_start), 1, sizeof(unsigned int), fp);
|
||||||
|
fwrite(&(patches[i].patch_size), 1, sizeof(unsigned short), fp);
|
||||||
|
fwrite(&(patches[i].ram_used), 1, sizeof(unsigned short), fp);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PatchServer::AddPatch(unsigned short nvert, unsigned short nface) {
|
||||||
|
PatchEntry entry;
|
||||||
|
entry.patch = NULL;
|
||||||
|
entry.patch_start = Length()/chunk_size;
|
||||||
|
entry.patch_size = Patch::ChunkSize(signature, nvert, nface, chunk_size);
|
||||||
|
entry.ram_used = entry.patch_size;
|
||||||
|
entry.lru_pos = 0xffffffff;
|
||||||
|
patches.push_back(entry);
|
||||||
|
|
||||||
|
Redim(Length() + entry.patch_size * chunk_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Patch &PatchServer::GetPatch(unsigned int idx,
|
||||||
|
unsigned short nvert, unsigned short nface,
|
||||||
|
bool flush) {
|
||||||
|
|
||||||
|
assert(idx < patches.size());
|
||||||
|
PatchEntry &entry = patches[idx];
|
||||||
|
|
||||||
|
if(entry.patch) {
|
||||||
|
assert(entry.lru_pos < lru.size());
|
||||||
|
assert(lru[entry.lru_pos].patch == idx);
|
||||||
|
lru[entry.lru_pos].frame = frame++;
|
||||||
|
} else {
|
||||||
|
SetPosition(entry.patch_start * chunk_size);
|
||||||
|
|
||||||
|
assert(entry.patch_size != 0);
|
||||||
|
char *start = new char[entry.patch_size * chunk_size];
|
||||||
|
ReadBuffer(start, entry.patch_size * chunk_size);
|
||||||
|
|
||||||
|
entry.patch = new Patch(signature, start, nvert, nface);
|
||||||
|
entry.lru_pos = lru.size();
|
||||||
|
lru.push_back(PTime(idx, frame++));
|
||||||
|
ram_used += entry.ram_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
//avoid frame overflow!
|
||||||
|
if(frame > (1<<30)) {
|
||||||
|
cerr << "oVERFLOW!" << endl;;
|
||||||
|
for(unsigned int i = 0; i < lru.size(); i++) {
|
||||||
|
if(lru[i].frame < (1<<29)) lru[i].frame = 0;
|
||||||
|
else lru[i].frame -= (1<<29);
|
||||||
|
}
|
||||||
|
make_heap(lru.begin(), lru.end());
|
||||||
|
for(unsigned int i = 0; i < lru.size(); i++)
|
||||||
|
patches[lru[i].patch].lru_pos = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flush && ram_used > ram_size * 1.1)
|
||||||
|
Flush();
|
||||||
|
|
||||||
|
return *(entry.patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PatchServer::Flush() {
|
||||||
|
cerr << "FLUSHING\n\n\n n";
|
||||||
|
cerr << "ram_size: " << ram_size << endl;
|
||||||
|
cerr << "ram_used: " << ram_used << endl;
|
||||||
|
make_heap(lru.begin(), lru.end());
|
||||||
|
while(ram_used > ram_size) {
|
||||||
|
pop_heap(lru.begin(), lru.end());
|
||||||
|
PTime &ptime = lru.back();
|
||||||
|
|
||||||
|
Flush(ptime.patch);
|
||||||
|
|
||||||
|
lru.pop_back();
|
||||||
|
}
|
||||||
|
make_heap(lru.begin(), lru.end());
|
||||||
|
for(unsigned int i = 0; i < lru.size(); i++)
|
||||||
|
patches[lru[i].patch].lru_pos = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PatchServer::FlushAll() {
|
||||||
|
for(unsigned int i = 0; i < lru.size(); i++) {
|
||||||
|
PTime &ptime = lru[i];
|
||||||
|
Flush(ptime.patch);
|
||||||
|
}
|
||||||
|
assert(ram_used == 0);
|
||||||
|
lru.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PatchServer::Flush(unsigned int patch) {
|
||||||
|
|
||||||
|
PatchEntry &entry = patches[patch];
|
||||||
|
assert(entry.patch);
|
||||||
|
|
||||||
|
if(!readonly) { //write back patch
|
||||||
|
SetPosition(entry.patch_start * chunk_size);
|
||||||
|
WriteBuffer(entry.patch->start, entry.patch_size * chunk_size);
|
||||||
|
}
|
||||||
|
delete [](entry.patch->start);
|
||||||
|
delete entry.patch;
|
||||||
|
entry.patch = NULL;
|
||||||
|
entry.lru_pos = 0xffffffff;
|
||||||
|
ram_used -= entry.ram_used;
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
#ifndef NXS_PATCH_SERVER_H
|
||||||
|
#define NXS_PATCH_SERVER_H
|
||||||
|
|
||||||
|
#include "patch.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace nxs {
|
||||||
|
|
||||||
|
struct PatchEntry {
|
||||||
|
Patch *patch;
|
||||||
|
unsigned int patch_start; //granularita' Chunk
|
||||||
|
unsigned short patch_size; //in chunks
|
||||||
|
unsigned short ram_used; // in chunks (used when compressed)
|
||||||
|
unsigned int lru_pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PatchServer: public File {
|
||||||
|
public:
|
||||||
|
struct PTime {
|
||||||
|
unsigned int patch;
|
||||||
|
unsigned int frame;
|
||||||
|
|
||||||
|
PTime(unsigned int p = 0xffffffff, unsigned int f = 0xffffffff):
|
||||||
|
patch(p), frame(f) {}
|
||||||
|
|
||||||
|
bool operator<(const PTime &p) const { return frame < p.frame; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Signature signature;
|
||||||
|
unsigned int chunk_size;
|
||||||
|
unsigned int ram_size;
|
||||||
|
unsigned int ram_used;
|
||||||
|
unsigned int frame;
|
||||||
|
|
||||||
|
|
||||||
|
bool Create(const std::string &filename, Signature signature,
|
||||||
|
unsigned int chunk_size, unsigned int ram_size = 128000);
|
||||||
|
bool Load(const std::string &filename, Signature sig,
|
||||||
|
unsigned int chunk_size, bool readonly,
|
||||||
|
unsigned int ram_size = 128000);
|
||||||
|
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
bool ReadEntries(FILE *fp);
|
||||||
|
bool WriteEntries(FILE *fp);
|
||||||
|
|
||||||
|
void AddPatch(unsigned short nvert, unsigned short nface);
|
||||||
|
Patch &GetPatch(unsigned int patch, unsigned short nvert, unsigned short nface,
|
||||||
|
bool flush = true);
|
||||||
|
|
||||||
|
void Flush();
|
||||||
|
void FlushAll();
|
||||||
|
void Flush(unsigned int patch);
|
||||||
|
|
||||||
|
std::vector<PatchEntry> patches;
|
||||||
|
std::vector<PTime> lru;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue