`
裴小星
  • 浏览: 265817 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
8ccf5db2-0d60-335f-a337-3c30d2feabdb
Java NIO翻译
浏览量:27853
F3e939f0-dc16-3d6e-8c0b-3315c810fb91
PureJS开发过程详解
浏览量:74378
07a6d496-dc19-3c71-92cf-92edb5203cef
MongoDB Java ...
浏览量:63076
社区版块
存档分类
最新评论

MongoDB Java Driver 源码分析(13):OutputBuffer,BasicOutputBuffer 和 PoolOutputBuffer

阅读更多
  在之前的源代码分析中我们经常遇到神秘的 OutMessage 类的实例,并调用它的 writeInt,query 等方法与 MongoDB 数据库进行交互。
  但 OutMessage 继承了 BSONEncoder 类,而 BSONEncoder 的 writeInt 等方法实际上是委托给 OutputBuffer 类的实例执行的。
  因此为了弄清楚 OutMessage 类的实例的行为,我们需要先了解 OutputBuffer 类的主要逻辑。

BasicOutputBuffer 和 PoolOutputBuffer 的 write 和 pipe 方法的实现

  OutputBuffer 类是一个抽象类,有两个子类: BasicOutputBuffer 和 PoolOutputBuffer。
  OutputBuffer 的作用是缓冲对将要写入到输出流中的数据进行缓冲,准备好后通过 pipe 方法将数据输出到输出流中。

  子类主要实现了抽象方法 write 和 pipe:
public abstract void write(byte[] b, int off, int len);
public abstract void write(int b);
public abstract int pipe( OutputStream out );

  BasicOutputBuffer 类的 write 方法的实现如下:
    // 写入数据到缓冲区
    public void write(byte[] b, int off, int len){
        // 保证缓冲区空间足够
        // 不够则开辟新的空间
        _ensure( len );

        // 复制数据到缓冲区
        System.arraycopy( b , off , _buffer , _cur , len );

        // 改变代表偏移量和缓冲区大小的数字
        _cur += len;
        _size = Math.max( _cur , _size );
    }

    // 保证缓冲区空间足够
    // 不够则开辟新的空间
    void _ensure( int more ){
        // 计算需要的大小
        final int need = _cur + more;

        // 目前的缓冲区大小足够。
        // 不再开辟新的空间
        if ( need < _buffer.length )
            return;

        // 新的缓冲区大小是原来的两倍
        int newSize = _buffer.length*2;
        // 如果仍然不够,开辟更大的空间
        if ( newSize <= need )
            newSize = need + 128;

        // 创建数组
        byte[] n = new byte[newSize];
        // 将缓冲区中数据复制到数组中
        System.arraycopy( _buffer , 0 , n , 0 , _size );
        // 以新的数组作为缓冲区
        _buffer = n;
    }

    // 只写入一个字节
    public void write(int b){
        // 保证有一个字节的空间
        _ensure(1);
        // 将 int 型数据的低 8 位保存到缓冲区
        _buffer[_cur++] = (byte)(0xFF&b);
        // 修改表示缓冲区数据大小的数值
        _size = Math.max( _cur , _size );
    }

BasicOutputBuffer 类的 pipe 方法的实现如下:
    public int pipe( OutputStream out )
        throws IOException {
        // 将缓冲区中的数据写入输出流中
        out.write( _buffer , 0 , _size );

        // 返回缓冲区大小
        return _size;
    }

PoolOutputBuffer 类的 write 方法实现如下:
    public void write(byte[] b, int off, int len){
        while ( len > 0 ){
            // 获取一块当前缓冲区空间
            byte[] bs = _cur();
            // 计算本次写入大小
            int space = Math.min( bs.length - _cur.y , len );
            // 将数据复制缓冲区
            System.arraycopy( b , off , bs , _cur.y , space );

            // 修改偏移量等后续工作
            _cur.inc( space );
            len -= space;
            off += space;

            // 其他后续处理
            // 如缓冲区满时,创建下一个缓冲区块等
            _afterWrite();
        }
    }

    // 只写入一个字节
    public void write(int b){
        // 获取缓冲区空间
        byte[] bs = _cur();
        // 将 int 型数值的低 8 为保存到缓冲区
        bs[_cur.getAndInc()] = (byte)(b&0xFF);
        // 后续处理
        _afterWrite();
    }

PoolOutputBuffer 类的 pipe 方法实现如下:
    public int pipe( OutputStream out )
        throws IOException {
        
        if ( out == null )
            throw new NullPointerException( "out is null" );

        int total = 0;
        
        for ( int i=-1; i<_fromPool.size(); i++ ){
            // 获取对象池中指定索引的数据
            byte[] b = _get( i );
            // 获取对象池中指定索引的数据的大小
            int amt = _end.len( i );

            // 将数据写入到输出流中
            out.write( b , 0 , amt );

            // 增加表示总数据大小的数值
            total += amt;
        }
        
        return total;
    }

OutputBuffer 类的 write* 方法

基于子类实现的 write 方法,OutputBuffer 实现了一系列 write* 方法
    // 写入 int 型
    public void writeInt( int x ){
        // 写入第 1 个字节(第 1 - 8 位)
        write( x >> 0 );
        // 写入第 2 个字节(第 9 - 16 位)
        write( x >> 8 );
        // 写入第 3 个字节(第 17 - 24 位)
        write( x >> 16 );
        // 写入第 4 个字节(第 25 - 32 位)
        write( x >> 24 );
    }

    // 按“大端”(Big End) 法 写入 int 型
    public void writeIntBE( int x ){
        // 写入第 4 个字节(第 25 - 32 位)
        write( x >> 24 );
        // 写入第 3 个字节(第 17 - 24 位)
        write( x >> 16 );
        // 写入第 2 个字节(第 9 - 16 位)
        write( x >> 8 );
        // 写入第 1 个字节(第 1 - 8 位)
        write( x );
    }

    // 指定位置写入 int 型数据
    public void writeInt( int pos , int x ){
        // 获取当前位置
        final int save = getPosition();
        // 设置当前位置
        setPosition( pos );
        // 写入 int 型数据
        writeInt( x );
        // 恢复当前位置
        setPosition( save );
    }

    // 写入 long 型数值
    public void writeLong( long x ){
        // 写入第 1 个字节(第 1 - 8 位)
        write( (byte)(0xFFL & ( x >> 0 ) ) );
        // 写入第 2 个字节(第 9 - 16 位)
        write( (byte)(0xFFL & ( x >> 8 ) ) );
        // 写入第 3 个字节(第 17 - 24 位)
        write( (byte)(0xFFL & ( x >> 16 ) ) );
        // 写入第 4 个字节(第 25 - 32 位)
        write( (byte)(0xFFL & ( x >> 24 ) ) );
        // 写入第 5 个字节(第 33 - 40 位)
        write( (byte)(0xFFL & ( x >> 32 ) ) );
        // 写入第 6 个字节(第 41 - 48 位)
        write( (byte)(0xFFL & ( x >> 40 ) ) );
        // 写入第 7 个字节(第 49 - 56 位)
        write( (byte)(0xFFL & ( x >> 48 ) ) );
        // 写入第 8 个字节(第 57 - 64 位)
        write( (byte)(0xFFL & ( x >> 56 ) ) );
    }

    // 写入 double 型数值
    public void writeDouble( double x ){
        // 将 double 型转为 long 型 (IEEE 754 表示法) 后写入
        writeLong( Double.doubleToRawLongBits( x ) );
    }
1
0
分享到:
评论

相关推荐

    MongoDB Java Driver 源码分析(1):Package 概述

    本篇文章将聚焦于MongoDB Java Driver的源码分析,首先从Package概述的角度进行深入探讨。 MongoDB Java Driver的源码主要分为以下几个核心包: 1. **com.mongodb**: 这是最顶层的包,包含了驱动的核心组件。`...

    MongoDB Java Driver 简单操作

    ### MongoDB Java Driver 简单操作详解 #### 一、简介 MongoDB 是一款非常流行的文档型数据库系统,因其灵活性和高性能而被广泛应用于多种场景之中。为了方便开发者使用 Java 进行开发,MongoDB 提供了官方的 Java ...

    mongodb-driver-sync-4.2.3-API文档-中英对照版.zip

    标签:mongodb、driver、sync、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,...

    mongodb-driver-core-4.2.3-API文档-中文版.zip

    标签:mongodb、driver、core、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...

    mongoDB java driver api

    MongoDB Java驱动API是用于与MongoDB数据库交互的Java库,它是MongoDB官方提供的一个关键组件,使得Java开发者能够方便地在应用程序中存取数据。MongoDB是一个高性能、开源、无模式的文档型数据库,而Java驱动API则...

    mongodb-driver-sync-4.2.3-API文档-中文版.zip

    标签:mongodb、driver、sync、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...

    MongoDB_3.8.2驱动jar包及其同版本依赖包bson和mongodb-driver-core

    java和mongodb连接,需要mongodb-driver,您还必须下载其依赖项: bson和 mongodb-driver-core》》3个包: mongodb-driver-3.8.2.jar; bson-3.8.2.jar; mongodb-driver-core-3.8.2.jar

    mongodb java driver 2.11

    MongoDB Java Driver 2.11是用于与MongoDB数据库进行交互的Java开发库,它提供了丰富的API,使得Java开发者可以方便地在应用程序中存取和管理MongoDB的数据。MongoDB是一款高性能、分布式、文档型的NoSQL数据库,它...

    MongoDBjava各版本驱动下载

    MongoDB Java驱动是Java开发者与MongoDB数据库交互的重要工具,它允许Java应用程序通过标准的Java API来执行查询、插入、更新和删除等操作。在Java中使用MongoDB,首先需要安装并配置对应的驱动版本,以确保与正在...

    mongodb java Driver

    6. **聚合框架**:MongoDB的聚合框架允许对数据进行处理和分析。Java驱动程序通过`Aggregation`接口提供支持,允许你构建复杂的管道操作,如`$match`、`$group`、`$sort`等。 7. **异步操作**:对于高并发应用,...

    mongodb-java-driver-4.4.0.jar

    mongodb-java-driver-4.4.0.jar

    MongoDb java driver 3.4.2

    - `mongo-java-driver-3.4.2.jar`:这是核心的MongoDB Java驱动程序库,包含了所有必要的类和方法,用于在Java应用中连接、查询和操作MongoDB数据库。 - `mongo-java-driver-3.4.2-sources.jar`:这个文件包含驱动...

    mongodb-java-driver源码依赖库

    MongoDB Java Driver是Java开发者用来与MongoDB数据库交互的官方驱动程序。这个源码依赖库包含了一组Java类和接口,使得开发人员能够方便地在应用程序中执行CRUD(创建、读取、更新、删除)操作以及其他高级功能,如...

    mongodb-async-driver-2.0.1 jar包

    总的来说,"mongodb-async-driver-2.0.1.jar"这个包是Java开发者与MongoDB数据库交互的强大工具,它通过异步I/O和事件驱动的编程模型,提高了应用的并发能力和响应速度。通过这个驱动,开发者可以充分利用MongoDB的...

    mongodb-driver-core-3.5.0.jar

    `mongodb-driver-3.5.0.jar`是完整版的MongoDB Java驱动,它扩展了`mongodb-driver-core`,提供了更高级别的操作接口,如`MongoClient`和`MongoDatabase`,方便开发者进行数据库操作。这个驱动程序使开发者能够方便...

    mongodb driver for java 源码

    MongoDB Java驱动程序是Java开发者用来与MongoDB数据库进行交互的官方库。源码分析将帮助我们深入理解其内部工作原理,优化应用性能,并有可能自定义功能以满足特定需求。以下是对MongoDB Java驱动2.5.3版本源码的...

    Java连接mongoDB需要的jar包(3.9.1)

    这里提到的"Java连接mongoDB需要的jar包(3.9.1)"是指Java开发者用于连接MongoDB数据库的一组关键库文件,包括`bson-3.9.1.jar`、`mongodb-driver-3.9.1.jar`和`mongodb-driver-core-3.9.1.jar`。这些JAR文件是...

    mongodb-driver-core-4.2.3-API文档-中英对照版.zip

    标签:mongodb、driver、core、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,...

    mongo-java-driver-3.4.3,java连接mongodb的jar包驱动包

    mongo-java-driver-3.4.3.jar 是 MongoDB 官方为 Java 开发者提供的 Java 驱动程序的一个特定版本(3.4.3)。这个 JAR 文件包含了与 MongoDB 数据库进行交互所需的类和接口,允许 Java 应用程序连接到 MongoDB 实例...

    MongoDBjava驱动源码程序

    MongoDB Java驱动是Java开发者与MongoDB数据库交互的主要工具,它是MongoDB官方提供的一款开源库,使得在Java应用程序中执行CRUD(创建、读取、更新、删除)操作变得简单。MongoDB Java驱动源码程序提供了深入理解其...

Global site tag (gtag.js) - Google Analytics