Make ef_open() extend files with fixed size automatically

Turns the fixed size into an invariant.  Before, the files utility
created them empty, then extended them.
This commit is contained in:
Markus Armbruster 2011-05-04 07:45:05 +02:00
parent 31b9ff08f3
commit 7d2269b5ae
2 changed files with 49 additions and 35 deletions

View file

@ -58,6 +58,7 @@ static int do_write(struct empfile *, void *, int, int);
static unsigned get_seqno(struct empfile *, int); static unsigned get_seqno(struct empfile *, int);
static void new_seqno(struct empfile *, void *); static void new_seqno(struct empfile *, void *);
static void must_be_fresh(struct empfile *, void *); static void must_be_fresh(struct empfile *, void *);
static int do_extend(struct empfile *, int);
static void do_blank(struct empfile *, void *, int, int); static void do_blank(struct empfile *, void *, int, int);
static int ef_check(int); static int ef_check(int);
@ -74,7 +75,7 @@ int
ef_open(int type, int how) ef_open(int type, int how)
{ {
struct empfile *ep; struct empfile *ep;
int oflags, fd, fsiz, fids, nslots; int oflags, fd, fsiz, fids, nslots, fail;
if (ef_check(type) < 0) if (ef_check(type) < 0)
return 0; return 0;
@ -97,19 +98,23 @@ ef_open(int type, int how)
} }
/* get file size */ /* get file size */
fsiz = fsize(fd); if (how & EFF_CREATE) {
if (fsiz % ep->size) { fids = ep->nent >= 0 ? ep->nent : 0;
logerror("Can't open %s (file size not a multiple of record size %d)", } else {
ep->file, ep->size); fsiz = fsize(fd);
close(fd); if (fsiz % ep->size) {
return 0; logerror("Can't open %s (file size not a multiple of record size %d)",
} ep->file, ep->size);
fids = fsiz / ep->size; close(fd);
if (ep->nent >= 0 && ep->nent != fids && !(how & EFF_CREATE)) { return 0;
logerror("Can't open %s (got %d records instead of %d)", }
ep->file, fids, ep->nent); fids = fsiz / ep->size;
close(fd); if (ep->nent >= 0 && ep->nent != fids) {
return 0; logerror("Can't open %s (got %d records instead of %d)",
ep->file, fids, ep->nent);
close(fd);
return 0;
}
} }
/* allocate cache */ /* allocate cache */
@ -139,17 +144,24 @@ ef_open(int type, int how)
} }
ep->baseid = 0; ep->baseid = 0;
ep->cids = 0; ep->cids = 0;
ep->fids = fids;
ep->flags = (ep->flags & EFF_IMMUTABLE) | (how & ~EFF_CREATE); ep->flags = (ep->flags & EFF_IMMUTABLE) | (how & ~EFF_CREATE);
ep->fd = fd; ep->fd = fd;
/* map file into cache */ if (how & EFF_CREATE) {
if ((how & EFF_MEM) && fids) { /* populate new file */
if (fillcache(ep, 0) != fids) { ep->fids = 0;
ep->cids = 0; /* prevent cache flush */ fail = !do_extend(ep, fids);
ef_close(type); } else {
return 0; ep->fids = fids;
} if ((how & EFF_MEM) && fids)
fail = fillcache(ep, 0) != fids;
else
fail = 0;
}
if (fail) {
ep->cids = 0; /* prevent cache flush */
ef_close(type);
return 0;
} }
if (ep->onresize) if (ep->onresize)
@ -678,13 +690,24 @@ int
ef_extend(int type, int count) ef_extend(int type, int count)
{ {
struct empfile *ep; struct empfile *ep;
if (ef_check(type) < 0)
return 0;
ep = &empfile[type];
if (!do_extend(ep, count))
return 0;
if (ep->onresize)
ep->onresize(type);
return 1;
}
static int
do_extend(struct empfile *ep, int count)
{
char *p; char *p;
int need_sentinel, i, id; int need_sentinel, i, id;
if (ef_check(type) < 0 || CANT_HAPPEN(EF_IS_VIEW(type))) if (CANT_HAPPEN(EF_IS_VIEW(ep->uid)) || count < 0)
return 0;
ep = &empfile[type];
if (CANT_HAPPEN(count < 0))
return 0; return 0;
id = ep->fids; id = ep->fids;
@ -723,8 +746,6 @@ ef_extend(int type, int count)
} }
} }
ep->fids = id + count; ep->fids = id + count;
if (ep->onresize)
ep->onresize(type);
return 1; return 1;
} }

View file

@ -136,8 +136,6 @@ main(int argc, char *argv[])
} }
} }
ef_extend(EF_GAME, 1);
ef_extend(EF_NATION, MAXNOC);
ef_read(EF_NATION, 0, &nat); ef_read(EF_NATION, 0, &nat);
strcpy(nat.nat_cnam, "POGO"); strcpy(nat.nat_cnam, "POGO");
strcpy(nat.nat_pnam, "peter"); strcpy(nat.nat_pnam, "peter");
@ -147,7 +145,6 @@ main(int argc, char *argv[])
nat.nat_flags |= NF_FLASH; nat.nat_flags |= NF_FLASH;
ef_write(EF_NATION, 0, &nat); ef_write(EF_NATION, 0, &nat);
printf("All praise to %s!\n", nat.nat_cnam); printf("All praise to %s!\n", nat.nat_cnam);
ef_extend(EF_REALM, MAXNOC * MAXNOR);
if (mkdir(teldir, S_IRWXU | S_IRWXG) < 0 && errno != EEXIST) { if (mkdir(teldir, S_IRWXU | S_IRWXG) < 0 && errno != EEXIST) {
perror(teldir); perror(teldir);
printf("Can't make telegram directory\n"); printf("Can't make telegram directory\n");
@ -159,10 +156,6 @@ main(int argc, char *argv[])
} }
close(creat(annfil, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)); close(creat(annfil, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
ef_extend(EF_SECTOR, WORLD_SZ());
ef_extend(EF_MAP, MAXNOC);
ef_extend(EF_BMAP, MAXNOC);
for (i = 0; i < EF_MAX; i++) { for (i = 0; i < EF_MAX; i++) {
if (!EF_IS_GAME_STATE(i)) if (!EF_IS_GAME_STATE(i))
continue; continue;