예제 #1
0
static unsigned
ValToBin(unsigned logscale, uint32_t val)
{
    unsigned bin;

    if (val <= 1)
        return val;
    bin = (logscale == 10)
        ? (unsigned) ceil(log10((double) val))
        : (logscale == 2)
        ? (unsigned) CeilingLog2Size(val)
        : val;
    return Min(bin, 10U);
}
예제 #2
0
/*
** Iterate over the entries in the hash table calling func for each
** entry found. Stop if "f" says to (return value & JS_ENUMERATE_STOP).
** Return a count of the number of elements scanned.
*/
int
JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg)
{
    JSHashEntry *he, **hep, **bucket;
    uint32_t nlimit, n, nbuckets, newlog2;
    int rv;

    nlimit = ht->nentries;
    n = 0;
    for (bucket = ht->buckets; n != nlimit; ++bucket) {
        hep = bucket;
        while ((he = *hep) != nullptr) {
            JS_ASSERT(n < nlimit);
            rv = f(he, n, arg);
            n++;
            if (rv & HT_ENUMERATE_REMOVE) {
                *hep = he->next;
                ht->allocOps->freeEntry(ht->allocPriv, he, HT_FREE_ENTRY);
                --ht->nentries;
            } else {
                hep = &he->next;
            }
            if (rv & HT_ENUMERATE_STOP) {
                goto out;
            }
        }
    }

out:
    /* Shrink table if removal of entries made it underloaded */
    if (ht->nentries != nlimit) {
        JS_ASSERT(ht->nentries < nlimit);
        nbuckets = NBUCKETS(ht);
        if (MINBUCKETS < nbuckets && ht->nentries < UNDERLOADED(nbuckets)) {
            newlog2 = CeilingLog2Size(ht->nentries);
            if (newlog2 < MINBUCKETSLOG2)
                newlog2 = MINBUCKETSLOG2;

            /*  Check that we really shrink the table. */
            JS_ASSERT(JS_HASH_BITS - ht->shift > newlog2);
            Resize(ht, JS_HASH_BITS - newlog2);
        }
    }
    return (int)n;
}
예제 #3
0
JSHashTable *
JS_NewHashTable(uint32_t n, JSHashFunction keyHash,
                JSHashComparator keyCompare, JSHashComparator valueCompare,
                const JSHashAllocOps *allocOps, void *allocPriv)
{
    JSHashTable *ht;
    size_t nb;

    if (n <= MINBUCKETS) {
        n = MINBUCKETSLOG2;
    } else {
        n = CeilingLog2Size(n);
        if (int32_t(n) < 0)
            return nullptr;
    }

    if (!allocOps) allocOps = &defaultHashAllocOps;

    ht = (JSHashTable*) allocOps->allocTable(allocPriv, sizeof *ht);
    if (!ht)
        return nullptr;
    memset(ht, 0, sizeof *ht);
    ht->shift = JS_HASH_BITS - n;
    n = JS_BIT(n);
    nb = n * sizeof(JSHashEntry *);
    ht->buckets = (JSHashEntry**) allocOps->allocTable(allocPriv, nb);
    if (!ht->buckets) {
        allocOps->freeTable(allocPriv, ht, nb);
        return nullptr;
    }
    memset(ht->buckets, 0, nb);

    ht->keyHash = keyHash;
    ht->keyCompare = keyCompare;
    ht->valueCompare = valueCompare;
    ht->allocOps = allocOps;
    ht->allocPriv = allocPriv;
    return ht;
}
예제 #4
0
void
JS_DumpHistogram(JSBasicStats *bs, FILE *fp)
{
    unsigned bin;
    uint32_t cnt, max;
    double sum, mean;

    for (bin = 0, max = 0, sum = 0; bin <= 10; bin++) {
        cnt = bs->hist[bin];
        if (max < cnt)
            max = cnt;
        sum += cnt;
    }
    mean = sum / cnt;
    for (bin = 0; bin <= 10; bin++) {
        unsigned val = BinToVal(bs->logscale, bin);
        unsigned end = (bin == 10) ? 0 : BinToVal(bs->logscale, bin + 1);
        cnt = bs->hist[bin];
        if (val + 1 == end)
            fprintf(fp, "        [%6u]", val);
        else if (end != 0)
            fprintf(fp, "[%6u, %6u]", val, end - 1);
        else
            fprintf(fp, "[%6u,   +inf]", val);
        fprintf(fp, ": %8u ", cnt);
        if (cnt != 0) {
            if (max > 1e6 && mean > 1e3)
                cnt = uint32_t(ceil(log10((double) cnt)));
            else if (max > 16 && mean > 8)
                cnt = CeilingLog2Size(cnt);
            for (unsigned i = 0; i < cnt; i++)
                putc('*', fp);
        }
        putc('\n', fp);
    }
}