diff options
author | Joris Vink <joris@cvs.openbsd.org> | 2005-06-10 21:13:41 +0000 |
---|---|---|
committer | Joris Vink <joris@cvs.openbsd.org> | 2005-06-10 21:13:41 +0000 |
commit | 73143948c706a14d99e2c96b0f2276ee32c9d35f (patch) | |
tree | 7675f55fa7fc1422e4d1e3dba08ccc95d858b7bf /usr.bin | |
parent | 696826f2934829d8a80aa24685fbd148ff759ac4 (diff) |
instead of opening and closing the entry file all the
time, keep the entry file for the last received directory
open until we switch directories. cuts CPU time in half
and increases overall performance a bit.
ok xsa@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/cvs/resp.c | 91 |
1 files changed, 61 insertions, 30 deletions
diff --git a/usr.bin/cvs/resp.c b/usr.bin/cvs/resp.c index e62610614e8..b74f197c797 100644 --- a/usr.bin/cvs/resp.c +++ b/usr.bin/cvs/resp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resp.c,v 1.41 2005/05/31 08:58:48 xsa Exp $ */ +/* $OpenBSD: resp.c,v 1.42 2005/06/10 21:13:40 joris Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -112,7 +112,15 @@ struct cvs_resphdlr { { cvs_resp_m }, }; - +/* + * Instead of opening and closing the Entry file all the time, + * which caused a huge CPU load and slowed down everything, + * we keep the Entry file for the directory we are working in + * open until we encounter a new directory. + */ +static char cvs_resp_lastdir[MAXPATHLEN] = ""; +static CVSENTRIES *cvs_resp_lastent = NULL; +static int resp_check_dir(const char *); /* * The MT command uses scoping to tag the data. Whenever we encouter a '+', @@ -292,6 +300,11 @@ cvs_resp_m(struct cvsroot *root, int type, char *line) static int cvs_resp_ok(struct cvsroot *root, int type, char *line) { + /* + * If we still have an Entry file open, close it now. + */ + if (cvs_resp_lastent != NULL) + cvs_ent_close(cvs_resp_lastent); return (1); } @@ -463,7 +476,6 @@ cvs_resp_newentry(struct cvsroot *root, int type, char *line) { char entbuf[128]; struct cvs_ent *ent; - CVSENTRIES *entfile; /* get the remote path */ cvs_getln(root, entbuf, sizeof(entbuf)); @@ -472,16 +484,15 @@ cvs_resp_newentry(struct cvsroot *root, int type, char *line) if (cvs_getln(root, entbuf, sizeof(entbuf)) < 0) return (-1); - entfile = cvs_ent_open(line, O_WRONLY); - if (entfile == NULL) + if (resp_check_dir(line) < 0) return (-1); + if (type == CVS_RESP_NEWENTRY) { - cvs_ent_addln(entfile, entbuf); + cvs_ent_addln(cvs_resp_lastent, entbuf); } else if (type == CVS_RESP_CHECKEDIN) { ent = cvs_ent_parse(entbuf); if (ent == NULL) { cvs_log(LP_ERR, "failed to parse entry"); - cvs_ent_close(entfile); return (-1); } @@ -489,11 +500,10 @@ cvs_resp_newentry(struct cvsroot *root, int type, char *line) ent->ce_mtime = time(&(ent->ce_mtime)); /* replace the current entry with the one we just received */ - (void)cvs_ent_remove(entfile, ent->ce_name); + (void)cvs_ent_remove(cvs_resp_lastent, ent->ce_name); - cvs_ent_add(entfile, ent); + cvs_ent_add(cvs_resp_lastent, ent); } - cvs_ent_close(entfile); return (0); } @@ -600,7 +610,6 @@ cvs_resp_updated(struct cvsroot *root, int type, char *line) mode_t fmode; char path[MAXPATHLEN], cksum_buf[CVS_CKSUM_LEN]; BUF *fbuf; - CVSENTRIES *entfile; struct cvs_ent *ep; struct timeval tv[2]; @@ -623,11 +632,8 @@ cvs_resp_updated(struct cvsroot *root, int type, char *line) } ret = 0; - entfile = cvs_ent_open(line, O_WRONLY); - if (entfile == NULL) { - cvs_ent_free(ep); + if (resp_check_dir(line) < 0) return (-1); - } if (cvs_modtime != CVS_DATE_DMSEC) { ep->ce_mtime = cvs_modtime; @@ -636,21 +642,18 @@ cvs_resp_updated(struct cvsroot *root, int type, char *line) if ((type == CVS_RESP_UPDEXIST) || (type == CVS_RESP_UPDATED) || (type == CVS_RESP_MERGED) || (type == CVS_RESP_CREATED)) { - if ((cvs_ent_remove(entfile, ep->ce_name) < 0) && + if ((cvs_ent_remove(cvs_resp_lastent, ep->ce_name) < 0) && (type != CVS_RESP_CREATED)) { cvs_log(LP_WARN, "failed to remove entry for '%s`", ep->ce_name); } } - if (cvs_ent_add(entfile, ep) < 0) { + if (cvs_ent_add(cvs_resp_lastent, ep) < 0) { cvs_ent_free(ep); - cvs_ent_close(entfile); return (-1); } - cvs_ent_close(entfile); - if ((fbuf = cvs_recvfile(root, &fmode)) == NULL) return (-1); if (cvs_buf_write(fbuf, path, fmode) < 0) { @@ -702,7 +705,6 @@ cvs_resp_removed(struct cvsroot *root, int type, char *line) { int l; char buf[MAXPATHLEN], base[MAXPATHLEN], fpath[MAXPATHLEN], *file; - CVSENTRIES *ef; if (cvs_getln(root, buf, sizeof(buf)) < 0) return (-1); @@ -715,16 +717,10 @@ cvs_resp_removed(struct cvsroot *root, int type, char *line) return (-1); } - ef = cvs_ent_open(line, O_RDWR); - if (ef == NULL) { - cvs_log(LP_ERR, "error handling `Removed' response"); - if (type == CVS_RESP_RMENTRY) - return (-1); - } else { - (void)cvs_ent_remove(ef, file); - cvs_ent_close(ef); - } + if (resp_check_dir(line) < 0) + return (-1); + (void)cvs_ent_remove(cvs_resp_lastent, file); if ((type == CVS_RESP_REMOVED) && ((unlink(fpath) == -1) && errno != ENOENT)) { cvs_log(LP_ERRNO, "failed to unlink `%s'", file); @@ -853,3 +849,38 @@ cvs_resp_template(struct cvsroot *root, int type, char *line) return (0); } + +/* + * Check if <dir> is the same as the last + * received directory, if it's not, switch Entry files. + */ +static int +resp_check_dir(const char *dir) +{ + size_t len; + + if (strcmp(dir, cvs_resp_lastdir)) { + if (cvs_resp_lastent != NULL) + cvs_ent_close(cvs_resp_lastent); + cvs_resp_lastent = cvs_ent_open(dir, O_WRONLY); + if (cvs_resp_lastent == NULL) + return (-1); + + len = strlcpy(cvs_resp_lastdir, dir, sizeof(cvs_resp_lastdir)); + if (len >= sizeof(cvs_resp_lastdir)) { + errno = ENAMETOOLONG; + cvs_log(LP_ERRNO, "%s", cvs_resp_lastdir); + return (-1); + } + } else { + /* make sure the old one is still open */ + if (cvs_resp_lastent == NULL) { + cvs_resp_lastent = cvs_ent_open(cvs_resp_lastdir, + O_WRONLY); + if (cvs_resp_lastent == NULL) + return (-1); + } + } + + return (0); +} |