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

📄 pblisam.c

📁 B树算法实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  DESCRIPTION:  commit or rollback changes done during a transaction                on a single ISAM file  RESTRICTIONS: transactions can be nested, if so the commit                only happens when the outermost transaction                calls a commit.                the commit only happens to process space buffer cache,                call pblIsamFlush() after pblIsamCommitFile() if you want to                flush to kernel space buffer cache.   RETURNS:      int rc == 0: the commit went ok                int rc >  0: a rollback happened,                             either because the caller requested it                             or because an inner transaction                             resulted in a rollback                 int rc <  0: an error see pbl_errno------------------------------------------------------------------------------*/static int pblIsamCommitFile( PBLISAMFILE_t * isam, int rollback ){    int n;    /*     * remember if this is a rollback     */    if( rollback )    {        isam->rollback = 1;    }    else    {        /*         * find out if any of the keyfiles needs a rollback         * do this by starting another transaction on the ISAM file         * if any of the index files have a rollback isam->rollback is set!         */        pblIsamStartTransOnFile( isam );        /*         * commit the main file transaction started above         */        pblKfCommit( isam->mainfile, isam->rollback );    }    /*     * commit the outer transaction on the main file     */    pblKfCommit( isam->mainfile, isam->rollback );    /*     * do the rollback or commit on all key files     */    for( n = 0; n < isam->nkeys; n++ )    {        if( !rollback )        {            /*             * commit the transaction started above             */            pblKfCommit( isam->keyfiles[ n ], isam->rollback );        }        /*         * commit the outer transaction         */        pblKfCommit( isam->keyfiles[ n ], isam->rollback );    }    if( !rollback )    {        /*         * count the transaction started above         */        isam->transactions -= 1;    }    /*     * we have one transaction less on the ISAM file     */    isam->transactions -= 1;    return( isam->rollback );}/** * commit or rollback changes done during a transaction * * transactions can be nested, if so the commit * only happens when the outermost transaction * calls a commit. * * the commit only happens to process space buffer cache, * call \Ref{pblIsamFlush}() after \Ref{pblIsamCommit}() if you want to * flush to kernel space buffer cache. * * @return int rc == 0: the commit went ok * @return int rc >  0: a rollback happened, either because the caller *                      requested it or because an inner transaction resulted *                      in a rollback * @return int rc <  0: some error, see pbl_errno */int pblIsamCommit(int nfiles,                  /** number of files in ISAM file list      */pblIsamFile_t ** isamfiles,  /** ISAM file list to commit changes of    */int rollback       /** != 0: roll back the changes, == 0: commit the changes  */){    PBLISAMFILE_t ** files = ( PBLISAMFILE_t ** ) isamfiles;    int n;    int dorollback = rollback;    if( !rollback )    {        /*         * find out if any of the files needs a rollback         * do this by starting another transaction on the file set         * if any of the ISAM files have a rollback dorollback is set!         */        if( pblIsamStartTransaction( nfiles, isamfiles ) > 0 )        {            dorollback = 1;        }    }    /*     * commit or rollback all files in the set     */    for( n = 0; n < nfiles; n++ )    {        if( !rollback )        {            /*             * commit the transaction done above             */            pblIsamCommitFile( files[ n ], dorollback );        }        /*         * commit the outer transaction         */        pblIsamCommitFile( files[ n ], dorollback );    }    return( dorollback );}/** * open an ISAM file, creates the file if necessary * * if update is 0, the ISAM file is opened for read access only, * if update is not 0 the ISAM file is opened for reading and writing * * a file set tag can be attached to the ISAM file, * if a file having a non NULL file set tag is flushed * to disk all files having the same file set tag attached * are flushed as well. * * @return  pblIsamFile_t * retptr == NULL: an error occured, see pbl_errno * @return  pblIsamFile_t * retptr != NULL: a pointer to an ISAM file descriptor */pblIsamFile_t * pblIsamOpen(char * path,         /** path of file to create                               */int    update,       /** flag: should file be opened for update?              */void * filesettag,   /** filesettag, for flushing multiple files consistently */int    nkeys,        /** number of key files to create                        */char **keyfilenames, /** list of names of key index files to create           */int  * keydup        /** flaglist: is the i'th index key a duplicate key?     */){    char          * ptr;    char          * keyfile;    PBLISAMFILE_t * isam;    int             i;    /*     * create the descriptor     */    isam = pbl_malloc0( "pblIsamOpen ISAMFILE", sizeof( PBLISAMFILE_t ));    if( !isam )    {        return( 0 );    }    /*     * if the user did not specify an external file set tag     * the isam file descriptor is used in order to make sure     * all key files of the isam file are flushed at the same time     */    if( update && !filesettag )    {        filesettag = isam;    }    isam->nkeys = nkeys;    if( isam->nkeys )    {        /*         * create space for pointers to key file descriptors         */        isam->keyfiles = pbl_malloc0( "pblIsamOpen keyfiles",                                       nkeys * sizeof( pblKeyFile_t * ));        if( !isam->keyfiles )        {            PBL_FREE( isam );            return( 0 );        }        /*         * save the duplicate key flags for all keys         */        isam->keydup = pbl_memdup( "pblIsamOpen keydup",                                    keydup, nkeys * sizeof( int * ));        if( !isam->keydup )        {            PBL_FREE( isam->keyfiles );            PBL_FREE( isam );            pbl_errno = PBL_ERROR_OUT_OF_MEMORY;            return( 0 );        }        /*         * create the array of keycompare functions for all keys         */        isam->keycompare = pbl_malloc0( "pblIsamOpen keycompare",                                        nkeys * sizeof( void * ));        if( !isam->keycompare )        {            PBL_FREE( isam->keydup );            PBL_FREE( isam->keyfiles );            PBL_FREE( isam );            pbl_errno = PBL_ERROR_OUT_OF_MEMORY;            return( 0 );        }    }    /*     * open the main file     */    if( update )    {        /*         * try to create         */        isam->mainfile = pblKfCreate( path, filesettag );    }    if( !isam->mainfile )    {        /*         * try to open         */        isam->mainfile = pblKfOpen( path, update, filesettag );        /*         * if the main file is not open         */        if( !isam->mainfile )        {            PBL_FREE( isam->keycompare );            PBL_FREE( isam->keydup );            PBL_FREE( isam->keyfiles );            PBL_FREE( isam );            return( 0 );        }    }    /*     * if the name of the main file has a directory part     * and the names of the index files do not     * we prepend the directory part of the main file to     * the names of the index files     *     * get a pointer to last / or \ in path     */    ptr = strrchr( path, '/' );    keyfile = strrchr( path, '\\' );    if( ptr )    {        if( keyfile > ptr )        {            ptr = keyfile;        }    }    else    {        ptr = keyfile;    }    if( ptr )    {        /*         * set pointer to the character after the slash         */        ptr++;    }    /*     * open all key files     */    for( i = 0; i < nkeys; i++ )    {        /*         * if the path contains a directory part         * and the name of the keyfile does not         */        if( ptr         && !strchr( keyfilenames[ i ], '/' )         && !strchr( keyfilenames[ i ], '\\' ))        {            /*             * build the the path to the keyfile             */            keyfile = pbl_mem2dup( "pblIsamOpen keyfile",                                   path, ptr - path,                                   keyfilenames[ i ],                                   strlen( keyfilenames[ i ] ) + 1 );        }        else        {            /*             * use keyfile name as given             */            keyfile = strdup( keyfilenames[ i ] );        }        if( !keyfile )        {            pblKfClose( isam->mainfile );            PBL_FREE( isam->keycompare );            PBL_FREE( isam->keydup );            PBL_FREE( isam->keyfiles );            PBL_FREE( isam );            pbl_errno = PBL_ERROR_OUT_OF_MEMORY;            return( 0 );        }        if( update )        {            /*             * try create             */            isam->keyfiles[ i ] = pblKfCreate( keyfile, filesettag );        }        if( !isam->keyfiles[ i ] )        {            /*             * try open             */            isam->keyfiles[ i ] = pblKfOpen( keyfile, update, filesettag );        }        if( !isam->keyfiles[ i ] )        {            int j;            for( j = 0; j < i; j++ )            {                pblKfClose( isam->keyfiles[ j ] );            }            pblKfClose( isam->mainfile );            PBL_FREE( keyfile );            PBL_FREE( isam->keycompare );            PBL_FREE( isam->keydup );            PBL_FREE( isam->keyfiles );            PBL_FREE( isam );            return( 0 );        }        /*         * set our custom compare function for keyfiles allowing         * duplicate keys         */        if( isam->keydup[ i ] )        {            pblKfSetCompareFunction( isam->keyfiles[ i ], pblIsamDupKeyCompare);        }        /*         * the key file is open, we don't need its name anymore         */        PBL_FREE( keyfile );    }    isam->magic = rcsid;    return( ( pblIsamFile_t * )isam );}/** * close an ISAM file * * all changes are flushed to disk before, * all memory allocated for the file is released. * * @return int rc == 0: call went ok, file is closed * @return int rc != 0: some error, see pbl_errno */int pblIsamClose(pblIsamFile_t * isamfile           /** ISAM file to close */){    PBLISAMFILE_t * isam = ( PBLISAMFILE_t * ) isamfile;    int             rc = 0;    int             i;    int             saveerrno = 0;    /*     * close all the keyfiles     */    for( i = 0; i < isam->nkeys; i++ )    {        if( pblKfClose( isam->keyfiles[ i ] ))        {            saveerrno = pbl_errno;            rc = -1;        }    }    /*     * close the main file     */    if( pblKfClose( isam->mainfile ))    {        saveerrno = pbl_errno;        rc = -1;    }    PBL_FREE( isam->keycompare );    PBL_FREE( isam->keydup );    PBL_FREE( isam->keyfiles );    PBL_FREE( isam );    if( rc )    {        pbl_errno = saveerrno;    }    return( rc );}/** * flush an ISAM file * * all changes are flushed to disk, * * @return int rc == 0: call went ok * @return int rc != 0: some error, see pbl_errno */int pblIsamFlush(pblIsamFile_t * isamfile           /** ISAM file to flush */){    PBLISAMFILE_t * isam = ( PBLISAMFILE_t * ) isamfile;    int             rc = 0;    int             i;    int             saveerrno = 0;    /*     * flush all the keyfiles     */    for( i = 0; i < isam->nkeys; i++ )    {        if( pblKfFlush( isam->keyfiles[ i ] ))        {            saveerrno = pbl_errno;            rc = -1;        }    }    /*     * flush the main file     */    if( pblKfFlush( isam->mainfile ))    {        saveerrno = pbl_errno;        rc = -1;    }    if( rc )    {        pbl_errno = saveerrno;    }    return( rc );}/* * set the current record of the main file * used after deletes of records in the main file */static int pblIsamSetCurrentRecord( PBLISAMFILE_t * isam ){    long datalen;    char okey[ PBLKEYLENGTH ];    int  okeylen;    int  saveerrno = pbl_errno;    /*     * read the key of the current record in the main file     */    datalen = pblKfThis( isam->mainfile, okey, &okeylen );    if( datalen >= 0 )    {        if( okeylen == 9 )        {

⌨️ 快捷键说明

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