diff options
author | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-09-27 21:39:12 +0000 |
---|---|---|
committer | file <file@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-09-27 21:39:12 +0000 |
commit | 92cbbd56dcc7ad661ad2864d0957343a4a92400e (patch) | |
tree | 816239f825f9beb659280fc3b99d702299819988 /apps | |
parent | 63d14e3b63cf4a9a625dee706336cce5eb388d66 (diff) |
Do the directory walk dance instead of repeated stat calls as it seems to be faster (issue #7507 reported by Corydon76)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@43827 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps')
-rw-r--r-- | apps/app_voicemail.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 06eb5d35a..f3342f709 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -1625,14 +1625,27 @@ static void copy_file(char *frompath, char *topath) static int last_message_index(struct ast_vm_user *vmu, char *dir) { int x; - char fn[256]; + unsigned char map[MAXMSGLIMIT] = ""; + DIR *msgdir; + struct dirent *msgdirent; + int msgdirint; if (vm_lock_path(dir)) return ERROR_LOCK_PATH; + /* Reading the entire directory into a file map scales better than + * doing a stat repeatedly on a predicted sequence. I suspect this + * is partially due to stat(2) internally doing a readdir(2) itself to + * find each file. */ + msgdir = opendir(dir); + while ((msgdirent = readdir(msgdir))) { + if (sscanf(msgdirent->d_name, "msg%d", &msgdirint) == 1 && msgdirint < MAXMSGLIMIT) + map[msgdirint] = 1; + } + closedir(msgdir); + for (x = 0; x < vmu->maxmsg; x++) { - make_file(fn, sizeof(fn), dir, x); - if (ast_fileexists(fn, NULL, NULL) < 1) + if (map[x] == 0) break; } ast_unlock_path(dir); @@ -2525,13 +2538,7 @@ static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int i if (vm_lock_path(todir)) return ERROR_LOCK_PATH; - recipmsgnum = 0; - do { - make_file(topath, sizeof(topath), todir, recipmsgnum); - if (!EXISTS(todir, recipmsgnum, topath, chan->language)) - break; - recipmsgnum++; - } while (recipmsgnum < recip->maxmsg); + recipmsgnum = last_message_index(recip, todir) + 1; if (recipmsgnum < recip->maxmsg) { COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); } else { @@ -2995,12 +3002,8 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_ unlink(tmptxtfile); ast_unlock_path(dir); } else { - for (;;) { - make_file(fn, sizeof(fn), dir, msgnum); - if (!EXISTS(dir, msgnum, fn, NULL)) - break; - msgnum++; - } + msgnum = last_message_index(vmu, dir) + 1; + make_file(fn, sizeof(fn), dir, msgnum); /* assign a variable with the name of the voicemail file */ pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); @@ -3123,11 +3126,9 @@ static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg if (vm_lock_path(ddir)) return ERROR_LOCK_PATH; - for (x = 0; x < vmu->maxmsg; x++) { - make_file(dfn, sizeof(dfn), ddir, x); - if (!EXISTS(ddir, x, dfn, NULL)) - break; - } + x = last_message_index(vmu, ddir) + 1; + make_file(dfn, sizeof(dfn), ddir, x); + if (x >= vmu->maxmsg) { ast_unlock_path(ddir); return -1; |