📄 ovfcns.c
字号:
(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 + -