db_alloc.c

Go to the documentation of this file.
00001 /*                      D B _ A L L O C . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1988-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup db4 */
00023 
00024 /*@{*/
00025 /** @file db_alloc.c
00026  *
00027  * Functions -
00028  *      - db_alloc      Find a contiguous block of database storage
00029  *      - db_delete     Delete storage associated w/entry, zap records
00030  *      - db_zapper     Zap region of file into ID_FREE records
00031  *
00032  *
00033  *  Authors -
00034  *      Michael John Muuss
00035  *      Robert Jon Reschly Jr.
00036  *
00037  *  Source -
00038  *      SECAD/VLD Computing Consortium, Bldg 394
00039  *      The U. S. Army Ballistic Research Laboratory
00040  *      Aberdeen Proving Ground, Maryland  21005-5066
00041  *
00042  */
00043 
00044 #ifndef lint
00045 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/db_alloc.c,v 14.11 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00046 #endif
00047 
00048 #include "common.h"
00049 
00050 #include <stdio.h>
00051 #ifdef HAVE_STRING_H
00052 #  include <string.h>
00053 #else
00054 #  include <strings.h>
00055 #endif
00056 
00057 #include "machine.h"
00058 #include "vmath.h"
00059 #include "db.h"
00060 #include "raytrace.h"
00061 
00062 #include "./debug.h"
00063 
00064 
00065 /**
00066  *                      D B _ A L L O C
00067  *
00068  *  Find a block of database storage of "count" granules.
00069  *
00070  *  Returns -
00071  *       0      OK
00072  *      -1      failure
00073  */
00074 int
00075 db_alloc(register struct db_i *dbip, register struct directory *dp, int count)
00076 {
00077         unsigned long   addr;
00078         union record    rec;
00079 
00080         RT_CK_DBI(dbip);
00081         RT_CK_DIR(dp);
00082         if(RT_G_DEBUG&DEBUG_DB) bu_log("db_alloc(%s) x%x, x%x, count=%d\n",
00083                 dp->d_namep, dbip, dp, count );
00084         if( count <= 0 )  {
00085                 bu_log("db_alloc(0)\n");
00086                 return(-1);
00087         }
00088 
00089         if( dp->d_flags & RT_DIR_INMEM )  {
00090                 if( dp->d_un.ptr )  {
00091                         dp->d_un.ptr = bu_realloc( dp->d_un.ptr,
00092                                 count * sizeof(union record), "db_alloc() d_un.ptr" );
00093                 } else {
00094                         dp->d_un.ptr = bu_malloc( count * sizeof(union record), "db_alloc() d_un.ptr" );
00095                 }
00096                 dp->d_len = count;
00097                 return 0;
00098         }
00099 
00100         if( dbip->dbi_read_only )  {
00101                 bu_log("db_alloc on READ-ONLY file\n");
00102                 return(-1);
00103         }
00104         while(1)  {
00105                 if( (addr = rt_memalloc( &(dbip->dbi_freep), (unsigned)count )) == 0L )  {
00106                         /* No contiguous free block, append to file */
00107                         if( (dp->d_addr = dbip->dbi_eof) < 0 )  {
00108                                 bu_log("db_alloc: bad EOF\n");
00109                                 return(-1);
00110                         }
00111                         dp->d_len = count;
00112                         dbip->dbi_eof += count * sizeof(union record);
00113                         dbip->dbi_nrec += count;
00114                         break;
00115                 }
00116                 dp->d_addr = addr * sizeof(union record);
00117                 dp->d_len = count;
00118                 if( db_get( dbip, dp, &rec, 0, 1 ) < 0 )
00119                         return(-1);
00120                 if( rec.u_id != ID_FREE )  {
00121                         bu_log("db_alloc():  addr %ld non-FREE (id %d), skipping\n",
00122                                 addr, rec.u_id );
00123                         continue;
00124                 }
00125         }
00126 
00127         /* Clear out ALL the granules, for safety */
00128         return( db_zapper( dbip, dp, 0 ) );
00129 }
00130 
00131 /**
00132  *                      D B _ D E L R E C
00133  *
00134  *  Delete a specific record from database entry
00135  *  No longer supported.
00136  */
00137 int
00138 db_delrec(struct db_i *dbip, register struct directory *dp, int recnum)
00139 {
00140 
00141         RT_CK_DBI(dbip);
00142         RT_CK_DIR(dp);
00143         if(RT_G_DEBUG&DEBUG_DB) bu_log("db_delrec(%s) x%x, x%x, recnum=%d\n",
00144                 dp->d_namep, dbip, dp, recnum );
00145 
00146         bu_log("ERROR db_delrec() is no longer supported.  Use combination import/export routines.\n");
00147         return -1;
00148 }
00149 
00150 /**
00151  *                      D B _ D E L E T E
00152  *
00153  *  Delete the indicated database record(s).
00154  *  Arrange to write "free storage" database markers in it's place,
00155  *  positively erasing what had been there before.
00156  */
00157 int
00158 db_delete(struct db_i *dbip, struct directory *dp)
00159 {
00160         register int i = -1;
00161 
00162         RT_CK_DBI(dbip);
00163         RT_CK_DIR(dp);
00164         if(RT_G_DEBUG&DEBUG_DB) bu_log("db_delete(%s) x%x, x%x\n",
00165                 dp->d_namep, dbip, dp );
00166 
00167         if( dp->d_flags & RT_DIR_INMEM )  {
00168                 bu_free( dp->d_un.ptr, "db_delete d_un.ptr");
00169                 dp->d_un.ptr = NULL;
00170                 dp->d_len = 0;
00171                 return 0;
00172         }
00173 
00174         if( dbip->dbi_version == 4 )  {
00175                 i = db_zapper( dbip, dp, 0 );
00176                 rt_memfree( &(dbip->dbi_freep), (unsigned)dp->d_len,
00177                         dp->d_addr/(sizeof(union record)) );
00178         } else if( dbip->dbi_version == 5 )  {
00179                 i = db5_write_free( dbip, dp, dp->d_len );
00180                 rt_memfree( &(dbip->dbi_freep), dp->d_len,
00181                         dp->d_addr );
00182         } else {
00183                 bu_bomb("db_delete() unsupported database version\n");
00184         }
00185 
00186         dp->d_len = 0;
00187         dp->d_addr = -1;
00188         return i;
00189 }
00190 
00191 /**
00192  *                      D B _ Z A P P E R
00193  *
00194  *  Using a single call to db_put(), write multiple zeroed records out,
00195  *  all with u_id field set to ID_FREE.
00196  *  This will zap all records from "start" to the end of this entry.
00197  *
00198  *  Returns:
00199  *      -1      on error
00200  *      0       on success (from db_put())
00201  */
00202 int
00203 db_zapper(struct db_i *dbip, struct directory *dp, int start)
00204 {
00205         register union record   *rp;
00206         register int            i;
00207         int                     todo;
00208 
00209         RT_CK_DBI(dbip);
00210         RT_CK_DIR(dp);
00211         if(RT_G_DEBUG&DEBUG_DB) bu_log("db_zapper(%s) x%x, x%x, start=%d\n",
00212                 dp->d_namep, dbip, dp, start );
00213 
00214         if( dp->d_flags & RT_DIR_INMEM )  bu_bomb("db_zapper() called on RT_DIR_INMEM object\n");
00215 
00216         if( dbip->dbi_read_only )
00217                 return(-1);
00218 
00219         BU_ASSERT_LONG( dbip->dbi_version, ==, 4 );
00220 
00221         if( (todo = dp->d_len - start) == 0 )
00222                 return(0);              /* OK -- trivial */
00223         if( todo < 0 )
00224                 return(-1);
00225 
00226         rp = (union record *)bu_malloc( todo * sizeof(union record), "db_zapper buf");
00227         bzero( (char *)rp, todo * sizeof(union record) );
00228         for( i=0; i < todo; i++ )
00229                 rp[i].u_id = ID_FREE;
00230         i = db_put( dbip, dp, rp, start, todo );
00231         bu_free( (char *)rp, "db_zapper buf" );
00232         return i;
00233 }
00234 /*@}*/
00235 
00236 /*
00237  * Local Variables:
00238  * mode: C
00239  * tab-width: 8
00240  * c-basic-offset: 4
00241  * indent-tabs-mode: t
00242  * End:
00243  * ex: shiftwidth=4 tabstop=8
00244  */

Generated on Mon Sep 18 01:24:49 2006 for BRL-CAD by  doxygen 1.4.6