`
BucketLi
  • 浏览: 189798 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
5a76a659-f8e6-3bf3-b39a-8ae8f7a0f9d9
Percolator与分布...
浏览量:5547
社区版块
存档分类
最新评论

一个简单的BufferPool

 
阅读更多
一个简单的buffer分配和收集代码,将一大段buffer分片,外部向这个pool申请,如果全部用完,就额外分配,但不计入pool所持有的数量,外部使用完后,回收分片.

import java.nio.ByteBuffer;
import java.util.concurrent.locks.ReentrantLock;

public final class BufferPool {

    private final int chunkSize;
    private final ByteBuffer[] items;
    private final ReentrantLock lock;
    private int putIndex;
    private int takeIndex;
    private int count;
    private volatile int newCount;

    public BufferPool(int bufferSize, int chunkSize) {
        this.chunkSize = chunkSize;
        int capacity = bufferSize / chunkSize;
        capacity = (bufferSize % chunkSize == 0) ? capacity : capacity + 1;
        this.items = new ByteBuffer[capacity];
        this.lock = new ReentrantLock();
        for (int i = 0; i < capacity; i++) {
            insert(create(chunkSize));
        }
    }

    public int capacity() {
        return items.length;
    }

    public int size() {
        return count;
    }

    public int getNewCount() {
        return newCount;
    }

    public ByteBuffer allocate() {
        ByteBuffer node = null;
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            node = (count == 0) ? null : extract();
        } finally {
            lock.unlock();
        }
        if (node == null) {
            ++newCount;
            return create(chunkSize);
        } else {
            return node;
        }
    }

    public void recycle(ByteBuffer buffer) {
        // 拒绝回收null和容量大于chunkSize的缓存
        if (buffer == null || buffer.capacity() > chunkSize) {
            return;
        }
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            if (count != items.length) {
                buffer.clear();
                insert(buffer);
            }
        } finally {
            lock.unlock();
        }
    }

    private void insert(ByteBuffer buffer) {
        items[putIndex] = buffer;
        putIndex = inc(putIndex);
        ++count;
    }

    private ByteBuffer extract() {
        final ByteBuffer[] items = this.items;
        ByteBuffer item = items[takeIndex];
        items[takeIndex] = null;
        takeIndex = inc(takeIndex);
        --count;
        return item;
    }

    private int inc(int i) {
        return (++i == items.length) ? 0 : i;
    }

    private ByteBuffer create(int size) {
        return ByteBuffer.allocate(size);
    }
}
分享到:
评论

相关推荐

    16 简单的LRU链表在Buffer Pool实际运行中,可能导致哪些问题.pdf

    16 简单的LRU链表在Buffer Pool实际运行中,可能导致哪些问题.pdf

    行业-16 简单的LRU链表在Buffer Pool实际运行中,可能导致哪些问题.rar

    行业-16 简单的LRU链表在Buffer Pool实际运行中,可能导致哪些问题.rar

    MySQL 删除大表的性能问题解决方案

    微博上讨论MySQL在删除大表engine=innodb(30G+)时,如何减少MySQL hang的时间,现做一下简单总结: 当buffer_pool很大的时候(30G+),由于删除表时,会遍历整个buffer pool来清理数据,会导致MySQL hang住,解决...

    DB2数据库创建脚本自动生成脚本 bash shell和Python开发

    之所以使用方便,是因为完全省去了人工换算表空间容器页大小,页数量换算操作,而且自动处理bufferpool与表空间关系,仅仅是简单回答问题,脚本自动生成脚本。静默模式,很高效的一种批量创建多套db2数据库的解决...

    ORACLE SQL性能优化

    比如当一个where子句中的一列有索引时去走索引。 COST (基于成本) 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性. CHOOSE (选择性) 如果table已经被analyze过, 优化器...

    MySQL全局共享内存介绍

    前言 全局共享内存则主要是 MySQL Instance(mysqld进程)以及底层存储引擎用来暂...下面针对 MySQL 主要的共享内存进行一个简单的分析。 查询缓存(Query Cache) 查询缓存是 MySQL 比较独特的一个缓存区域,用来缓存

    MTKMTK内存管理

    在文件app_mem.c里,有两个memory pool,一个是用于应用之间共享内存,另一个是用于屏幕内存。 第一种内存,主要是用于各种应用之间共享内存(以下简称ASM),这样可以节省内存,MTK实现了一种机制,可以在多个应用...

    Oracle语句优化30个规则详解

    因此,当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的执行路径。 ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的...

    Oracle优化53解

    这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享。 因此,当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ...

    ORACLE SQL性能优化系列

    这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享. 因此,当你执行一个SQL语句(有时被称为一个游标)时,如果它 和之前的执行过的语句完全相同, ORACLE...

    Android 4游戏编程入门经典

     8.2.4 一个简单的用法示例  8.3 2d物理定律浅析  8.3.1 牛顿和欧拉,永远的好朋友  8.3.2 力和质量  8.3.3 理论上的运动  8.3.4 运动的实现  8.4 2d碰撞检测和对象表示  8.4.1 边界形状  8.4.2 构造边界...

    华为编程开发规范与案例

    话单池的一个备份指针Pool_head_1和中继计次表的头指针重合,影响到第一个中继计次表的计费。 思考与启示: 随机值的背后往往隐藏着指针问题,两块内存缓冲区的交界处比较容易出现问题,在编程时是应该注意的地方...

    android游戏编程入门

     8.2.4 一个简单的用法示例 292  8.3 2D物理定律浅析 296  8.3.1 牛顿和欧拉,永远的  好朋友 296  8.3.2 力和质量 297  8.3.3 理论上的运动 298  8.3.4 运动的实现 299  8.4 2D碰撞检测和对象表示 302  ...

    转oracle keep池.docx

    KEEP池的使用十分简单,设置DB_KEEP_CACHE_SIZE的值大于0,就可以将其他对象的BUFFER_POOL参数设置为KEEP了。

    CISCO 技术大集合

    定义一个全局地址池 ip nat pool name start-ip end-ip {netmask netmask | prefix-length prefix-length} [type rotary] 建立动态地址翻译 ip nat inside source {list {access-list-number | name} pool name ...

    stable-connection

    我想加强 TCP 连接的稳定性,在 Client 失去 Server 的响应后(通常在应用层用心跳保持),可以重新发起一个 TCP 连接,取代之前的连接。这个模块可以完成这项工作,但模块本身不涉及 socket api ,它仅仅封装了控制...

    Oracle数据库实验操作

    实验1:书写一个最简单的sql语句,查询一张表的所有行和所有列 9 实验2:查询一张表的所有行,但列的顺序我们自己决定 10 实验3:查询表的某些列,在列上使用表达式 10 实验4:使用sqlplus,进入sqlplus并进行简单的...

    Oracle数据库管理员技术指南

    指定一个查询 3.4.4 导出/导入预计算优化程序统计 数据 3.4.5 可移动表空间 3.5 回顾 第4章 设计高可用性数据库 4.1 如何发现和保护“致命的弱点” 4.2 复用数据库控制文件 4.3 在硬件级上镜像控制文件 ...

Global site tag (gtag.js) - Google Analytics