Read-only was a bit of a misnomer: you could write to the table by
obtaining a pointer into it from ef_ptr(), you just couldn't write to
the backing file.
Semantic changes:
* ef_flush() is now allowed when the table is file-backed or privately
mapped. Before, it had to be file-backed. Flushing a privately
mapped table does nothing, just like flushing a read-only table did.
* ef_write() is now allowed when the table is file-backed or fully
cached. Before, it had to be file-backed and not read-only.
Writing to a privately mapped file-backed table doesn't write to the
file.
* ef_extend() is not implemented for privately mapped tables, just
like it wasn't implemented for read-only tables.
int cids; /* # entries in cache */
int fids; /* # entries in table */
int fd; /* file descriptor, -1 if not open */
int cids; /* # entries in cache */
int fids; /* # entries in table */
int fd; /* file descriptor, -1 if not open */
- /* flags bits EFF_RDONLY, EFF_CUSTOM also vary */
+ /* flags bits EFF_PRIVATE, EFF_CUSTOM also vary */
/* User callbacks */
void (*init)(int, void *); /* called after entry creation, unless null */
/* User callbacks */
void (*init)(int, void *); /* called after entry creation, unless null */
/* Flags set when table contents is mapped */
/* Table is entirely in memory */
#define EFF_MEM bit(8)
/* Flags set when table contents is mapped */
/* Table is entirely in memory */
#define EFF_MEM bit(8)
-/* Table is read-only */
-#define EFF_RDONLY bit(9)
+/* Table is privately mapped: changes don't affect the underlying file */
+#define EFF_PRIVATE bit(9)
/* Table is customized (configuration tables only) */
#define EFF_CUSTOM bit(10)
/* Transient flags, only occur in argument of ef_open() */
/* Table is customized (configuration tables only) */
#define EFF_CUSTOM bit(10)
/* Transient flags, only occur in argument of ef_open() */
/*
* Empire `file types'
* These are really table IDs. Some tables are backed by files, some
/*
* Empire `file types'
* These are really table IDs. Some tables are backed by files, some
- * are compiled into the server.
+ * are compiled into the server, some initialized from configuration
+ * files.
*/
enum {
/* Error value */
*/
enum {
/* Error value */
if (CANT_HAPPEN(ep->fd >= 0))
return 0;
oflags = O_RDWR;
if (CANT_HAPPEN(ep->fd >= 0))
return 0;
oflags = O_RDWR;
oflags = O_RDONLY;
if (how & EFF_CREATE)
oflags |= O_CREAT | O_TRUNC;
oflags = O_RDONLY;
if (how & EFF_CREATE)
oflags |= O_CREAT | O_TRUNC;
- lock.l_type = how & EFF_RDONLY ? F_RDLCK : F_WRLCK;
+ lock.l_type = how & EFF_PRIVATE ? F_RDLCK : F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = lock.l_len = 0;
if (fcntl(fd, F_SETLK, &lock) == -1) {
lock.l_whence = SEEK_SET;
lock.l_start = lock.l_len = 0;
if (fcntl(fd, F_SETLK, &lock) == -1) {
- * Flush file-backed table TYPE (EF_SECTOR, ...) to disk.
+ * Flush table TYPE (EF_SECTOR, ...) to disk.
+ * Does nothing if the table is privately mapped.
* Return non-zero on success, zero on failure.
*/
int
* Return non-zero on success, zero on failure.
*/
int
if (ef_check(type) < 0)
return 0;
ep = &empfile[type];
if (ef_check(type) < 0)
return 0;
ep = &empfile[type];
+ if (ep->flags & EFF_PRIVATE)
+ return 1; /* nothing to do */
if (CANT_HAPPEN(ep->fd < 0))
return 0;
/*
if (CANT_HAPPEN(ep->fd < 0))
return 0;
/*
* allowed only with EFF_MEM. Assume the whole cash is dirty
* then.
*/
* allowed only with EFF_MEM. Assume the whole cash is dirty
* then.
*/
- if (!(ep->flags & EFF_RDONLY) && (ep->flags & EFF_MEM))
+ if (ep->flags & EFF_MEM)
return do_write(ep, ep->cache, ep->baseid, ep->cids) >= 0;
return 1;
return do_write(ep, ep->cache, ep->baseid, ep->cids) >= 0;
return 1;
- if (CANT_HAPPEN(ep->fd < 0 || id < 0 || count < 0))
+ if (CANT_HAPPEN(ep->fd < 0 || (ep->flags & EFF_PRIVATE)
+ || id < 0 || count < 0))
return -1;
if (lseek(ep->fd, id * ep->size, SEEK_SET) == (off_t)-1) {
return -1;
if (lseek(ep->fd, id * ep->size, SEEK_SET) == (off_t)-1) {
- * Write element ID into file-backed table TYPE from buffer FROM.
+ * Write element ID into table TYPE from buffer FROM.
* FIXME pass buffer size!
* FIXME pass buffer size!
- * Write through cache straight to disk.
+ * If table is file-backed and not privately mapped, write through
+ * cache straight to disk.
* Cannot write beyond the end of fully cached table (flags & EFF_MEM).
* Can write at the end of partially cached table.
* Return non-zero on success, zero on failure.
* Cannot write beyond the end of fully cached table (flags & EFF_MEM).
* Can write at the end of partially cached table.
* Return non-zero on success, zero on failure.
if (ef_check(type) < 0)
return 0;
ep = &empfile[type];
if (ef_check(type) < 0)
return 0;
ep = &empfile[type];
+ if (CANT_HAPPEN((ep->flags & (EFF_MEM | EFF_PRIVATE)) == EFF_PRIVATE))
+ return 0;
if (ep->prewrite)
ep->prewrite(id, from);
if (CANT_HAPPEN((ep->flags & EFF_MEM) ? id >= ep->fids : id > ep->fids))
return 0; /* not implemented */
if (ep->prewrite)
ep->prewrite(id, from);
if (CANT_HAPPEN((ep->flags & EFF_MEM) ? id >= ep->fids : id > ep->fids))
return 0; /* not implemented */
- if (do_write(ep, from, id, 1) < 0)
- return 0;
+ if (!(ep->flags & EFF_PRIVATE)) {
+ if (do_write(ep, from, id, 1) < 0)
+ return 0;
+ }
if (id >= ep->baseid && id < ep->baseid + ep->cids) {
/* update the cache if necessary */
to = ep->cache + (id - ep->baseid) * ep->size;
if (id >= ep->baseid && id < ep->baseid + ep->cids) {
/* update the cache if necessary */
to = ep->cache + (id - ep->baseid) * ep->size;
/*
* Extend the file-backed table TYPE by COUNT elements.
/*
* Extend the file-backed table TYPE by COUNT elements.
+ * Can't extend privately mapped tables.
* Return non-zero on success, zero on failure.
*/
int
* Return non-zero on success, zero on failure.
*/
int
ep = &empfile[type];
if (CANT_HAPPEN(ep->fd < 0 || count < 0))
return 0;
ep = &empfile[type];
if (CANT_HAPPEN(ep->fd < 0 || count < 0))
return 0;
+ if (CANT_HAPPEN(ep->flags & EFF_PRIVATE))
+ return 0; /* not implemented */
tmpobj = calloc(1, ep->size);
id = ep->fids;
tmpobj = calloc(1, ep->size);
id = ep->fids;
SZ((array)), 0, SZ((array)) - 1, SZ((array)) - 1, -1, NULL, NULL, NULL
/* Common configuration table flags */
SZ((array)), 0, SZ((array)) - 1, SZ((array)) - 1, -1, NULL, NULL, NULL
/* Common configuration table flags */
-#define EFF_CFG (EFF_RDONLY | EFF_MEM | EFF_STATIC)
+#define EFF_CFG (EFF_PRIVATE | EFF_MEM | EFF_STATIC)
struct empfile empfile[] = {
/*
struct empfile empfile[] = {
/*
* bits of flags get their final value.
* If flags & EFF_STATIC, the cache is mapped here, and members
* cache, csize get their final value.
* bits of flags get their final value.
* If flags & EFF_STATIC, the cache is mapped here, and members
* cache, csize get their final value.
- * Members baseid, cids, fids and the EFF_MEM|EFF_RDONLY bits of
+ * Members baseid, cids, fids and the EFF_MEM|EFF_PRIVATE bits of
* flags are initialized according the initial cache contents.
* Member fd is initialized to -1.
* Members init, postread, prewrite get initialized to NULL, but
* flags are initialized according the initial cache contents.
* Member fd is initialized to -1.
* Members init, postread, prewrite get initialized to NULL, but