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

📄 dio.c

📁 db.* (pronounced dee-be star) is an advanced, high performance, small footprint embedded database fo
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ======================================================================    Return a pointer to the buffer of a requested page*/int EXTERNAL_FCN dio_getpg(    FILE_NO         file,       /* file table index */    F_ADDR          page,       /* page in file */    short           pg_tag,    PAGE_ENTRY    **last_lu,    /* the last looked-up page */    PAGE_ENTRY    **xpg_ptr,    DB_TASK *task){    PAGE_TABLE *pgtab = (file == task->ov_file) ? &task->cache->ix_pgtab : &task->cache->db_pgtab;    PAGE_TAG   *tag_ptr;    PAGE_ENTRY *pg_ptr;    short       pgsize;    int         retcode;    F_ADDR      ovfl_addr;        retcode = task->db_status;    tag_ptr = &task->cache->tag_table[pg_tag];    if (tag_ptr->lookups > LONG_MAX)    {        /* prevent roll-over while keeping proportions */        tag_ptr->lookups >>= 1;        tag_ptr->hits    >>= 1;    }    tag_ptr->lookups++;    STAT_lookups(file, task);#ifdef DB_DEBUG    if (task->db_debug & LOCK_CHECK)    {        /* make sure that a locked file has not been modified by someone else        */        if (file != task->ov_file && !(task->file_table[file].ft_flags & STATIC) &&            task->dbopen == 1 && (task->app_locks[file] || task->excl_locks[file]))        {            if (task->pgzero[file].pz_next)            {                if (dio_open(file, task) != S_OKAY)                    return (task->db_status);                if (task->pgzero[file].file_mtime != psp_fileModTime(task->file_table[file].ft_desc))                    retcode = dberr(SYS_FILEMODIFIED);                if (retcode)                    return (task->db_status = retcode);            }        }    }#endif /* DB_DEBUG */    /* look in the cache */    if (dio_findpg(file, page, last_lu, xpg_ptr, task) == S_OKAY)    {        /* found the page in the cache */#ifdef DB_DEBUG        if (task->db_debug & LOCK_CHECK)        {            /* make sure that a locked page gotten from the cache has not been               modified by someone else in the meantime            */            if (file != task->ov_file && !(task->file_table[file].ft_flags & STATIC) &&                task->dbopen == 1 && (task->app_locks[file] || task->excl_locks[file]))            {                const SG *sg;                long      ptime = 0L;                off_t     addr = task->file_table[file].ft_pgsize * (off_t)page;                if ((sg = task->sgs[file]) != NULL)                {                    off_t  begin;                    off_t  off;                    size_t size;                    block_parms(addr, sizeof(long), &begin, &size, &off, sg);                    dio_readfile(file, begin, task->enc_buff, size, 0,                            NULL, task);                    (*sg->dec)(sg->data, task->enc_buff, size);                    memcpy(&ptime, (char *) task->enc_buff + off, sizeof(long));                }                else                    dio_readfile(file, addr, &ptime, 4, 0, NULL, task);                if (memcmp((*xpg_ptr)->buff, (char *)&ptime, 4) != 0)                    return (dberr(SYS_FILEMODIFIED));            }        }#endif /* DB_DEBUG */        tag_ptr->hits++;        STAT_hits(file, task);        return (task->db_status);    }    if (task->db_status == S_NOTFOUND)        task->db_status = S_OKAY;    /* page not found -- start of process to read into cache */    /* #1 -- search the page table for a page not recently used */    if (dio_findlru(file, page, pg_tag, &pg_ptr, task) != S_OKAY)        return (task->db_status);#ifdef DB_DEBUG    if (pg_ptr <  pgtab->pg_table     || pg_ptr >= pgtab->pg_table + pgtab->pgtab_sz)        return (dberr(SYS_INVPAGE));#endif    /* #2 -- write page if dirty */    if (pg_ptr->modified)    {        FILE_ENTRY *file_ptr = &task->file_table[pg_ptr->file];        if (pg_ptr->file == task->ov_file          || file_ptr->ft_flags & TEMPORARY          || (!task->trans_id[0] && (task->dbopen >= 2 || task->excl_locks[pg_ptr->file]))          || !(task->dboptions & TRLOGGING))        {            /* ix page swapping occurs here; also data/key pages when               (in one-user/exclusive mode or has exclusive locks) and               (without transactions).            */            retcode = dio_out(pg_ptr, task);            if (pg_ptr->file != task->ov_file)            {                /* this will cause the file to be committed at d_close */                file_ptr->ft_flags |= NEEDS_COMMIT;            }        }        else        {            retcode = o_write(pg_ptr, task);            if (retcode == S_OKAY)                task->cache_ovfl = TRUE;        }        if (retcode == S_OKAY)            pg_ptr->modified = FALSE;    }    /* #3 -- remove the found page from the hash_table old bucket */    if (retcode == S_OKAY && pg_ptr->file != -1)        retcode = dio_clrpage(pg_ptr, task);    if (retcode != S_OKAY)        goto ret_dbstatus;    /* old page has now been swapped out, bring in new page */    /* #4 -- resize the page buffer if necessary */    pgsize = task->file_table[file].ft_pgsize;    if (!task->cache->prealloc)    {        if ((pgsize != pg_ptr->buff_size) || (pg_ptr->buff == NULL))        {            /* The realloc for a smaller page allows for the cache to shrink               when the db needing the larger pages is d_iclose()-ed.  If this               is not done, the d_iopen() would make the cache grow without the               possibility of it ever shrinking.            */            char *tempbuff = psp_cGetMemory(pgsize, 0);            if (! tempbuff)                return (dberr(S_NOMEMORY));            if (pg_ptr->buff)                psp_freeMemory(pg_ptr->buff, 0);            pg_ptr->buff = tempbuff;#ifdef DBSTAT            STAT_mem_alloc(pgtab, pgsize - pg_ptr->buff_size);#endif        }    }    pg_ptr->buff_size = pgsize;    /* #5 -- check to see if page is in overflow file */    ovfl_addr = 0L;    if (file == task->ov_file)    {        ovfl_addr = page;    }    else if (task->cache_ovfl)    {        retcode = o_search(file, page, &ovfl_addr, task);        if (retcode != S_OKAY)            goto ret_dbstatus;    /* o_search failed, exit function */    }    /* #6 -- this is now the one we are looking for, setup for dio_in() */    pg_ptr->file = file;    pg_ptr->pageno = page;    pg_ptr->ovfl_addr = ovfl_addr;    /* #7 -- read the page from disk */    if ((retcode = dio_in(pg_ptr, task)) == S_OKAY)    {        /* #8 -- add pg_ptr into hash_table in new bucket, front of the chain */        dio_rehash(pg_ptr, task);        pg_ptr->tag = pg_tag;        if (file != task->ov_file)        {            pg_ptr->n_pg = task->pgzero[file].pg_ptr;            task->pgzero[file].pg_ptr = pg_ptr;            if (pg_ptr->n_pg)                pg_ptr->n_pg->p_pg = pg_ptr;        }        ++task->cache->tag_table[pg_tag].num_pages;        STAT_pages(file, 1, task);        if (last_lu) *last_lu = pg_ptr;        if (xpg_ptr) *xpg_ptr = pg_ptr;    }#ifdef DB_DEBUG    if (task->db_debug & CACHE_CHECK)    {        if (check_cache(DB_TEXT("after dio_getpg"), task) != S_OKAY)            retcode = task->db_status;    }#endifret_dbstatus:    return (task->db_status = retcode);}/* ======================================================================*/int INTERNAL_FCN dio_out(    PAGE_ENTRY *pg_ptr,       /* page table entry to be output */    DB_TASK    *task){    FILE_NO   fno;                /* file number */    short     pgsize;             /* size of page */    off_t     addr;               /* file address */    long      curr_time;    void     *buff;    const SG *sg;#ifdef DB_DEBUG    DB_ADDR   page_id;#endif    if (task->dboptions & READONLY)        return (dberr(S_READONLY));    if (pg_ptr->buff == NULL)        return (dberr(S_INVPTR));    fno = pg_ptr->file;    pgsize = task->file_table[fno].ft_pgsize;#ifdef DB_DEBUG    if (pg_ptr->buff_size != pgsize)        return (dberr(SYS_INVPGSIZE));#endif    if (pg_ptr->ovfl_addr == 0L)    {        /* write to database file */        if (pg_ptr->pageno == 0)            return (dberr(SYS_PZACCESS));#ifdef DB_DEBUG        if (task->db_debug & PAGE_CHECK)        {            ENCODE_DBA(min(fno, 255), pg_ptr->pageno, &page_id);            if (memcmp(pg_ptr->buff, &page_id, sizeof(DB_ADDR)) != 0)                return (dberr(SYS_BADPAGE));        }        else if (task->db_debug & LOCK_CHECK)        {            /* make sure that a locked page has not been modified by someone               else in the meantime            */            if (fno != task->ov_file && !(task->file_table[fno].ft_flags & STATIC) &&                task->dbopen == 1 && (task->app_locks[fno] || task->excl_locks[fno]))            {                long ptime = 0L;                addr = pgsize * (off_t)pg_ptr->pageno;                if ((sg = task->sgs[fno]) != NULL)                {                    off_t  begin;                    off_t  off;                    size_t size;                    block_parms(addr, sizeof(long), &begin, &size, &off, sg);                    dio_readfile(fno, begin, task->enc_buff, size, 0,                            NULL, task);                    (*sg->dec)(sg->data, task->enc_buff, size);                    memcpy(&ptime, (char *) task->enc_buff, sizeof(long));                }                else                {                    dio_readfile(fno, addr, &ptime, sizeof(long), 0,                            NULL, task);                }                if (memcmp(pg_ptr->buff, &ptime, 4) != 0)                    return (dberr(SYS_FILEMODIFIED));            }        }#endif /* DB_DEBUG */        curr_time = psp_timeSecs();             /* get the current time */        memcpy(pg_ptr->buff, &curr_time, sizeof(time_t));        addr = pgsize * (off_t)pg_ptr->pageno;    }    else    {        /* write to overflow file */        fno = task->ov_file;        addr = pg_ptr->ovfl_addr;    }    if ((sg = task->sgs[pg_ptr->file]) != NULL)    {        buff = task->enc_buff;        memcpy(buff, pg_ptr->buff, pgsize);        (*sg->enc)(sg->data, buff, pgsize);    }    else        buff = pg_ptr->buff;    dio_writefile(fno, addr, buff, pgsize, 0, task);#ifdef DB_DEBUG    if (task->db_debug & PAGE_CHECK)    {        if (fno != task->ov_file)        {            /* put page id back in header */            memcpy(pg_ptr->buff, &page_id, sizeof(DB_ADDR));        }    }#endif    if (task->db_status == S_OKAY)    {        if (fno != task->ov_file)            STAT_pg_write(fno, pgsize, task);        else            STAT_log_write(pgsize, task);    }    return (task->db_status);}/* ======================================================================    Read in a page to the buffer*/int INTERNAL_FCN dio_in(    PAGE_ENTRY *pg_ptr,    DB_TASK *task){    FILE_NO   fno;           /* file number */    short     pgsize;        /* page size */    off_t     addr;          /* file address */    int       extended;    DB_ULONG  extend = EXTENDFILES;    const SG *sg;    if (pg_ptr->buff == NULL)        return (dberr(S_INVPTR));    fno = pg_ptr->file;    pgsize = task->file_table[fno].ft_pgsize;    if (pg_ptr->buff_size != pgsize)        return (dberr(SYS_INVPGSIZE));        if (pg_ptr->ovfl_addr == 0L)    {        /* read from database file */        if (pg_ptr->pageno == 0)            return (dberr(SYS_PZACCESS));        addr = pgsize * (off_t)pg_ptr->pageno;        /* suppress file extend logic if called from dbCheck */        if (task->dboptions & NORECOVER)            extend = 0;#ifdef DB_DEBUG        else        {            /* suppress file extend logic if not at end of file */            if (pg_ptr->pageno < dio_pages(fno, task))                extend = 0;        }#endif    }    else    {        /* read from overflow file */        fno = task->ov_file;        addr = pg_ptr->ovfl_addr;    }    if ((sg = task->sgs[fno]) != NULL)    {        dio_readfile(fno, addr, task->enc_buff, pgsize, extend,                &extended, task);        (*sg->dec)(sg->data, task->enc_buff, pgsize);        memcpy(pg_ptr->buff, task->enc_buff, pgsize);    }    else    {        dio_readfile(fno, addr, pg_ptr->buff, pgsize, extend,                &extended, task);    }#ifdef DB_DEBUG    if (extended && !extend && !(task->dboptions & NORECOVER))    {        /* report the error if not dbCheck */        return (dberr(SYS_INVEXTEND));    }    if (task->db_status == S_OKAY && (task->db_debug & PAGE_CHECK))    {        if (fno != task->ov_file)        {            DB_ADDR page_id;            ENCODE_DBA(min(fno, 255), pg_ptr->pageno, &page_id);            memcpy(pg_ptr->buff, &page_id, sizeof(DB_ADDR));        }    }

⌨️ 快捷键说明

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