首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

求目录缓存设计方案,该如何处理

2012-05-07 
求目录缓存设计方案小弟需要写一个网络文件系统的目录缓存管理的模块。该模块将一个目录信息缓存在内存里。

求目录缓存设计方案
小弟需要写一个网络文件系统的目录缓存管理的模块。该模块将一个目录信息缓存在内存里。

目录内容来源于服务器,一次获得一个目录下面的所有文件与目录列表。
相当于Windows通过FindFirstFile与FindNextFile遍历得到该目录下的所有子文件与子目录信息(类似WIN32_FIND_DATA)

客户端会很频繁的访问该缓存,以获取文件目录的信息,服务器也会很频繁的通知我,某个目录有变更,需要将该目录的子项清理,这时候我会清楚该目录的缓存,重新获取。

我已经使用过几种方案:
大锁:  将所有的获取设置等操作锁起来,这样通知来时清理缓存时可以避免该文件或目录的缓存正在被访问造成违例。但是多线程全被砍了。
引用技术:这样搞使用起来十分不方便,要万分小心引用的加减,而且代码也难看。

各位大神,求一种较为优美的方案:
1.能解决访问违例问题,使用数据和刷新都相当频繁
2.能支持大量的并发
3.代码结构优美、清晰,容易理解

求大神提供方案:一百分呀一百分!!!

[解决办法]
仅供参考

C/C++ code
//输出PROG中有但LIST中没有的文本行,即集合PROG-LIST#include <stdio.h>#include <string.h>#include <stdlib.h>#include <search.h>#define MAXLINES 1000000#define MAXCHARS 256char buf[MAXLINES][MAXCHARS];char P[256]="PROG";//程序Program需要的文件列表char L[256]="LIST";//dir /b /s生成的实际文件列表ListFILE *fp,*fl;int c,n,L1,hh;int ignore_case=0;char ln[MAXCHARS];int icompare(const void *arg1,const void *arg2) {   return stricmp((char *)arg1,(char *)arg2);}int compare(const void *arg1,const void *arg2) {   return strcmp((char *)arg1,(char *)arg2);}int main(int argc,char **argv) {    if (argc>1) strcpy(P,argv[1]);//命令行参数1覆盖PROG    if (argc>2) strcpy(L,argv[2]);//命令行参数2覆盖LIST    if (argc>3) ignore_case=1;//若存在命令行参数3,忽略大小写    if ((fl=fopen(L,"rt"))==NULL) {        fprintf(stderr,"Can not open %s\n",L);        fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);        return 1;    }    if ((fp=fopen(P,"rt"))==NULL) {        fclose(fl);        fprintf(stderr,"Can not open %s\n",P);        return 2;    }    n=0;    hh=0;    while (1) {        if (fgets(ln,MAXCHARS,fl)==NULL) break;//        hh++;        L1=strlen(ln)-1;        if ('\n'!=ln[L1]) {//超长行忽略后面内容            fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",L,hh,MAXCHARS);            while (1) {                c=fgetc(fl);                if ('\n'==c || EOF==c) break;//            }        }        while (1) {//去掉行尾的'\n'和空格            if ('\n'==ln[L1] || ' '==ln[L1]) {                ln[L1]=0;                L1--;                if (L1<0) break;//            } else break;//        }        if (L1>=0) {            strcpy(buf[n],ln);            n++;            if (n>=MAXLINES) {                fclose(fl);                fclose(fp);                fprintf(stderr,"%s up to %d lines",L,MAXLINES);                return 3;            }        }    }    fclose(fl);    if (ignore_case) qsort(buf,n,MAXCHARS,icompare);    else qsort(buf,n,MAXCHARS,compare);    hh=0;    while (1) {        if (fgets(ln,MAXCHARS,fp)==NULL) break;//        hh++;        L1=strlen(ln)-1;        if ('\n'!=ln[L1]) {//超长行忽略后面内容            fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",P,hh,MAXCHARS);            while (1) {                c=fgetc(fp);                if ('\n'==c || EOF==c) break;//            }        }        while (1) {//去掉行尾的'\n'和空格            if ('\n'==ln[L1] || ' '==ln[L1]) {                ln[L1]=0;                L1--;                if (L1<0) break;//            } else break;//        }        if (L1>=0) {            if (ignore_case) {                if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);            } else {                if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);            }        }    }    fclose(fp);    return 0;}
[解决办法]
探讨

这属于造轮子行为,说了半天就是key=>val映射,要求高效,要求在内存里维护,要求网络可存取,要么用memcached,要么用redis。

服务端要监控本地目录的变动,不知道你是怎么实现的,定时去扫吗?
我倒建议你懒惰监控,用户不请求,我就不检查。
如果用户请求,可以使用etag/if-modified-since这些web里的类似方法来验证缓存自上一次修改后目录是否发生过变动,无效……

热点排行