BufferPool(int count, int size, Persistit persistit) {
        _persistit = persistit;
        if (count < MINIMUM_POOL_COUNT) {
            throw new IllegalArgumentException("Buffer pool count too small: " + count);
        }
        if (count > MAXIMUM_POOL_COUNT) {
            throw new IllegalArgumentException("Buffer pool count too large: " + count);
        }

        int possibleSize = Buffer.MIN_BUFFER_SIZE;
        boolean ok = false;
        while (!ok && possibleSize <= Buffer.MAX_BUFFER_SIZE) {
            if (size == possibleSize)
                ok = true;
            else
                possibleSize *= 2;
        }
        if (!ok)
            throw new IllegalArgumentException("Invalid buffer size requested: " + size);

        _bufferCount = count;
        _bufferSize = size;
        _buffers = new Buffer[_bufferCount];
        _availablePagesBits = new AtomicLongArray((count + 63) / 64);
        _hashTable = new Buffer[_bufferCount * HASH_MULTIPLE];
        _hashLocks = new ReentrantLock[HASH_LOCKS];
        _maxKeys = (_bufferSize - Buffer.HEADER_SIZE) / Buffer.MAX_KEY_RATIO;
        
        for (int index = 0; index < HASH_LOCKS; index++) {
            _hashLocks[index] = new ReentrantLock();
        }

        int buffers = 0;
        //
        // Allocate this here so that in the event of an OOME we can release it
        // to free enough memory to write the error information out.
        //
        byte[] reserve = new byte[1024 * 1024];
        try {
            for (int index = 0; index < _bufferCount; index++) {
                Buffer buffer = new Buffer(size, index, this, _persistit);
                _buffers[index] = buffer;
                buffers++;
            }
        } catch (OutOfMemoryError e) {
            //
            // Note: written this way to try to avoid another OOME.
            // Do not use String.format here.
            //
            reserve = null;
            System.err.print("Out of memory with ");
            System.err.print(Runtime.getRuntime().freeMemory());
            System.err.print(" bytes free after creating ");
            System.err.print(buffers);
            System.err.print("/");
            System.err.print(_bufferCount);
            System.err.print(" buffers from maximum heap ");
            System.err.println(_persistit.getAvailableHeap());
            throw e;
        }
        _writer = new PageWriter();
        _cacher = new PageCacher();
    }