/* PROGRAM: dsmMandFindEntry - find the meta_filectl entry by dbkey or table * number (preferably by table number) in the shared memory mandatory * structures; fills in a pointer passed to it. ASSUMES that the caller has * obtained the appropriate (MT_LOCK_SCC()) latch before calling */ dsmStatus_t dsmMandFindEntry( dsmContext_t *pcontext, struct meta_filectl **ppmetactl, dsmDbkey_t fileDbkey, /* dbkey of _file record */ int fileNumber, /* file # of _file record */ dsmBoolean_t fileKey) /* dbkey/file# of _file */ { dbcontext_t *pdbcontext = pcontext->pdbcontext; dbshm_t *pdbshm = pcontext->pdbcontext->pdbpub; SHPTR *pmandhashtbl, qhashentry; struct meta_filectl *pmetactl = NULL; int tempi; if (pdbshm->qmandctl == 0) { *ppmetactl = NULL; return DSM_S_FAILURE; } pmandhashtbl = (SHPTR *) QP_TO_P(pdbcontext, pdbshm->qmandctl); if (fileKey == FILE_IDENT_FILNO) { qhashentry = pmandhashtbl[ABS(fileNumber) % SIZE_MAND_HASH]; for (pmetactl = (META_FILECTL *)QP_TO_P(pdbcontext, qhashentry); (pmetactl != NULL) && (pmetactl->filno != fileNumber); pmetactl = XMETACTL(pdbcontext, pmetactl->qnext)) ; } else { for (tempi = 0, pmetactl = NULL; pmetactl == NULL && tempi < SIZE_MAND_HASH; tempi++) { qhashentry = pmandhashtbl[tempi]; for (pmetactl = (META_FILECTL *)QP_TO_P(pdbcontext, qhashentry); pmetactl; pmetactl = (META_FILECTL *)QP_TO_P(pdbcontext, pmetactl->qnext)) { if (pmetactl->fildbk == fileDbkey) break; } } } *ppmetactl = pmetactl; return DSM_S_SUCCESS; }
/* PROGRAM: rlaiseto - initialize aictl and buffers */ DSMVOID rlaiseto (dsmContext_t *pcontext) { dbcontext_t *pdbcontext = pcontext->pdbcontext; dbshm_t *pdbpub = pdbcontext->pdbpub; AICTL *paictl; BKTBL *pbktbl; AIBUF *paibuf = (AIBUF *)0; AIBUF *pn; int i; /* *** TODO: there is a memory leak when peforming aimage begin on a * database that has 2phase on already rlaiseto is called twice. Not * a big deal, but something to remember. */ if (pdbcontext->paictl != NULL) { /* memory leak! */ } /* allocate the ai control structure */ paictl = (AICTL *)stGet(pcontext, (STPOOL *)QP_TO_P(pdbcontext, pdbpub->qdbpool), sizeof(AICTL)); pdbpub->qaictl = P_TO_QP(pcontext, paictl); pdbcontext->paictl = paictl; /* initialize blocksize information based on masterblock info */ paictl->aiblksize = pdbcontext->pmstrblk->mb_aiblksize; paictl->aiFileType = BKAI; /* initialize block size log and mask constants for quick calculations */ paictl->aiblklog = bkblklog(paictl->aiblksize); paictl->aiblkmask = (ULONG)0xFFFFFFFF << paictl->aiblklog; /* * allocate buffer for ai writer to use for writing. This buffer is * used for making a copy of the current buffer prior to writing * it so that the ai writer can be writing while others are storing * more data in the next output buffer. Also used during extent switches. */ pbktbl = &paictl->aiwbktbl; QSELF (pbktbl) = P_TO_QP(pcontext, pbktbl); pbktbl->bt_raddr = -1; pbktbl->bt_dbkey = -1; /* BUM - Assuming aiFileType < 256 */ pbktbl->bt_ftype = (TEXT)paictl->aiFileType; if ( paictl->aiFileType == BKAI ) { paictl->aiArea = rlaiGetNextArea(pcontext, 1); if( pdbcontext->pmstrblk->mb_aibusy_extent ) { paictl->aiArea = pdbcontext->pmstrblk->mb_aibusy_extent; } } else { paictl->aiArea = DSMAREA_TL; } pbktbl->bt_area = paictl->aiArea; bmGetBufferPool(pcontext, pbktbl); /* must have at least one ai buffer */ if (pdbpub->argaibufs < 1) pdbpub->argaibufs = 1; /* allocate a ring of output ai buffer control blocks */ pn = NULL; for (i = pdbpub->argaibufs; i > 0; i--) { paibuf = (AIBUF *)stGet (pcontext, (STPOOL *)QP_TO_P(pdbcontext, pdbpub->qdbpool), sizeof(AIBUF)); QSELF (paibuf) = P_TO_QP(pcontext, paibuf); if (pn) { /* set previous buffer's link to next buffer in chain */ pn->aiqnxtb = QSELF (paibuf); } else { /* this is the first, current, and next to write buffer */ paictl->aiqbufs = QSELF (paibuf); paictl->aiqcurb = QSELF (paibuf); paictl->aiqwrtb = QSELF (paibuf); } pn = paibuf; } /* link the last one to the first one */ paibuf->aiqnxtb = paictl->aiqbufs; /* now allocate the ai block buffers themselves */ pn = XAIBUF(pdbcontext, paictl->aiqbufs); for (i = pdbpub->argaibufs; i > 0; i--) { pbktbl = &(pn->aibk); QSELF (pbktbl) = P_TO_QP(pcontext, pbktbl); pbktbl->bt_raddr = -1; pbktbl->bt_dbkey = -1; pbktbl->bt_area = paictl->aiArea; /* BUM - Assuming UCOUNT aiFileType < 256 */ pbktbl->bt_ftype = (TEXT)paictl->aiFileType; bmGetBufferPool(pcontext, pbktbl); pn = XAIBUF(pdbcontext, pn->aiqnxtb); } } /* rlaiseto */
/* PROGRAM: dsmMandatoryFieldsCachePut - build mandatory field cache and it * is stored in shared memory * * RETURNS: DSM_S_SUCCES * */ dsmStatus_t dsmMandatoryFieldsPut(dsmContext_t *pcontext, struct meta_filectl *pInMetactl, /* new metadata ctl for cache */ struct meta_filectl *pOldmetactl, /* old metadata ctl for cache */ DL_VECT *pdl_vect_in, /* next dl column vector */ DL_VECT *pdl_col_in, /* next dl columns list to use */ int ndl_ent, /* # delayed columns */ int mandtblSize, /* size of mand fld table */ int useCache, /* use shm cache ? */ struct mand *pmand) /* storage for all mand flds */ { dbcontext_t *pdbcontext = pcontext->pdbcontext; dbshm_t *pdbshm = pdbcontext->pdbpub; dsmStatus_t returnCode; SHPTR *pmandhashtbl, qhashentry; struct meta_filectl *pmetactl = NULL; pdbcontext->inservice++; /* postpone signal handler processing */ SETJMP_ERROREXIT(pcontext, returnCode) /* Ensure error exit address set */ if ((returnCode = dsmThreadSafeEntry(pcontext)) != DSM_S_SUCCESS) { returnCode = dsmEntryProcessError(pcontext, returnCode, (TEXT *)"dsmMandatoryFieldsPut"); goto done; } /* get the schema cache latch */ MT_LOCK_SCC (); /* Check if the entry already exists */ dsmMandFindEntry(pcontext, &pmetactl, pInMetactl->fildbk, pInMetactl->filno, FILE_IDENT_DBKEY); if (pmetactl != NULL) { /* entry had already been made */ goto okdone; } /* get ptr to hash table array */ if (pdbshm->qmandctl) pmandhashtbl = (SHPTR *) QP_TO_P(pdbcontext, pdbshm->qmandctl); else /* need to allocate it */ { pmandhashtbl = (SHPTR *) stRent(pcontext, XSTPOOL(pdbcontext, pdbshm->qdbpool), SIZE_MAND_HASH * sizeof(SHPTR)); pdbshm->qmandctl = P_TO_QP(pcontext, pmandhashtbl); } /* allocate storage in shm */ pmetactl = (struct meta_filectl *)stRent(pcontext, XSTPOOL(pdbcontext, pdbshm->qdbpool), (unsigned)(sizeof(struct meta_filectl) + mandtblSize)); pmetactl->fildbk = pInMetactl->fildbk; pmetactl->filno = pInMetactl->filno; pmetactl->nmand = pInMetactl->nmand; pmetactl->schemavers = pInMetactl->schemavers; if ( (useCache != MANB_USECACHE_NONE) && (mandtblSize > 0) ) { bufcop(pmetactl->mand, pmand, (int) mandtblSize); } if ((useCache == MANB_USECACHE_PHYSICAL) && (pOldmetactl != NULL)) { pOldmetactl->filno = 0; pOldmetactl->fildbk = 0; } /* Chain this structure in shared memory. The assumption is that an entry for this fildbk does not already exist on the cache. */ qhashentry = pmandhashtbl[ABS(pmetactl->filno) % SIZE_MAND_HASH]; pmetactl->qnext = qhashentry; pmandhashtbl[ABS(pmetactl->filno) % SIZE_MAND_HASH] = P_TO_QP(pcontext, pmetactl); DEBUG_FPRINTF(pmetactl, "dbmanb (chained to sh mem):"); okdone: MT_UNLK_SCC (); returnCode = DSM_S_SUCCESS; done: dsmThreadSafeExit(pcontext); pdbcontext->inservice--; return returnCode; }