From cf16c74a3d34aeeaa91051bfb16552c19d16564e Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 9 Mar 2008 13:42:12 +0100 Subject: [PATCH] New ef_truncate() --- include/file.h | 1 + src/lib/common/file.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/file.h b/include/file.h index fc571620..c0eca3ad 100644 --- a/include/file.h +++ b/include/file.h @@ -187,6 +187,7 @@ extern void ef_blank(int, int, void *); extern int ef_write(int, int, void *); extern int ef_extend(int, int); extern int ef_ensure_space(int, int, int); +extern int ef_truncate(int, int); extern int ef_nelem(int); extern int ef_flags(int); extern int ef_byname(char *); diff --git a/src/lib/common/file.c b/src/lib/common/file.c index caf55052..f2e4353a 100644 --- a/src/lib/common/file.c +++ b/src/lib/common/file.c @@ -514,6 +514,49 @@ do_blank(struct empfile *ep, void *buf, int id, int count) } } +/* + * Truncate table TYPE to COUNT elements. + * Any pointers obtained from ef_ptr() become invalid. + * Return non-zero on success, zero on failure. + */ +int +ef_truncate(int type, int count) +{ + struct empfile *ep; + + if (ef_check(type) < 0) + return 0; + ep = &empfile[type]; + if (CANT_HAPPEN(count < 0 || count > ep->fids)) + return 0; + + if (ep->fd >= 0 && !(ep->flags & EFF_PRIVATE)) { + if (ftruncate(ep->fd, count * ep->size) < 0) { + logerror("Can't truncate %s to %d elements (%s)", + ep->file, count, strerror(errno)); + return 0; + } + } + ep->fids = count; + + if (ep->flags & EFF_MEM) { + if (!(ep->flags & EFF_STATIC)) { + if (!ef_realloc_cache(ep, count)) { + logerror("Can't shrink cache after truncate"); + /* continue with unshrunk cache */ + } + } + ep->cids = count; + } else { + if (ep->baseid >= count) + ep->cids = 0; + else if (ep->cids > count - ep->baseid) + ep->cids = count - ep->baseid; + } + + return 1; +} + struct castr * ef_cadef(int type) {