• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/maloc/src/vsys/vset.c

00001 /*
00002  * ***************************************************************************
00003  * MALOC = < Minimal Abstraction Layer for Object-oriented C >
00004  * Copyright (C) 1994--2008 Michael Holst
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00019  *
00020  * rcsid="$Id: vset.c,v 1.15 2008/03/12 05:13:59 fetk Exp $"
00021  * ***************************************************************************
00022  */
00023 
00024 /*
00025  * ***************************************************************************
00026  * File:     vset.c
00027  *
00028  * Purpose:  Class Vset: methods.
00029  *
00030  * Author:   Michael Holst
00031  * ***************************************************************************
00032  */
00033 
00034 #include "vset_p.h"
00035 
00036 VEMBED(rcsid="$Id: vset.c,v 1.15 2008/03/12 05:13:59 fetk Exp $")
00037 
00038 /*
00039  * ***************************************************************************
00040  * Class Vset: Inlineable methods
00041  * ***************************************************************************
00042  */
00043 #if !defined(VINLINE_MALOC)
00044 
00045 /*
00046  * ***************************************************************************
00047  * Routine:  Vset_num
00048  *
00049  * Purpose:  Return the number of things currently in the list.
00050  *
00051  * Author:   Michael Holst
00052  * ***************************************************************************
00053  */
00054 VPUBLIC int Vset_num(Vset *thee)
00055 {
00056     return thee->numT;
00057 }
00058 
00059 /*
00060  * ***************************************************************************
00061  * Routine:  Vset_access
00062  *
00063  * Purpose:  Access an object in an arbitrary place in the list.
00064  *
00065  * Author:   Michael Holst
00066  * ***************************************************************************
00067  */
00068 VPUBLIC char *Vset_access(Vset *thee, int i)
00069 {
00070     if ((i >= 0) && (i < thee->numT))
00071         return &( thee->table[ i>>thee->blockPower               ]
00072                              [ thee->sizeT*(i&thee->blockModulo) ] );
00073     else
00074         return VNULL;
00075 }
00076 
00077 /*
00078  * ***************************************************************************
00079  * Routine:  Vset_create
00080  *
00081  * Purpose:  Create an object on the end of the list.
00082  *
00083  * Author:   Michael Holst
00084  * ***************************************************************************
00085  */
00086 VPUBLIC char *Vset_create(Vset *thee)
00087 {
00088     if (  (((thee->numT)>>thee->blockPower) >= thee->numBlocks)
00089        || (((thee->numT+1)%thee->prtT) == 0) ) {
00090         return Vset_createLast(thee);
00091     } else {
00092         (thee->numT)++;
00093         return Vset_access(thee,thee->numT-1);
00094     }
00095 }
00096 
00097 /*
00098  * ***************************************************************************
00099  * Routine:  Vset_destroy
00100  *
00101  * Purpose:  Delete an object from the end of the list.
00102  *
00103  * Author:   Michael Holst
00104  * ***************************************************************************
00105  */
00106 VPUBLIC void Vset_destroy(Vset *thee)
00107 {
00108     if ( (((thee->numT-1)>>thee->blockPower) < thee->numBlocks-1)
00109         || (thee->numT == 1) || (((thee->numT)%thee->prtT) == 0)) {
00110         Vset_destroyLast(thee);
00111     } else {
00112         (thee->numT)--;
00113     }
00114 }
00115 
00116 /*
00117  * ***************************************************************************
00118  * Routine:  Vset_first
00119  *
00120  * Purpose:  Return the first object in the set.
00121  *
00122  * Author:   Michael Holst
00123  * ***************************************************************************
00124  */
00125 VPUBLIC char *Vset_first(Vset *thee)
00126 {
00127     thee->curT = 0;
00128     return Vset_access(thee, thee->curT);
00129 }
00130 
00131 /*
00132  * ***************************************************************************
00133  * Routine:  Vset_last
00134  *
00135  * Purpose:  Return the last object in the set.
00136  *
00137  * Author:   Michael Holst
00138  * ***************************************************************************
00139  */
00140 VPUBLIC char *Vset_last(Vset *thee)
00141 {
00142     thee->curT = thee->numT-1;
00143     return Vset_access(thee, thee->curT);
00144 }
00145 
00146 /*
00147  * ***************************************************************************
00148  * Routine:  Vset_next
00149  *
00150  * Purpose:  Return the next object in the set.
00151  *
00152  * Author:   Michael Holst
00153  * ***************************************************************************
00154  */
00155 VPUBLIC char *Vset_next(Vset *thee)
00156 {
00157     thee->curT++;
00158     if (thee->curT < thee->numT)
00159         return Vset_access(thee, thee->curT);
00160     else return VNULL;
00161 }
00162 
00163 /*
00164  * ***************************************************************************
00165  * Routine:  Vset_prev
00166  *
00167  * Purpose:  Return the prev object in the set.
00168  *
00169  * Author:   Michael Holst
00170  * ***************************************************************************
00171  */
00172 VPUBLIC char *Vset_prev(Vset *thee)
00173 {
00174     thee->curT--;
00175     if (thee->curT >= 0)
00176         return Vset_access(thee, thee->curT);
00177     else return VNULL;
00178 }
00179 
00180 /*
00181  * ***************************************************************************
00182  * Routine:  Vset_peekFirst
00183  *
00184  * Purpose:  Return the first object in the set.
00185  *
00186  * Author:   Michael Holst
00187  * ***************************************************************************
00188  */
00189 VPUBLIC char *Vset_peekFirst(Vset *thee)
00190 {
00191     return Vset_access(thee, 0);
00192 }
00193 
00194 /*
00195  * ***************************************************************************
00196  * Routine:  Vset_peekLast
00197  *
00198  * Purpose:  Return the last object in the set.
00199  *
00200  * Author:   Michael Holst
00201  * ***************************************************************************
00202  */
00203 VPUBLIC char *Vset_peekLast(Vset *thee)
00204 {
00205     return Vset_access(thee, thee->numT-1);
00206 }
00207 
00208 #endif /* if !defined(VINLINE_MALOC) */
00209 /*
00210  * ***************************************************************************
00211  * Class Vset: Non-inlineable methods
00212  * ***************************************************************************
00213  */
00214 
00215 /*
00216  * ***************************************************************************
00217  * Routine:  Vset_ctor
00218  *
00219  * Purpose:  Construct the set object.
00220  *
00221  * Author:   Michael Holst
00222  * ***************************************************************************
00223  */
00224 VPUBLIC Vset* Vset_ctor(Vmem *vmem,
00225     const char *tname, int tsize, int tmaxNum, int ioKey)
00226 {
00227     char name[VMAX_ARGLEN];
00228     Vset *thee = VNULL;
00229     int K;
00230 
00231     VDEBUGIO("Vset_ctor: CREATING object..");
00232 
00233     thee = Vmem_malloc( VNULL, 1, sizeof(Vset) );
00234     if (vmem == VNULL) {
00235         sprintf(name, "Vset:%s", tname);
00236         thee->vmem = Vmem_ctor( name );
00237         thee->iMadeVmem = 1;
00238     } else {
00239         thee->vmem = vmem;
00240         thee->iMadeVmem = 0;
00241     }
00242 
00243     VASSERT( tsize > 0 );
00244     VASSERT( tmaxNum > 0 );
00245 
00246     /* set object name and size */
00247     strncpy(thee->nameT, tname, VMAX_ARGLEN);
00248     thee->sizeT = tsize;
00249 
00250     /* set blockSize as a power of two for quick block division via shifts */
00251     thee->blockPower  = VBLOCK_POWER; 
00252     thee->blockSize   = (1 << thee->blockPower);
00253 
00254     /* determine maxObjects such that:   [maxObjects >= tmaxNum]       */
00255     /* AND such that for some integer K: [maxObjects  = K * blockSize] */
00256     /* (this most excellent elegant expression is due to mr. bond)     */
00257     K = (int)( (tmaxNum - 1)/(thee->blockSize) ) + 1;
00258     thee->maxObjects = K * thee->blockSize;
00259     VASSERT( thee->maxObjects >= tmaxNum );
00260 
00261     /* set blockMax and blockModulo using maxObjects and blockSize */
00262     thee->blockMax    = (thee->maxObjects / thee->blockSize);
00263     thee->blockModulo = (thee->blockSize - 1);
00264 
00265     /* create the table of blocks */
00266     thee->table = Vmem_malloc( thee->vmem, thee->blockMax, sizeof( char* ) );
00267 
00268     /* now initialize the block data */
00269     Vset_initData(thee);
00270 
00271     VDEBUGIO("..done.\n");
00272 
00273     /* some i/o */
00274     if (ioKey) {
00275         Vnm_print(0,
00276             "Vset_ctor: %d (%d) %s [%d bs/%s, %d %s/bl, %d bls, %d:o bs]\n",
00277             (thee->blockSize * thee->blockMax), tmaxNum,
00278             thee->nameT, thee->sizeT, thee->nameT,
00279             thee->blockSize, thee->nameT, thee->blockMax,
00280             (VPTRSIZE * thee->blockMax) );
00281     }
00282 
00283     return thee;
00284 }
00285 
00286 /*
00287  * ***************************************************************************
00288  * Routine:  Vset_dtor
00289  *
00290  * Purpose:  Destroy the set object.
00291  *
00292  * Author:   Michael Holst
00293  * ***************************************************************************
00294  */
00295 VPUBLIC void Vset_dtor(Vset **thee)
00296 {
00297     VASSERT( (*thee) != VNULL );
00298     if ((*thee) != VNULL) {
00299         Vset_reset(*thee);
00300         Vmem_free( (*thee)->vmem, (*thee)->blockMax, sizeof(char*),
00301             (void**)&((*thee)->table) );
00302 
00303         VDEBUGIO("Vset_dtor: DESTROYING object..");
00304         if ((*thee)->iMadeVmem) Vmem_dtor( &((*thee)->vmem) );
00305         Vmem_free( VNULL, 1, sizeof(Vset), (void**)thee );
00306         VDEBUGIO("..done.\n");
00307 
00308         (*thee) = VNULL;
00309     }
00310 }
00311 
00312 /*
00313  * ***************************************************************************
00314  * Routine:  Vset_createLast
00315  *
00316  * Purpose:  Create an object on the end of the list.
00317  *
00318  * Author:   Michael Holst
00319  * ***************************************************************************
00320  */
00321 VPUBLIC char *Vset_createLast(Vset *thee)
00322 {
00323     /* get block number and index into block */
00324     int blockIdx = thee->sizeT*(thee->numT & thee->blockModulo);
00325     int blockNum = thee->numT >> thee->blockPower;
00326 
00327     /* do we need a new block yet? */
00328     if (blockNum >= thee->numBlocks) {
00329         VASSERT( blockNum == thee->numBlocks );
00330         thee->table[blockNum] = Vmem_malloc(thee->vmem,
00331                                     thee->blockSize, thee->sizeT);
00332         VASSERT ( thee->table[blockNum] != VNULL );
00333         thee->numBlocks++;
00334         VASSERT ( thee->numBlocks <= thee->blockMax );
00335     }
00336 
00337     /* increase global object count by one */
00338     thee->numT++;
00339 
00340     /* some i/o if needed */
00341     /* *** Vnm_print(0,"Vset_create: numT = %d\n", thee->numT); *** */
00342     if ( (thee->numT%thee->prtT) == 0 )
00343         Vnm_print(0,"[%s:c%d]",thee->nameT,thee->numT);
00344 
00345     /* return new obj */
00346     return &(thee->table[blockNum][blockIdx]);
00347 }
00348 
00349 /*
00350  * ***************************************************************************
00351  * Routine:  Vset_destroyLast
00352  *
00353  * Purpose:  Free up the object currently on the end of the list.
00354  *
00355  * Author:   Michael Holst
00356  * ***************************************************************************
00357  */
00358 VPUBLIC void Vset_destroyLast(Vset *thee)
00359 {
00360     int blockNum;
00361 
00362     /* some i/o if needed */
00363     /* *** Vnm_print(0,"Vset_destroy: numT = %d\n", thee->numT); *** */
00364     if ( (thee->numT%thee->prtT) == 0 )
00365         Vnm_print(0,"[%s:d%d]",thee->nameT,thee->numT);
00366 
00367     /* decrease global object count by one */
00368     thee->numT--;
00369 
00370     /* has block been completely emptied? */
00371     blockNum = thee->numT >> thee->blockPower;
00372     if (blockNum < thee->numBlocks-1) {
00373         VASSERT( blockNum == thee->numBlocks-2 );
00374         thee->numBlocks--;
00375         Vmem_free( thee->vmem, thee->blockSize, thee->sizeT,
00376             (void**)&(thee->table[thee->numBlocks]) );
00377         thee->table[thee->numBlocks] = VNULL;
00378     } else if (thee->numT == 0) {
00379         VASSERT( thee->numBlocks == 1 );
00380         thee->numBlocks = 0;
00381         Vmem_free( thee->vmem, thee->blockSize, thee->sizeT,
00382             (void**)&(thee->table[0]) );
00383         thee->table[0] = VNULL;
00384     }
00385 }
00386 
00387 /*
00388  * ***************************************************************************
00389  * Routine:  Vset_initData
00390  *
00391  * Purpose:  Initialize the Vset data (thee).
00392  *
00393  * Author:   Michael Holst
00394  * ***************************************************************************
00395  */
00396 VPUBLIC void Vset_initData(Vset *thee)
00397 {
00398     int j;
00399     thee->numBlocks = 0;
00400     thee->curT      = 0;
00401     thee->numT      = 0;
00402     thee->prtT      = 10000;
00403     for (j=0; j<thee->blockMax; j++) thee->table[j]=VNULL;
00404 }
00405 
00406 /*
00407  * ***************************************************************************
00408  * Routine:  Vset_reset
00409  *
00410  * Purpose:  Release all Ram controlled by this (thee) and re-initialize.
00411  *
00412  * Author:   Michael Holst
00413  * ***************************************************************************
00414  */
00415 VPUBLIC void Vset_reset(Vset *thee)
00416 {
00417     int j;
00418     while (Vset_num(thee) > 0) Vset_destroy(thee);
00419     for (j=0; j<thee->blockMax; j++)
00420         if (thee->table[j] != VNULL)
00421              Vmem_free( thee->vmem, thee->blockSize, thee->sizeT,
00422                  (void**)&(thee->table[j]) );
00423     Vset_initData(thee);
00424 }
00425 
00426 /*
00427  * ***************************************************************************
00428  * Routine:  Vset_check
00429  *
00430  * Purpose:  Get and return the RAM Control Block (thee) information.
00431  *
00432  * Author:   Michael Holst
00433  * ***************************************************************************
00434  */
00435 VPUBLIC void Vset_check(Vset *thee,
00436     int *tnum, int *tsize, int *tVecUse, int *tVecMal, int *tVecOhd)
00437 {
00438     (*tnum)    = thee->numT;
00439     (*tsize)   = thee->sizeT;
00440     (*tVecUse) = thee->sizeT * thee->numT;
00441     (*tVecMal) = thee->sizeT * (thee->numBlocks * thee->blockSize);
00442     (*tVecOhd) = VPTRSIZE * thee->blockMax;
00443 }
00444 
00445 /*
00446  * ***************************************************************************
00447  * Routine:  Vset_memChk
00448  *
00449  * Purpose:  Print the exact current malloc usage.
00450  *
00451  * Author:   Michael Holst
00452  * ***************************************************************************
00453  */
00454 VPUBLIC void Vset_memChk(Vset *thee)
00455 {
00456     if (thee->iMadeVmem) Vmem_print(thee->vmem);
00457 }
00458 

Generated on Wed Oct 20 2010 11:12:15 for APBS by  doxygen 1.7.2