背景:
阅读文章

大量数据存储和读取的问题

[日期:2007-05-11] 来源:  作者: [字体: ]

这个问题一直比较迷惑,比如 read_file 最多可以读多长
的文件,write_file 最多可以写多长的文件,save_object
最多可以存多大的内容。

最近在写一个取 mudlib 内所有文件进行时间比较的程序中
遇到了这个问题。这个程序主要是想取得所有文件的
last_touched_time 进行保存,下次进行此操作时再把目前
的信息与上次保存的信息进行比较,列出修改过的文件。比


如说我用下面的程序列出所有 / 下的文件:
string *deep_file_list(string dir)
{
        int i;
        string *flist, *result = ({ }), file;

        if (member_array(dir, exclude_dir) != -1)
        {
                return ({ });
        }
        flist = get_dir(dir);

        for (i = 0; i < sizeof(flist); i++)
        {
                file = dir + flist[i];
               
                if (file_size(file + "/") == -2)
                        result += deep_file_list(file + "/");
                else
                        result += ({ file });
        }

        return result;
}

然后再用下面的程序生成一个 mapping:
private void build_version()
{
        string *flist;
        int i, max;

        flist = deep_file_list("/");
        max = sizeof(flist);
        file_info = ([ ]);

        for (i = 0; i < max; i++)
        {
                if (! i % 100)
                        reset_eval_cost();

                file_info[flist[i]] = stat(flist[i])[1];
        }
        return;
}

一开始,我是继承了 F_SAVE,想用 save(); 来保存,结果
是存盘文件中除了 #/xxx/xxxx/xxx.c 之外没有任何数据,
于是我尝试用 write_file 的方法,即如下程序:
int save()
{
        string info;
        int i;
        string *key;

        if (! mapp(file_info) || ! sizeof(file_info))
                return 0;

        info = sprintf("version : %d\n", version);
        key = keys(file_info);
        for (i = 0; i < sizeof(file_info); i++)
        {
                info += sprintf("%s : %d\n", key[i], file_info[key[i]]);
        }
        return write_file(VERSION_FILE, info, 1);
}
写入是成功的,文件大概有将近 300K(我以前用 save_object
则保存过 150K 左右的文件)。

但是,用 read_file 来读这整个文件返回的是 0,于是我只好
用如下程序一行一行地来读:
void restore()
{
        string info;
        string file, line;
        string *lines;
        int time;
        int i;
       
        if (stringp(info = read_file(VERSION_FILE, 1, 1)))
        {
                sscanf(info, "version : %d", version);

                for (i = 2; ; i++)
                {
                        if (! stringp(line = read_file(VERSION_FILE, i, i)))
                                break;
                        if (sscanf(line, "%s : %d", file, time) == 2)
                                file_info[file] = time;
                        if (! i % 100)
                                reset_eval_cost();
                }
        }
}
以上程序经过测试确实使可以运行的,但运行起来就非常的慢
了,大概 save() + restore() 一次要半分钟。所以这里想问
问有没有更好的方法可以进行这种大容量的存储和读取?

--------------------------------------------------------------------------------
莫愁前路无知己,天下谁人不识君?

做成守护进程吧。   


作者:Super  发表时间:2001年8月1日 16:19

--------------------------------------------------------------------------------

mapping file_info[];

int save(int t)
{
        string info;
        int i;
        string *key;
        int flag;
       
        flag = 0;
       
        if (memory_info() > 5000000) {
call_out("save",5);
return 1;
        }

        if (t > sizeof(file_info)) {t = sizeof(file_info);flag = 1;}

        if (! mapp(file_info) || ! sizeof(file_info))
                return 0;

        info = sprintf("version : %d\n", version);
        key = keys(file_info);
        for (i = t; i < t ; i++)
        {
                info += sprintf("%s : %d\n", key[i], file_info[key[i]]);
        }
       
        remove_all_callout();
       
        if (flag == 1) return write_file(VERSION_FILE,info);
       
        call_out("save",0,t+30);
       
        return 1;
}
void create()
{
set("id","Saver_Storer");
seteuid(geteuid());
}
void start_save() { save(0); }

int write_file(string filename,mixed info)
{
write("save file done!\n");
return ::write_file(filename,info);
}

这样储存时间虽然要长点,不过储存的时候应该感觉不到延迟的。
另外memory_info()的判断的大小,根据系统的负担而定。


re   


作者:doing  发表时间:2001年8月1日 16:20

--------------------------------------------------------------------------------

save_object 可以保存 300k 的内容。至于 read_file 和 write_file 读写文件也没有限制,完全看你的 buffer 或 string 的容量,这个是在配置里面指明的。

save_object 只是限制了递归的层次,这个也是在配置中指明的。 
 
 
 尊重作者 转载请注明出处52mud.com

收藏 推荐 打印 | 录入:sbso | 阅读:
相关内容      
内容推送
52mud提供
一起回忆泥巴游戏QQ群68186072
52mud官方微信公众平台
热门评论