Warning: session_start(): open(/var/lib/php/sessions/sess_03e3vlfnlvt3l1hhmdobb1itbr, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!include once #1027304 // Eclipse Collections
// read-only, so far. not thread-safe
final sclass BufferedDiskIntMemory implements IIntMemory, AutoCloseable {
File file;
int size;
RandomAccessFile raf;
bool bigEndian = true;
bool readOnly = true;
bool debug, verboseEvictions;
long cacheSize = 128*1024*1024; // in bytes
// pageSize is in ints
int pageShift, pageSize, maxCachedPages;
new IntObjectHashMap cache;
CacheEntry newestCacheEntry, oldestCacheEntry;
// stats
int pageLoads, evictions;
sclass CacheEntry {
int page;
bool dirty;
int[] data;
CacheEntry newer, older; // MRU list
toString { ret "Page " + page; }
}
*() {
setPageSize(4096);
}
void setPageSize(int pageSizeInBytes) {
clearCache();
pageShift = 31-Int.numberOfLeadingZeros(pageSizeInBytes >> 2);
pageSize = 1 << pageShift;
maxCachedPages = (int) (cacheSize >> (pageShift+2));
}
void clearCache {
flush();
cache = new IntObjectHashMap;
newestCacheEntry = oldestCacheEntry = null;
}
*(File *file) {
this();
size = toInt_safe(fileSize(file)/4);
raf = randomAccessFileForReading(file);
}
public void close {
flush();
dispose raf;
}
void flush {
for (CacheEntry e: cache.values())
flushPage(e);
}
public int get(int idx) {
rangeCheck(idx, size);
ret loadCell(idx).data[idx & (pageSize-1)];
}
Page loadCell(int idx) {
int page = idx >> pageShift;
CacheEntry e = cache.get(page);
if (e == null) {
if (debug) print("Accessing unloaded cell " + intToHex(idx));
e = loadPage(page);
} else
touchPage(e);
ret e;
}
void touchPage(CacheEntry e) {
if (e == newestCacheEntry) ret;
if (debug) print("Touching page " + e.page + ". Older=" + e.older + ", newer=" + e.newer + ". Oldest=" + oldestCacheEntry + ", newest=" + newestCacheEntry);
// Take out of list, insert at top
if (e.older != null)
e.older.newer = e.newer; // There is an older page, point it to who was on top of us
else
oldestCacheEntry = e.newer; // We were the oldest, point it to who was on top uf os
e.newer.older = e.older; // Point who was on top of us to who was behind us (or no one)
e.newer = null; // nobody newer than us
e.older = newestCacheEntry; // point to previous newest
newestCacheEntry.newer = e; // point previous newest to us
newestCacheEntry = e; // make us the newest
if (debug) print("Touched page " + e.page + ". Older=" + e.older + ", newer=" + e.newer + ". Oldest=" + oldestCacheEntry + ", newest=" + newestCacheEntry);
}
bool cacheFull() { ret cache.size() >= maxCachedPages; }
void evictAPage {
++evictions;
CacheEntry e = oldestCacheEntry;
flushPage(e);
if (debug || verboseEvictions) print("Evicting page " + e.page);
cache.remove(e.page);
oldestCacheEntry = e.newer;
if (oldestCacheEntry == null) newestCacheEntry = null;
}
void flushPage(CacheEntry) {
if (!e.dirty) ret;
if (debug) print("Loading page " + page);
raf.seek(((long) page) << (pageShift+2));
byte[] buf = bigEndian ? intArrayToBytes(e.data) : intArrayToBytes_littleEndian(e.data);
raf.write(buf);
e.dirty = false;
}
CacheEntry loadPage(int page) ctex {
++pageLoads;
if (cacheFull()) evictAPage();
if (debug) print("Loading page " + page);
raf.seek(((long) page) << (pageShift+2));
byte[] buf = new[pageSize*4];
raf.read(buf);
new CacheEntry e;
e.page = page;
e.data = bigEndian ? intArrayFromBytes(buf) : intArrayFromBytes_littleEndian(buf);
cache.put(page, e);
// put e in front of MRU list
e.older = newestCacheEntry; // point to previous top
if (newestCacheEntry != null) // list is not empty, update "newer" pointer of current top
newestCacheEntry.newer = e;
else oldestCacheEntry = e; // otherwise, we are also the oldest entry
newestCacheEntry = e; // we are new top
if (debug) print("Loaded page " + e.page + ". Older=" + e.older + ", newer=" + e.newer + ". Oldest=" + oldestCacheEntry + ", newest=" + newestCacheEntry);
ret e;
}
public void set(int idx, int val) {
checkWriteable();
rangeCheck(idx, size);
CacheEntry e = loadCell(idx);
e.data[idx & (pageSize-1)] = val;
e.dirty = true;
}
void checkWriteable {
if (readOnly) fail("read-only");
}
public int size() {
ret size;
}
double cacheFullPercentage() {
ret percentRatio(cache.size(), maxCachedPages);
}
}