Home | History | Annotate | Download | only in back
      1 /*
      2  * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 /* General routines for manipulating a bag data structure */
     27 
     28 #include "util.h"
     29 #include "bag.h"
     30 
     31 struct bag {
     32     void *items;    /* hold items in bag, must align on itemSize */
     33     int used;       /* number of items in bag */
     34     int allocated;  /* space reserved */
     35     int itemSize;   /* size of each item, should init to sizeof item */
     36 };
     37 
     38 struct bag *
     39 bagCreateBag(int itemSize, int initialAllocation) {
     40     struct bag *theBag = (struct bag *)jvmtiAllocate(sizeof(struct bag));
     41     if (theBag == NULL) {
     42         return NULL;
     43     }
     44     itemSize = (itemSize + 7) & ~7;    /* fit 8 byte boundary */
     45     theBag->items = jvmtiAllocate(initialAllocation * itemSize);
     46     if (theBag->items == NULL) {
     47         jvmtiDeallocate(theBag);
     48         return NULL;
     49     }
     50     theBag->used = 0;
     51     theBag->allocated = initialAllocation;
     52     theBag->itemSize = itemSize;
     53     return theBag;
     54 }
     55 
     56 struct bag *
     57 bagDup(struct bag *oldBag)
     58 {
     59     struct bag *newBag = bagCreateBag(oldBag->itemSize,
     60                                       oldBag->allocated);
     61     if (newBag != NULL) {
     62         newBag->used = oldBag->used;
     63         (void)memcpy(newBag->items, oldBag->items, newBag->used * newBag->itemSize);
     64     }
     65     return newBag;
     66 }
     67 
     68 void
     69 bagDestroyBag(struct bag *theBag)
     70 {
     71     if (theBag != NULL) {
     72         jvmtiDeallocate(theBag->items);
     73         jvmtiDeallocate(theBag);
     74     }
     75 }
     76 
     77 void *
     78 bagFind(struct bag *theBag, void *key)
     79 {
     80     char *items = theBag->items;
     81     int itemSize = theBag->itemSize;
     82     char *itemsEnd = items + (itemSize * theBag->used);
     83 
     84     for (; items < itemsEnd; items += itemSize) {
     85         /*LINTED*/
     86         if (*((void**)items) == key) {
     87             return items;
     88         }
     89     }
     90     return NULL;
     91 }
     92 
     93 void *
     94 bagAdd(struct bag *theBag)
     95 {
     96     int allocated = theBag->allocated;
     97     int itemSize = theBag->itemSize;
     98     void *items = theBag->items;
     99     void *ret;
    100 
    101     /* if there are no unused slots reallocate */
    102     if (theBag->used >= allocated) {
    103         void *new_items;
    104         allocated *= 2;
    105         new_items = jvmtiAllocate(allocated * itemSize);
    106         if (new_items == NULL) {
    107             return NULL;
    108         }
    109         (void)memcpy(new_items, items, (theBag->used) * itemSize);
    110         jvmtiDeallocate(items);
    111         items = new_items;
    112         theBag->allocated = allocated;
    113         theBag->items = items;
    114     }
    115     ret = ((char *)items) + (itemSize * (theBag->used)++);
    116     (void)memset(ret, 0, itemSize);
    117     return ret;
    118 }
    119 
    120 void
    121 bagDelete(struct bag *theBag, void *condemned)
    122 {
    123     int used = --(theBag->used);
    124     int itemSize = theBag->itemSize;
    125     void *items = theBag->items;
    126     void *tailItem = ((char *)items) + (used * itemSize);
    127 
    128     if (condemned != tailItem) {
    129         (void)memcpy(condemned, tailItem, itemSize);
    130     }
    131 }
    132 
    133 void
    134 bagDeleteAll(struct bag *theBag)
    135 {
    136     theBag->used = 0;
    137 }
    138 
    139 
    140 int
    141 bagSize(struct bag *theBag)
    142 {
    143     return theBag->used;
    144 }
    145 
    146 jboolean
    147 bagEnumerateOver(struct bag *theBag, bagEnumerateFunction func, void *arg)
    148 {
    149     char *items = theBag->items;
    150     int itemSize = theBag->itemSize;
    151     char *itemsEnd = items + (itemSize * theBag->used);
    152 
    153     for (; items < itemsEnd; items += itemSize) {
    154         if (!(func)((void *)items, arg)) {
    155             return JNI_FALSE;
    156         }
    157     }
    158     return JNI_TRUE;
    159 }
    160