• C语言读写伯克利DB 4


    因为缓存数据的buffer总是不够大(会引起段错误)索性从堆上拿了两块大内存

    /*
    功能说明:逐日存储来访用户(使用伯克利DB)
    根据存储的用户信息确定某用户是否是首次来访用户(未被存储的伯克利DB)
    
    调用方式1: 查询游客在2013年8月8日是否访问了指定渠道
    ./channeldb -s "bch2000 guest:123456789" 20130808
    调用方式2:将指定文件里的用户信息写入DB,同时将该文件里的首次访问用户写入日志
    ./channeldb -f 20130809 ./clog/20130809.log 20130809
    */
    
    #include <assert.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <db.h>
    #include <sys/types.h>
    #include <getopt.h>
    
    #define DATABASE "/mnt/disk1/ucshuqi/touch/userlist/historydb/channel.db"
    #define YES 1
    #define NO  0
    #define BUFFER_SIZE 1024 * 8
    
    char *readBuffer = NULL;
    char *writeBuffer = NULL;
    
    /* ViewData 组件:记录
        用户第一次来访时需要记录的数据,例如日期
     */
    
    struct ViewData {
            int date;
    };
    
    void setDate(struct ViewData *data,char *s)
    {
            assert(data!=NULL && s!= NULL && strlen(s) == 8);
            data->date = atoi(s);
    }
    
    /*当 query.date >= stored.date 返回YES,即包含此附属数据的用户信息是历史来访用户*/
    int isHistoryViewInfo(struct ViewData *query , struct ViewData *stored)
    {
            assert(query != NULL && stored != NULL);
            printf("query date is %d , stored date is %d 
    ",query->date, stored->date);
    
            if(query->date >= stored->date)
            {
                    return YES;
            }
            else
            {
                    return NO;
            }
    }
    
    void printViewData(struct ViewData *data)
    {
            assert(data != NULL);
            printf("print view date : %d
    ",data->date);
    }
    
    
    /* string helper module */
    
    char *trim(char *s)
    {
            int i;
    
            assert(s!=NULL);
            i = strlen(s);
            for(;i>0;i--)
            {
                    if(s[i]==' ' || s[i]=='
    ' || s[i]=='' || s[i]=='	')
                    {
                            s[i] = '';
                    }
                    else
                    {
                            break;
                    }
            }
            return s;
    }
    
    /* 数据库访问 组件*/
    
    DB *openDb()
    {
            int ret;
            DB *dbp = NULL;
    
            ret = db_create(&dbp, NULL, 0);
            if(ret != 0)
            {
                    fprintf(stderr,"create Db error!
    ");
                    exit(1);
            }
    
            ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE,0664);
    
            if(ret != 0)
            {
                    fprintf(stderr,"open Db error!
    ");
                    exit(1);
            }
    
            return dbp;
    }
    
    /* 业务逻辑 */
    
    /* 存储用户访问信息和附属信息viewdata */
    int saveViewInfo(DB *dbp, char *user, struct ViewData *data)
    {
            DBT key,value;
    
            assert(dbp != NULL && user != NULL && data != NULL);
    
            memset(&key, 0, sizeof(key));
            key.data = user;
            key.size = strlen(user) + 1;
    
            memset(&value, 0, sizeof(value));
            value.data = data;
            value.size = sizeof(*data);
            if(dbp->put(dbp, NULL, &key, &value, 0) == 0)
            {
                    //printf("save ---> %s, %d
    ", key.data, key.size);
                    printViewData(value.data);
                    return YES;
            }
            else
            {
                    return NO;
            }
    }
    
    /*查找用户访问信息,并将附属信息写入data*/
    int findViewInfo(DB *dbp, char *user, struct ViewData *data)
    {
            DBT key,value;
    
            assert(dbp != NULL && user != NULL && data != NULL);
    
            memset(&key, 0, sizeof(key));
            key.data = user;
            key.size = strlen(user) + 1;
    
            memset(&value,0,sizeof(value)); // must !!!
    
            if(dbp->get(dbp, NULL, &key, &value, 0) == 0)
            {
                    memcpy((char*)data,(char*)value.data,value.size);
                    //printViewData(data);
                    return YES; //view in database 
            }
            else
            {
                    return NO; //view not in database
            }
    }
    
    /*记录用户信息,如果用户是首次来访*/
    void recordNewView(FILE *fp, char *user, char *buffer)
    {
            //char buffer[BUFFER_SIZE] = {0};                                                                
            assert(fp != NULL && user != NULL && buffer != NULL);
            printf("%s is new view
    ", user);
            sprintf(buffer, "%s found
    ", user);                                               
            fwrite(buffer, sizeof(char), strlen(buffer), fp);
    }
    
    /*存储访问信息到数据库,同时写入附属信息*/
    void saveViewFile(char *from, char *to, struct ViewData *writeData)
    {
            DB *dbp = openDb();
            struct ViewData stored;
            FILE *fp = fopen(from,"r");
            FILE *fpResult = fopen(to,"w");
    
            assert(fp != NULL && fpResult != NULL && writeData != NULL);
            assert(readBuffer != NULL && writeBuffer != NULL);
    
            /* clear global buffer content */
            memset(readBuffer, 0, BUFFER_SIZE); 
            memset(writeBuffer, 0, BUFFER_SIZE); 
    
            while(fgets((char*)readBuffer, BUFFER_SIZE, fp)!=NULL)
            {
                    char *user = trim((char*)readBuffer);
                    memset(&stored, 0, sizeof(stored));
    
                    if(findViewInfo(dbp, user, &stored) == YES)
                    {
                            if(isHistoryViewInfo(writeData,&stored) == NO)
                            {
                                    recordNewView(fpResult, user, writeBuffer);
                            }
                            continue;
                    }
    
                    recordNewView(fpResult, user, writeBuffer);
                    if(saveViewInfo(dbp, user, writeData) == NO)
                    {
                            printf("save %s faild
    ", user);
                    }
    
                    /* clear global buffer content */
                    memset(readBuffer, 0, BUFFER_SIZE); 
                    memset(writeBuffer, 0, BUFFER_SIZE); 
            }
    
            free(readBuffer);
            free(writeBuffer);
            dbp->close(dbp, 0);
            fclose(fp);
            fclose(fpResult);
    }
    
    /*给命令行调用的接口,找茬指定的用户是否是历史用户*/
    void hasViewInfo(char *user, struct ViewData *query)
    {
            DB *dbp = NULL;
            struct ViewData stored;
    
            dbp = openDb();
            assert(user != NULL && query != NULL);
            memset(&stored, 0 ,sizeof(stored));
            user = trim(user);
    
            if(findViewInfo(dbp, user, &stored) == YES)
            {
                    if(isHistoryViewInfo(query, &stored) == YES)
                    {
                            printf("found %s
    ",user);
                    }
                    else
                    {
                            //printf("%s in db
    ",user);
                            printf("not found %s
    ",user);
                    }
            }
            else
            {
                    printf("%s not in db
    ",user);
                    printf("not found %s
    ",user);
            }
    
            dbp->close(dbp, 0);
    }
    
    int main (int argc, char *argv[])
    {
            int oc;
            extern char *optarg;
            extern int optind, opterr, optopt;
    
            char *from = NULL;
            char *to = NULL;
    
            struct ViewData viewData;
            memset(&viewData, 0, sizeof(viewData));
    
            readBuffer = malloc(BUFFER_SIZE);
            writeBuffer = malloc(BUFFER_SIZE);
    
            while((oc=getopt(argc,argv,"f:s:t:")) != -1)
            {
                    switch(oc)
                    {
                            case 's':
                                    setDate(&viewData,argv[optind]);
                                    hasViewInfo(optarg, &viewData);
                                    break;
    
                            case 'f':
                                    from = optarg;
                                    to = argv[optind++];
                                    setDate(&viewData,argv[optind]);
                                    saveViewFile(from, to, &viewData);
                                    break;
                    }
            }
    
            return 0;
    }
  • 相关阅读:
    python mock知识02
    python+selenium实现web自动化
    接口幂等性
    Nacicat for Oracle 绿色版 亲测可用
    isinstance、流程控制(单项、双项、多项、巢状)
    算数运算符、比较运算符、赋值运算符、成员运算符、身份运算符、逻辑运算符、位运算符
    集合、字典、哈希算法、变量的缓存机制、小数据池、强制类型转换
    变量、编码知识、数据类型、字符串格式化
    Python基础(电脑基础知识、原码补码及反码)
    函数操作
  • 原文地址:https://www.cnblogs.com/code-style/p/3282870.html
Copyright © 2020-2023  润新知