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

📄 dio.c

📁 db.* (pronounced dee-be star) is an advanced, high performance, small footprint embedded database fo
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif    if (task->db_status == S_OKAY)    {        if (fno != task->ov_file)        {            if (extended)            {                STAT_pg_write(fno, pgsize, task);                STAT_new_page(fno, task);            }            else                STAT_pg_read(fno, pgsize, task);        }        else            STAT_log_read(pgsize, task);    }    return (task->db_status);}/*---------------------------------------------------------------------//----------------------------------------------------------------------/    Page zero handling functions for data and key files/----------------------------------------------------------------------//---------------------------------------------------------------------*//* ======================================================================    Initialize page zero table*/int EXTERNAL_FCN dio_pzinit(DB_TASK *task){    register FILE_NO i;    PGZERO          *pgzero_ptr;    size_t           size;    size_t           old;    size = task->size_ft * sizeof(PGZERO);    old  = task->old_size_ft * sizeof(PGZERO);    if (alloc_table((void **) &task->pgzero, size, old, task) != S_OKAY)        return (task->db_status);    /* read in page zeros */    for (i = task->old_size_ft, pgzero_ptr = &task->pgzero[task->old_size_ft];         i < task->size_ft; ++i, ++pgzero_ptr)        memset(pgzero_ptr, '\0', sizeof(PGZERO));    return (task->db_status);}/* ======================================================================    Free the memory allocated for page zeros*/static void INTERNAL_FCN dio_pzfree(int dbn, DB_TASK *task){    int low, high, total;    if (dbn == ALL_DBS)    {        low = 0;        high = task->size_ft;        total = task->size_ft;    }    else    {        low = task->db_table[dbn].ft_offset;        high = low + task->db_table[dbn].Size_ft;        total = task->size_ft;    }    if (task->pgzero) {        free_table((void **) &task->pgzero, low, high, total, sizeof(PGZERO),                task);    }}/* ======================================================================    Increment and return file timestamp*/DB_ULONG INTERNAL_FCN dio_pzsetts(FILE_NO fno, DB_TASK *task){    DB_ULONG    ts;    PGZERO     *pgzero_ptr;    if (task->db_tsrecs || task->db_tssets)    {        if ((task->pgzero[fno].pz_next == (F_ADDR) 0          &&  dio_pzread(fno, task) != S_OKAY)#ifdef DB_DEBUG          || dio_pzcheck(fno, task) != S_OKAY#endif          )            return 0L;        pgzero_ptr = &task->pgzero[fno];        if (++pgzero_ptr->pz_timestamp == 0L)            pgzero_ptr->pz_timestamp = 1L;        pgzero_ptr->pz_modified = TRUE;        task->file_table[fno].ft_flags |= TS_IS_CURRENT;        ts = pgzero_ptr->pz_timestamp;    }    else    {        ts = 0L;    }    return (ts);}/* ======================================================================    Return file timestamp*/DB_ULONG INTERNAL_FCN dio_pzgetts(FILE_NO fno, DB_TASK *task){    PGZERO    *pgzero_ptr;    pgzero_ptr = &task->pgzero[fno];        if ((task->pgzero[fno].pz_next == (F_ADDR) 0      &&  dio_pzread(fno, task) != S_OKAY)#ifdef DB_DEBUG      || dio_pzcheck(fno, task) != S_OKAY#endif      )        return 0L;    if (task->trans_id[0])        o_fileinit(fno, task);    if (! (task->file_table[fno].ft_flags & TS_IS_CURRENT))        dio_pzsetts(fno, task);    return (pgzero_ptr->pz_timestamp);}/* ======================================================================    Flush page zero table*/static int INTERNAL_FCN dio_pzflush(DB_TASK *task){    register FILE_NO       i;    register PGZERO       *pgzero_ptr;    register FILE_ENTRY   *file_ptr;    void                  *buff;    const SG              *sg;    if ((task->dboptions & TRLOGGING) && task->trans_id[0] && (! task->trcommit))    {        /* flush to overflow/log file -- before tx commit */        for (i = 0, pgzero_ptr = task->pgzero, file_ptr = task->file_table;             i < task->size_ft;             ++i, ++pgzero_ptr, ++file_ptr)        {            if (pgzero_ptr->pz_modified && !(file_ptr->ft_flags & TEMPORARY))            {#ifdef DB_DEBUG                if (dio_pzcheck(i, task) != S_OKAY)                    return (task->db_status);#endif                if (o_pzwrite(i, task) != S_OKAY)                    return (task->db_status);            }        }    }    else    {        /* flush modified page zeroes to database files */        for (i = 0, pgzero_ptr = task->pgzero, file_ptr = task->file_table;                i < task->size_ft; ++i, ++pgzero_ptr, ++file_ptr)        {            if (pgzero_ptr->pz_modified && !(file_ptr->ft_flags & TEMPORARY))            {#ifdef DB_DEBUG                if (dio_pzcheck(i, task) != S_OKAY)                    return (task->db_status);#endif                if ((sg = task->sgs[i]) != NULL)                {                    buff = task->enc_buff;                    memcpy(buff, pgzero_ptr, PGZEROSZ);                    (*sg->enc)(sg->data, buff, PGZEROSZ);                }                else                    buff = pgzero_ptr;                if (dio_writefile(i, 0L, buff, PGZEROSZ, 0, task) != S_OKAY)                    return (task->db_status);                STAT_pz_write(i, PGZEROSZ, task);                                pgzero_ptr->pz_modified = FALSE;                if (task->trlog_flag)                    dtrlog(i, 0L, (char *) pgzero_ptr, PGZEROSZ, task);                /* Since the file is getting committed immediately,                    there is no need to set the NEEDS_COMMIT flag.                */                commit_file(task->file_table[i].ft_desc, task);                task->file_table[i].ft_flags &= ~(NEEDS_COMMIT | TS_IS_CURRENT);            }        }    }    return (task->db_status);}/* ======================================================================    Read a file's page zero*/int EXTERNAL_FCN dio_pzread(FILE_NO fno, DB_TASK *task){    PGZERO   *pgzero_ptr = &task->pgzero[fno];    const SG *sg;    PSP_FH    desc;    if (dio_open(fno, task) != S_OKAY)        return task->db_status;            desc = task->file_table[fno].ft_desc;    if (psp_fileSeekRead(desc, 0, pgzero_ptr, PGZEROSZ) < (int) PGZEROSZ)    {        dberr(S_BADREAD);        pgzero_ptr->pz_dchain = (F_ADDR) 0;        pgzero_ptr->pz_next = (F_ADDR) 0;        pgzero_ptr->pz_timestamp = 0L;        pgzero_ptr->pz_modified = FALSE;        task->file_table[fno].ft_flags &= (~TS_IS_CURRENT);        goto exit;    }    if ((sg = task->sgs[fno]) != NULL)        (*sg->dec)(sg->data, pgzero_ptr, PGZEROSZ);    STAT_pz_read(fno, PGZEROSZ, task);#ifdef DB_DEBUG    if (task->db_debug & PZVERIFY)    {        pgzero_ptr->file_size = psp_fileLength(task->file_table[fno].ft_desc);        if (pgzero_ptr->file_size != -1L)        {            long pz_file_size;            FILE_ENTRY *file_ptr = &task->file_table[fno];            /* round the size down to the nearest page boundary */            pgzero_ptr->file_size -= (pgzero_ptr->file_size % file_ptr->ft_pgsize);            /* calculate the size that we'd expect from pz_next */            pz_file_size  = pgzero_ptr->pz_next - 1;  /* number of slots */            pz_file_size += file_ptr->ft_slots - 1;   /* round up to next page */            pz_file_size /= file_ptr->ft_slots;       /* number of pages */            pz_file_size++;                           /* add 1 for page 0 */            pz_file_size *= file_ptr->ft_pgsize;      /* number of bytes */            /*                The actual file size may be larger than we would expect from                 pz_next, as there may be some newly created records that were                written to the end of the file before a transaction was aborted.                The actual size should not be less than the value calculated                from pz_next, but it seems that psp_fileLength sometimes returns                a value that is not current, so allow some error.            */            if (pz_file_size > pgzero_ptr->file_size)            {                if ((pz_file_size - pgzero_ptr->file_size)                      > (32 * file_ptr->ft_pgsize))                {                    /* more than 32 pages - pznext probably corrupted */                    return (dberr(SYS_PZNEXT));                }                /* assume value returned by psp_fileLength is wrong */                pgzero_ptr->file_size = pz_file_size;            }        }    }#endifexit:#ifdef DB_DEBUG    if (task->db_debug & LOCK_CHECK)        pgzero_ptr->file_mtime = psp_fileModTime(desc);#endif    return (task->db_status);}/* ======================================================================    Allocate new record slot or key node from page zero*/int EXTERNAL_FCN dio_pzalloc(    FILE_NO  fno,              /* file number */    F_ADDR  *loc,              /* pointer to allocated location */    DB_TASK *task){    DB_ADDR    dba;    DB_ULONG   pg;    char      *ptr;    PGZERO    *pgzero_ptr;    /* check shared access privileges */    if ((task->dbopen == 1) && !task->trans_id[0] && !task->excl_locks[fno])        return (dberr(S_NOTRANS));    pgzero_ptr = &task->pgzero[fno];    if ((pgzero_ptr->pz_next == (F_ADDR) 0        && dio_pzread(fno, task) != S_OKAY)#ifdef DB_DEBUG        || dio_pzcheck(fno, task) != S_OKAY#endif      )        return (task->db_status);        if (task->trans_id[0] && o_fileinit(fno, task) != S_OKAY)        return (task->db_status);        if (task->file_table[fno].ft_type == KEY)    {        if ((pgzero_ptr->pz_dchain == DCH_NONE) || (! (task->dboptions & DCHAINUSE)))        {            if (pgzero_ptr->pz_next >= MAXRECORDS - 1)                return (dberr(S_RECLIMIT));            pg = pgzero_ptr->pz_next++;        }        else        {            pg = pgzero_ptr->pz_dchain;            if (dio_get(fno, pg, &ptr, NOPGHOLD, task) != S_OKAY)                return (task->db_status);            memcpy(&pgzero_ptr->pz_dchain,                ptr + sizeof(long) + sizeof(short), sizeof(F_ADDR));            if (dio_unget(fno, pg, NOPGFREE, task) != S_OKAY)                return (task->db_status);        }    }    else    {        if ((! pgzero_ptr->pz_dchain) || (! (task->dboptions & DCHAINUSE)))        {            if (pgzero_ptr->pz_next >= MAXRECORDS)                return (dberr(S_RECLIMIT));            pg = pgzero_ptr->pz_next++;        }        else        {            pg = pgzero_ptr->pz_dchain;            ENCODE_DBA(NUM2EXT(fno, ft_offset), pg, &dba);            if (dio_read(dba, (char **) &ptr,                         NOPGHOLD, task) != S_OKAY)                return (task->db_status);            memcpy(&pgzero_ptr->pz_dchain,                ptr + sizeof(short), sizeof(F_ADDR));            if (dio_release(dba, NOPGFREE, task) != S_OKAY)                return (task->db_status);        }    }    *loc = pg;    pgzero_ptr->pz_modified = TRUE;    return (task->db_status);}/* ======================================================================    Delete record slot or key node from page zero*/int EXTERNAL_FCN dio_pzdel(    FILE_NO fno,                           /* file number */    F_ADDR  loc,                            /* location to be freed */    DB_TASK *task){    DB_ADDR       dba;    short         recnum;    char         *ptr;    PGZERO       *pgzero_ptr;    /* check shared access privileges */    if ((task->dbopen == 1) && !task->trans_id[0] && !task->excl_locks[fno])        return (dberr(S_NOTRANS));    pgzero_ptr = &task->pgzero[fno];    if ((pgzero_ptr->pz_next == (F_ADDR) 0        && dio_pzread(fno, task) != S_OKAY)#ifdef DB_DEBUG        || dio_pzcheck(fno, task) != S_OKAY#endif      )        return (task->db_status);    if (task->file_table[fno].ft_type == KEY)    {        if (dio_get(fno, loc, &ptr, PGHOLD, task) != S_OKAY)            return (task->db_status);        memcpy(ptr + sizeof(long) + sizeof(short),            &pgzero_ptr->pz_dchain, sizeof(F_ADDR));        pgzero_ptr->pz_dchain = loc;        if (dio_touch(fno, loc, PGFREE, task) != S_OKAY)            return (task->db_status);    }    else    {        ENCODE_DBA(NUM2EXT(fno, ft_offset), loc, &dba);        if (dio_read(dba, &ptr, PGHOLD, task) != S_OKAY)            return (task->db_status);        memcpy(&recnum, ptr, sizeof(short));        recnum &= ~RLBMASK;              /* in case the RLB is set [624] */        recnum = (short) ~recnum;     /* indicates deleted record */        memcpy(ptr, &recnum, sizeof(short));        memcpy(ptr + sizeof(short), &pgzero_ptr->pz_dchain, sizeof(F_ADDR));        pgzero_ptr->pz_dchain = loc;        if (dio_write(dba, PGFREE, task) != S_OKAY)            return (task->db_status);    }    pgzero_ptr->pz_modified = TRUE;    return (task->db_status);}/* =====

⌨️ 快捷键说明

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