Roxen.git
/
server
/
etc
/
modules
/
Roxen.pmod
version
»
Context lines:
10
20
40
80
file
none
3
Roxen.git/server/etc/modules/Roxen.pmod:1:
/*
-
* $Id: Roxen.pmod,v 1.
2
1999/05/
07
23:
28
:
24
grubba Exp $
+
* $Id: Roxen.pmod,v 1.
3
1999/05/
10
23:
21
:
21
grubba Exp $
* * Various helper functions. * * Henrik Grubbström 1999-05-03 */ /* * TODO: * * o Quota: Fix support for the index file.
Roxen.git/server/etc/modules/Roxen.pmod:26:
#define LOCK() mixed key__; catch { _key = lock->lock(); } #define UNLOCK() do { if (key__) destruct(key__); } while(0) #else /* !constant(create_thread) */ #define LOCK() #define UNLOCK() #endif /* constant(create_thread) */ constant READ_BUF_SIZE = 256; constant CACHE_SIZE_LIMIT = 512;
-
object
index_file
;
+
string
base
;
+
object catalog_file; object data_file; mapping(string:int) new_entries_cache = ([]); mapping(string:object) active_objects = ([]); array(int) index; array(string) index_acc; int acc_scale;
Roxen.git/server/etc/modules/Roxen.pmod:245:
index_acc = allocate(sizeof(index)/acc_scale); QD_WRITE(sprintf("QuotaDB()::init_index_acc(): " "sizeof(index):%d, sizeof(index_acc):%d acc_scale:%d\n", sizeof(index), sizeof(index_acc), acc_scale)); } static void rebuild_index() { // FIXME: Actually make an index file.
+
array(string) new_keys = sort(indices(new_entries_cache));
+
+
int prev;
+
array(int) new_index = ({});
+
+
foreach(new_keys, string key) {
+
int lo;
+
int hi = sizeof(index_acc);
+
while(lo < hi-1) {
+
int probe = (lo + hi)/2;
+
+
if (!index_acc[probe]) {
+
object e = read_entry(index[probe * acc_scale]);
+
+
index_acc[probe] = e->name;
}
-
+
if (index_acc[probe] < key) {
+
lo = probe;
+
} else if (index_acc[probe] > key) {
+
hi = probe;
+
} else {
+
/* Found */
+
// Shouldn't happen...
+
break;
+
}
+
}
+
if (lo < hi-1) {
+
// Found...
+
// Shouldn't happen, but...
+
// Skip to the next key...
+
continue;
+
}
+
lo *= acc_scale;
+
hi *= acc_scale;
-
+
while (lo < hi-1) {
+
int probe = (lo + hi)/2;
+
object e = read_entry(index[probe]);
+
if (e->name < key) {
+
lo = probe;
+
} else if (e->name > key) {
+
hi = probe;
+
} else {
+
/* Found */
+
// Shouldn't happen...
+
break;
+
}
+
}
+
if (lo < hi-1) {
+
// Found...
+
// Shouldn't happen, but...
+
// Skip to the next key...
+
continue;
+
}
+
new_index += index[prev..lo] + ({ new_entries_cache[key] });
+
prev = hi;
+
}
+
+
LOCK();
+
+
object index_file = open(base + ".index.new", 1);
+
string to_write = sprintf("%@4c", new_index);
+
if (index_file->write(to_write) != sizeof(to_write)) {
+
index_file->close();
+
rm(base + ".index.new");
+
} else {
+
mv(base + ".index.new", base + ".index");
+
}
+
+
index = new_index;
+
init_index_acc();
+
+
UNLOCK();
+
+
foreach(new_keys, string key) {
+
m_delete(new_entries_cache, key);
+
}
+
}
+
static object low_lookup(string key) { QD_WRITE(sprintf("QuotaDB::low_lookup(%O)\n", key));
-
int
data
_offset;
+
int
cat
_offset;
-
if (!zero_type(
data
_offset = new_entries_cache[key])) {
-
return read_entry(
data
_offset);
+
if (!zero_type(
cat
_offset = new_entries_cache[key])) {
+
return read_entry(
cat
_offset);
} /* Try the index file. */ /* First use the accellerated index. */ int lo; int hi = sizeof(index_acc); while(lo < hi-1) { int probe = (lo + hi)/2;
Roxen.git/server/etc/modules/Roxen.pmod:376:
if (sizeof(new_entries_cache) > CACHE_SIZE_LIMIT) { rebuild_index(); } // low_lookup will always succeed at this point. return low_lookup(key); } void create(string base_name, int|void create_new) {
-
index_file
=
open(
base_name
+ ".index", create_new)
;
+
base
= base_name;
+
catalog_file = open(base_name + ".cat", create_new); data_file = open(base_name + ".data", create_new);
-
+
object index_file = open(base_name + ".index", 1);
#if constant(set_weak_flag) set_weak_flag(active_objects, 1); #endif /* constant(set_weak_flag) */ /* Initialize the new_entries table. */ array index_st = index_file->stat(); if (!index_st || !sizeof(index_st)) { error(sprintf("stat() failed for quota index file!\n")); }
Roxen.git/server/etc/modules/Roxen.pmod:415:
if (data_st[1] & 3) { error("quota data file has odd length!\n"); } /* Read the index, and find the last entry in the catalog file. */ int i; array(string) index_str = index_file->read()/4; index = allocate(sizeof(index_str));
-
if (sizeof(index)
*4
!=
sizeof(index_str)) {
+
if (sizeof(index
_str
)
&&
(
sizeof(index_str
[-1]
)
!= 4
)
)
{
error("Truncated read of the index file!\n"); } foreach(index_str, string offset_str) { int offset; sscanf(offset_str, "%4c", offset); index[i++] = offset; if (offset > next_offset) { next_offset = offset; }