⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ovfcns.c

📁 db.* (pronounced dee-be star) is an advanced, high performance, small footprint embedded database fo
💻 C
📖 第 1 页 / 共 2 页
字号:
                (PAGE_ENTRY **) &task->last_ixpage, (PAGE_ENTRY **) &ixpg_ptr,                task) != S_OKAY )            return task->db_status;        if (ixpg_ptr->buff == NULL)            return (dberr(S_INVPTR));        if (!ixp_used(fno, ipno, task))        {            /* initialize new index page */            ixpg_ptr->ovfl_addr = ip_addr;            memset(ixpg_ptr->buff, 0, IX_PAGESIZE);            set_ixpbit(fno, ipno, task);        }        /* set index entry for new database page */        ent = (int) (db_page - 1 - ipno * IX_EPP);        eptr = (F_ADDR *) (ixpg_ptr->buff + (sizeof(F_ADDR) * ent));        *eptr = pg_ptr->ovfl_addr;        /* mark index page as modified */        ixpg_ptr->modified = TRUE;        ixpg_ptr->recently_used = TRUE;    }    return task->db_status;}/* ======================================================================    Write a page zero to the overflow file*/int INTERNAL_FCN o_pzwrite(FILE_NO file, DB_TASK *task){    F_ADDR    pcnt;       /* Number of pages in file */    F_ADDR    pz_base;    /* page zero base address */    RI_ENTRY *ri_ptr;    void     *buff;    const SG *sg;    ri_ptr = &task->root_ix[file];    pcnt = ri_ptr->pg_cnt;    ri_ptr->pz_modified = TRUE;    pz_base = ri_ptr->base;    pz_base += (F_ADDR) (RI_BITMAP_SIZE(pcnt) * sizeof(int));    pz_base += (F_ADDR) (IX_SIZE(pcnt) * IX_PAGESIZE);    if ((sg = task->sgs[file]) != NULL)    {        buff = task->enc_buff;        memcpy(buff, &task->pgzero[file], PGZEROSZ);        (*sg->enc)(sg->data, buff, PGZEROSZ);    }    else        buff = &task->pgzero[file];    dio_writefile(task->ov_file, pz_base, buff, PGZEROSZ, 0, task);    task->file_table[file].ft_flags &= ~TS_IS_CURRENT;    STAT_log_write(PGZEROSZ, task);    return task->db_status;}/* ======================================================================    Flush the transaction recovery data to the overflow file*/int INTERNAL_FCN o_flush(DB_TASK *task){    PSP_FH              desc;       /* Overflow file descriptor */    int                 bm_size;    /* Size of ri_bitmap */    register int        i;          /* Loop counter */    register RI_ENTRY  *ri_ptr;    PAGE_ENTRY         *ixpg_ptr;    if (task->dboptions & READONLY)        return (dberr(S_READONLY));    if (dio_open(task->ov_file, task) != S_OKAY)        return task->db_status;    desc = task->file_table[task->ov_file].ft_desc;    /* write the root index data out to the overflow file */    for (i = 0, ri_ptr = task->root_ix; i < task->size_ft; ++i, ++ri_ptr)    {        if (psp_fileSeekWrite(desc, task->ov_rootaddr + i * RI_ENTRY_IOSIZE,                ri_ptr, RI_ENTRY_IOSIZE) < (int) RI_ENTRY_IOSIZE)            return (dberr(S_BADWRITE));        STAT_log_write(RI_ENTRY_IOSIZE, task);    }    /* write the index bitmaps to the overflow file */    for (i = 0, ri_ptr = task->root_ix; i < task->size_ft; ++i, ++ri_ptr)    {        bm_size = RI_BITMAP_SIZE(ri_ptr->pg_cnt) * sizeof(int);        if (bm_size)        {            if (psp_fileSeekWrite(desc, BM_BASE(i), ri_ptr->ri_bitmap,                    bm_size) < bm_size)                return (dberr(S_BADWRITE));            STAT_log_write(bm_size, task);        }    }    /* flush index page cache */    for (i = 0, ixpg_ptr = task->cache->ix_pgtab.pg_table; i < task->cache->ix_pgtab.pgtab_sz; ++i, ++ixpg_ptr)    {        if (ixpg_ptr->modified)        {            dio_out(ixpg_ptr, task);            ixpg_ptr->modified = FALSE;        }    }    /* commit the overflow file to ensure recoverability */    commit_file(desc, task);    return (task->db_status);}/* ======================================================================    Update the database from the data in the overflow file*/int INTERNAL_FCN o_update(DB_TASK *task){    register FILE_NO     file;       /* File loop counter */    register int         ent;        /* Ixp entry loop counter */    register F_ADDR      ipno;       /* Index page loop counter */    short                size;       /* Size of page to read */    F_ADDR               d_page;     /* Page num within db file */    F_ADDR               ipcnt;      /* Num of index pages for a file */    F_ADDR               pcnt;       /* Num of pages in file */    F_ADDR               ip_addr;    /* Address of index page */    F_ADDR              *eptr;       /* Ptr to ix page entry */    register RI_ENTRY   *ri_ptr;    register FILE_ENTRY *file_ptr;         PAGE_ENTRY          *ovpg_ptr;    PAGE_ENTRY          *pg_ptr;    PAGE_ENTRY           ovpg;       /* overflowed page *//*    int stat; */    if (task->dboptions & READONLY)        return (dberr(S_READONLY));    memset(&ovpg, '\0', sizeof(PAGE_ENTRY));    ovpg.buff = task->cache->dbpgbuff;    for ( file = 0, ri_ptr = task->root_ix, file_ptr = task->file_table;          (task->db_status == S_OKAY) && (file < task->size_ft);          ++file, ++ri_ptr, ++file_ptr)    {        if (ri_ptr->base == 0L)            continue;        size = file_ptr->ft_pgsize;        pcnt = ri_ptr->pg_cnt;        ipcnt = IX_SIZE(pcnt);        /* scan each index page */        for (ipno = 0; (task->db_status == S_OKAY) && (ipno < ipcnt); ++ipno)        {            if (ixp_used(file, ipno, task))            {                /* read index page */                ip_addr = oaddr_of_ixp(file, ipno, task);                dio_getpg(task->ov_file, ip_addr, task->ix_tag,                          &task->last_ixpage, &ovpg_ptr, task);                if (ovpg_ptr->buff == NULL)                    return (dberr(S_INVPTR));                /* scan each db page entry on index page */                for (ent = 0; (task->db_status == S_OKAY) && (ent < IX_EPP); ++ent)                {                    eptr = (F_ADDR *) (ovpg_ptr->buff + sizeof(F_ADDR) * ent);                    if (*eptr)                    {                        /* if page is in cache then it's already been                           output to db                        */                        d_page = (ipno * IX_EPP) + ent + 1;                        if ((dio_findpg(file, d_page, NULL, &pg_ptr, task) == S_OKAY) &&                            !pg_ptr->modified)                        {                            /* An overflowed db page may not have been modified                               after being reread into the cache from the overflow                               file. Thus the page needs to be marked as modified so                               dio_flush will write the page to the database.                            */                            pg_ptr->modified = TRUE;                        }                        else if (task->db_status == S_NOTFOUND)                        {                            task->db_status = S_OKAY;                            /* update db page from overflow file */                            ovpg.file = file;                            ovpg.pageno = d_page;                            ovpg.buff_size = size;                            /* read the overflow page */                            ovpg.ovfl_addr = *eptr;                            dio_in((PAGE_ENTRY *)&ovpg, task);                            if (task->db_status == S_OKAY)                            {                                /* write the page to the database */                                ovpg.ovfl_addr = 0L;                                dio_out((PAGE_ENTRY *)&ovpg, task);                                if (task->dboptions & TXTEST)                                {                                    dberr(S_DEBUG);                                    flush_dberr(task);                                }                            }                            /* log the page if enabled */                            if (task->trlog_flag && task->db_status == S_OKAY)                                dtrlog(file, d_page, task->cache->dbpgbuff, size, task);                        }                    }                }                dio_clrpage(ovpg_ptr, task);  /* better not use it again! */            }        }        /* If an archive log is being kept, then the pages which were written           directly to the end of the db file must be read and logged if not           in the cache.        */        if (task->db_status == S_OKAY && task->trlog_flag)        {            F_ADDR last_page = dio_pages(file, task);            ovpg.file = file;            for ( ovpg.pageno = pcnt;                  (task->db_status == S_OKAY) && (ovpg.pageno <= last_page);                  ++ovpg.pageno )            {                if (dio_findpg(file, ovpg.pageno, NULL, NULL, task) == S_NOTFOUND)                {                    task->db_status = S_OKAY;                    /* read db page */                    ovpg.ovfl_addr = 0L;                    ovpg.buff_size = size;                    dio_in((PAGE_ENTRY *)&ovpg, task);                    /* log database page */                    dtrlog(file, ovpg.pageno, ovpg.buff, size, task);                }            }        }    }#ifdef DB_DEBUG    /* the ix-cache should now be empty */    for (ipno = 0, pg_ptr = task->cache->ix_pgtab.pg_table;         ipno < task->cache->ix_pgtab.pgtab_sz;         ++ipno, ++pg_ptr)    {        if (pg_ptr->file != -1)            return (dberr(SYS_IXNOTCLEAR));    }#endif/*    stat = dio_close(task->ov_file, task);    if (task->db_status == S_OKAY)        task->db_status = stat; */    return (task->db_status);}/* ======================================================================    Return file's page count at tx start*/F_ADDR INTERNAL_FCN o_pages(FILE_NO file, DB_TASK *task){    return task->root_ix[file].pg_cnt;}/* ======================================================================    Free dynamically allocated data*/void INTERNAL_FCN o_free(int dbn, DB_TASK *task){    register int ft_lc;                 /* loop control */    register RI_ENTRY *ri_ptr;    int low, high;    if (task->root_ix)    {        if (dbn == ALL_DBS)        {            low      = 0;            ft_lc    = task->size_ft;            ri_ptr   = &task->root_ix[0];        }        else        {            low      = task->db_table[dbn].ft_offset;            ft_lc    = task->db_table[dbn].ft_offset + task->db_table[dbn].Size_ft;            ri_ptr   = &task->root_ix[task->db_table[dbn].ft_offset];        }        for (high = ft_lc--; ft_lc >= low; --ft_lc, ++ri_ptr)        {            if (ri_ptr->ri_bitmap)                psp_freeMemory(ri_ptr->ri_bitmap, 0);            task->ov_file--;        }        free_table((void **) &task->root_ix, low, high, task->size_ft,                sizeof(RI_ENTRY), task);    }    if (dbn == ALL_DBS)        task->ov_setup_done = FALSE;    /* Since FREE_TABLE() keeps everything above the region to be freed while        it frees the middle, o_setup() does not need to be called because the        task->ov_file element of the task->file_table[] will just slide down    */    /* set the initial useable address in the overflow file */    ov_header_init(task);}/* ======================================================================    Close the overflow file*/int INTERNAL_FCN o_close(DB_TASK *task){    /* close overflow file */    return dio_close(task->ov_file, task);}/**************************************************************************/static void INTERNAL_FCN ov_header_init(DB_TASK *task){    /* number of files */    task->ov_initaddr = (F_ADDR) sizeof(short);        /* page size & name of each file */    task->ov_initaddr += (F_ADDR) ((sizeof(short) + (FILENMLEN * sizeof(DB_TCHAR))) * task->size_ft);    task->ov_rootaddr = task->ov_initaddr;          /* address of start of root ix data */        /* root index area */    task->ov_initaddr += (F_ADDR) (task->size_ft * RI_ENTRY_IOSIZE);    task->ov_nextaddr = task->ov_initaddr;    task->ov_header_written = FALSE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -