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

📄 pblkf.c

📁 B树算法实现
💻 C
📖 第 1 页 / 共 5 页
字号:
     */    rc = pblHtDelete( pblblockhash );    if( !rc )    {        /*         * the hash table was empty and is deleted now         */        pblblockhash = 0;    }    else    {        /*         * the hash table was not deleted because it is not         * empty, clear the error         */        pbl_errno = 0;    }    return( 0 );}/*------------------------------------------------------------------------------  FUNCTION:     pblBlockHashFind  DESCRIPTION:  Find a block reference in the hash table  RETURNS:      PBLBLOCK_t * retptr == 0: block not found                otherwise:                pointer to block in memory------------------------------------------------------------------------------*/static PBLBLOCK_t * pblBlockHashFind( long blockno, long bf ){    PBLBLOCKHASHKEY_t   key;    PBLBLOCKREF_t     * ref;    memset( &key, 0, sizeof( key ));    key.blockno = blockno;    key.bf      = bf;    /*     * if there is no hash table yet, the reference is not found     */    if( !pblblockhash )    {        return( 0 );    }    /*     * see whether we have the reference     */    ref = pblHtLookup( pblblockhash, &key, sizeof( key ));    if( !ref )    {        if( pbl_errno == PBL_ERROR_NOT_FOUND )        {            pbl_errno = 0;        }        return( 0 );    }    return( ref->block );}/* * BIGFILE functions *//* * find a filehandle of a filesystem file */static PBLBIGFILEHANDLE_t * pbf_fh_find( int bf, int n ){    PBLBIGFILEHANDLE_t * entry;    /*     * file system handles are kept in an LRU list     */    for( entry = pbf_ft_head; entry; entry = entry->next )    {        if( bf == entry->bf && n == entry->n )        {            if( entry != pbf_ft_head )            {                PBL_LIST_UNLINK( pbf_ft_head, pbf_ft_tail, entry, next, prev );                PBL_LIST_PUSH( pbf_ft_head, pbf_ft_tail, entry, next, prev );            }            return( entry );        }    }    return( 0 );}/* * close files with the filesystem */static void pbf_fh_close( int bf, int n ){    PBLBIGFILEHANDLE_t * entry;    PBLBIGFILEHANDLE_t * tmp;    if( n < 0 )    {        /*         * close all file handles of this big file         */        for( entry = pbf_ft_head; entry; )        {            tmp = entry;            entry = entry->next;            if( bf == tmp->bf )            {                close( tmp->fh );                PBL_LIST_UNLINK( pbf_ft_head, pbf_ft_tail, tmp, next, prev );                PBL_FREE( tmp );            }        }        return;    }    /*     * close a particular file handle     */    entry = pbf_fh_find( bf, n );    if( !entry )    {        return;    }    close( entry->fh );    PBL_LIST_UNLINK( pbf_ft_head, pbf_ft_tail, entry, next, prev );    PBL_FREE( entry );}/* * create the bigfile path of a file * bigfiles are stored in multiple filesystem files * if the first one is called "file.ext", * the others have names like "file_0002.ext" etc. */static char * pbf_fh_path( char * name, long n ){    char * path;    char * dotptr;    if( n < 1 )    {        /*         * the name of the first file does not change         */        path = strdup( name );        if( !path )        {            pbl_errno = PBL_ERROR_OUT_OF_MEMORY;            return( 0 );        }        return( path );    }    path = pbl_malloc( "pbf_fh_path path", 6 + strlen( name ));    if( !path )    {        return( 0 );    }    /*     * see if there is a ".ext" after the last slash     */    dotptr = strrchr( name, '.' );    if( dotptr )    {        if( strchr( dotptr, '/' ) || strchr( dotptr, '\\' ))        {            dotptr = 0;        }    }    /*     * build the filename, start counting at one     */    n++;    if( dotptr )    {        memcpy( path, name, dotptr - name );        snprintf( path + ( dotptr - name ), 6, "_%04lx", 0xffff & n );        strcat( path, dotptr );    }    else    {        strcpy( path, name );        snprintf( path + strlen( path ), 6, "_%04lx", 0xffff & n );    }    return( path );}/* * open a file with the file system */static int pbf_fh_open( char * name, int mode, int bf, int n ){    PBLBIGFILEHANDLE_t * entry;    int                  fh = -1;    int                  i;    char               * path;    /*     * look in LRU list of open filesystem files     */    entry = pbf_fh_find( bf, n );    if( entry )    {        if( entry->mode != mode )        {            /*             * the file was found, but the open mode is wrong, close the file             */            pbf_fh_close( bf, n );            entry = 0;        }        else        {            /*             * the file is open in the right mode, use the file handle             */            return( entry->fh );        }    }    /*     * open the file     */    path = pbf_fh_path( name, n );    if( !path )    {        return( -1 );    }    for( i = 0; i < 3; i++ )    {        fh = open( path, mode, S_IREAD | S_IWRITE );        if( -1 == fh && pbf_ft_tail )        {            /*             * maybe the process or the system ran out of filehandles             * close one file and try again             */            pbf_fh_close( pbf_ft_tail->bf, pbf_ft_tail->n );            continue;        }        break;    }    PBL_FREE( path );    if( -1 == fh )    {        pbl_errno = PBL_ERROR_OPEN;        return( -1 );    }    /*     * create and link the file handle list entry     */    entry = pbl_malloc0( "pbf_fh_open *entry", sizeof( *entry ));    if( !entry )    {        close( fh );        return( 0 );    }    entry->fh   = fh;    entry->mode = mode;    entry->bf   = bf;    entry->n    = n;    PBL_LIST_PUSH( pbf_ft_head, pbf_ft_tail, entry, next, prev );    return( entry->fh );}/* * close a bigfile */static int pbf_close( int bf ){    if( bf < 0 || bf >= PBL_NFILES )    {        return( -1 );    }    /*     * close all filesystem files     */    pbf_fh_close( bf, -1 );    PBL_FREE( pbf_pool[ bf ].name );    pbf_pool[ bf ].name = 0;    return( 0 );}/* * open a bigfile */static int pbf_open(char * name,int    update,long   blocksperfile,long   blocksize){    int        fh = -1;    int        mode;    int        i;    char     * path;    path = pbf_fh_path( name, 0 );    if( !path )    {        return( -1 );    }    if( update )    {        mode = O_CREAT | O_BINARY | O_RDWR;    }    else    {        mode = O_BINARY | O_RDONLY;    }    /*     * find a slot in the big file pool that is free     */    for( i = 0; i < PBL_NFILES; i++ )    {        if( pbf_pool[ i ].name )        {            continue;        }        /*         * reserve the slot         */        pbf_pool[ i ].mode = mode;        pbf_pool[ i ].nextblockno = -1;        pbf_pool[ i ].blocksperfile = blocksperfile;        pbf_pool[ i ].blocksize = blocksize;        /*         * open the first filesystem file         */        fh = pbf_fh_open( path, mode, i, 0 );        if( -1 == fh )        {            PBL_FREE( path );            pbl_errno = PBL_ERROR_OPEN;            return( -1 );        }        pbf_pool[ i ].name = path;        return( i );    }    PBL_FREE( path );    pbl_errno = PBL_ERROR_OPEN;    return( -1 );}/* * file io for a bigfile */static int pbf_blockio(int             bf,int             blockwrite,long            blockno,unsigned char * buffer){    long       rc = -1;    long       n;    int        fh;    int        i;    int        j;    long       offset;    if( bf < 0 || bf >= PBL_NFILES || !pbf_pool[ bf ].name )    {        pbl_errno = PBL_ERROR_BAD_FILE;        return( -1 );    }    /*     * make sure the n'th filesystem file is open     */    n = blockno / pbf_pool[ bf ].blocksperfile;    fh = pbf_fh_open( pbf_pool[ bf ].name, pbf_pool[ bf ].mode, bf, n );    if( -1 == fh )    {        pbl_errno = PBL_ERROR_READ;        return( -1 );    }    blockno %= pbf_pool[ bf ].blocksperfile;    offset = blockno * pbf_pool[ bf ].blocksize;    if( blockwrite )    {        /*         * try the write more than once if needed         */        for( i = 0; i < 3; i++ )        {            /*             * try the seek more than once if needed             */            for( j = 0; j < 3; j++ )            {                rc = lseek( fh, offset, SEEK_SET );                if( offset != rc )                {                    continue;                }                break;            }            if( offset != rc )            {                pbl_errno = PBL_ERROR_SEEK;                return( -1 );            }            rc = write( fh, buffer, (unsigned int) pbf_pool[ bf ].blocksize );            if( rc != pbf_pool[ bf ].blocksize )            {                if( errno == EINTR )                {                    continue;                }                pbl_errno = PBL_ERROR_WRITE;                return( -1 );            }            break;        }        if( i >= 3 )        {            pbl_errno = PBL_ERROR_WRITE;            return( -1 );        }        pblnwrites++;    }    else    {        /*         * try the read more than once if needed         */        for( i = 0; i < 3; i++ )        {            /*             * try the seek more than once if needed             */            for( j = 0; j < 3; j++ )            {                rc = lseek( fh, offset, SEEK_SET );                if( offset != rc )                {                    continue;                }                break;            }            if( offset != rc )            {                pbl_errno = PBL_ERROR_SEEK;                return( -1 );            }            rc = read( fh, buffer, (unsigned int) pbf_pool[ bf ].blocksize );            if( rc < 0 )            {                if( errno == EINTR )                {                    continue;                }                pbl_errno = PBL_ERROR_READ;                return( -1 );            }            pblnreads++;            if( rc != pbf_pool[ bf ].blocksize )            {                if( errno == EINTR )                {                    continue;                }                pbl_errno = PBL_ERROR_BAD_FILE;                return( -1 );            }            break;        }        if( i >= 3 )        {            pbl_errno = PBL_ERROR_READ;            return( -1 );        }    }    return( 0 );}/*

⌨️ 快捷键说明

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