gfx/skia/trunk/src/core/SkTObjectPool.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/core/SkTObjectPool.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,104 @@
     1.4 +/*
     1.5 + * Copyright 2014 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#ifndef SkFreeList_DEFINED
    1.12 +#define SkFreeList_DEFINED
    1.13 +
    1.14 +#include "SkTInternalSList.h"
    1.15 +
    1.16 +/**
    1.17 + * An implementation of a self growing pool of objects.
    1.18 + * It maintains a pool of fully initialized objects. If an attempt is made to
    1.19 + * acquire one, and there are none left, it makes some more.
    1.20 + * It does not automatically reclaim them, they have to be given back to it.
    1.21 + * Constructors will be called on objects allocated by the pool at allocation
    1.22 + * time.
    1.23 + * All allocated objects will be destroyed and memory will be reclaimed when
    1.24 + * the pool is destroyed, so the pool must survive longer than you are using
    1.25 + * any item taken from it.
    1.26 + */
    1.27 +template<typename T, int numItemsPerBlock = 4096/sizeof(T)> class SkTObjectPool {
    1.28 +public:
    1.29 +    SkTObjectPool() {}
    1.30 +    ~SkTObjectPool() {
    1.31 +        while (!fBlocks.isEmpty()) {
    1.32 +            SkDELETE(fBlocks.pop());
    1.33 +        }
    1.34 +    }
    1.35 +
    1.36 +    /**
    1.37 +     * Get an item from the pool.
    1.38 +     * If the pool has no free items, it will allocate and construct some more.
    1.39 +     * The returned item is only valid as long as the pool has not been
    1.40 +     * destroyed, at that point all memory allocated by grow will have been
    1.41 +     * reclaimed.
    1.42 +     * This method is *not* thread safe.
    1.43 +     */
    1.44 +    T* acquire() {
    1.45 +        if (fAvailable.isEmpty()) {
    1.46 +            grow();
    1.47 +        }
    1.48 +        return fAvailable.pop();
    1.49 +    }
    1.50 +
    1.51 +    /**
    1.52 +     * Release an item into the pool.
    1.53 +     * The item does not have to have come from the pool, but if it did not
    1.54 +     * it must have a lifetime greater than the pool does.
    1.55 +     * This method is *not* thread safe.
    1.56 +     */
    1.57 +    void release(T* entry) {
    1.58 +        fAvailable.push(entry);
    1.59 +    }
    1.60 +
    1.61 +    /**
    1.62 +     * Takes all the items from an SkTInternalSList and adds them back to this
    1.63 +     * pool. The other list will be left empty.
    1.64 +     */
    1.65 +    void releaseAll(SkTInternalSList<T>* other) {
    1.66 +        fAvailable.pushAll(other);
    1.67 +    }
    1.68 +
    1.69 +    /**
    1.70 +     * Returns the number of items immediately available without having to
    1.71 +     * construct any new ones.
    1.72 +     */
    1.73 +    int available() const { return fAvailable.getCount(); }
    1.74 +
    1.75 +    /**
    1.76 +     * Returns the number of blocks of items the pool has allocated so far.
    1.77 +     */
    1.78 +    int blocks() const { return fBlocks.getCount(); }
    1.79 +
    1.80 +private:
    1.81 +    /**
    1.82 +     * The type for a new block of entries for the list.
    1.83 +     */
    1.84 +    struct Block {
    1.85 +        T entries[numItemsPerBlock];
    1.86 +        SK_DECLARE_INTERNAL_SLIST_INTERFACE(Block);
    1.87 +    };
    1.88 +    SkTInternalSList<Block> fBlocks;
    1.89 +    SkTInternalSList<T> fAvailable;
    1.90 +
    1.91 +    /**
    1.92 +     * When the free list runs out of items, this method is called to allocate
    1.93 +     * a new block of them.
    1.94 +     * It calls the constructors and then pushes the nodes into the available
    1.95 +     * list.
    1.96 +     */
    1.97 +    void grow() {
    1.98 +        Block* block = SkNEW(Block);
    1.99 +        fBlocks.push(block);
   1.100 +        for(int index = 0; index < numItemsPerBlock; ++index) {
   1.101 +            fAvailable.push(&block->entries[index]);
   1.102 +        }
   1.103 +    }
   1.104 +
   1.105 +};
   1.106 +
   1.107 +#endif

mercurial