首页 > 编程语言 >0042-Bytes-bytes源码阅读

0042-Bytes-bytes源码阅读

时间:2022-08-31 23:59:24浏览次数:77  
标签:mut bytes 0042 Bytes len 源码 shared data ptr

环境

  • Time 2022-05-29
  • Rust 1.61.0
  • Bytes 1.1.0

前言

说明

参考:

  1. https://github.com/tokio-rs/bytes
  2. https://zhuanlan.zhihu.com/p/109977513

目标

之前阅读的部分,都是关于静态的字节,后面开始涉及到动态。其中有很多关于原子类型的操作,来实现无锁并发。
这里不深入,先简单理解,之后有机会单独学原子操作和无锁数据结构和并发。
实现 bytes.rs 中的动态字节部分的方法。
前面实现了共享的 Vtable,还有一种复杂的是独占,并且在 clone 时转为共享。

promotable_odd_clone

奇数 Vtable 就不用再对指针进行减一的操作了。

unsafe fn promotable_odd_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Bytes {
    let shared = data.load(Ordering::Acquire);
    let kind = shared as usize & KIND_MASK;

    if kind == KIND_ARC {
        shallow_clone_arc(shared as _, ptr, len)
    } else {
        debug_assert_eq!(kind, KIND_VEC);
        shallow_clone_vec(data, shared, shared as *mut u8, ptr, len)
    }
}

promotable_odd_drop

unsafe fn promotable_odd_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usize) {
    data.with_mut(|shared| {
        let shared = *shared;
        let kind = shared as usize & KIND_MASK;

        if kind == KIND_ARC {
            release_shared(shared as *mut Shared);
        } else {
            debug_assert_eq!(kind, KIND_VEC);

            drop(rebuild_boxed_slice(shared as *mut u8, ptr, len));
        }
    });
}

from box

根据字节地址的奇偶性,分别创建 PROMOTABLE_EVEN_VTABLEPROMOTABLE_ODD_VTABLE
其中 data 指向的地址最先都是奇数。

impl From<Box<[u8]>> for Bytes {
    fn from(slice: Box<[u8]>) -> Bytes {
        if slice.is_empty() {
            return Bytes::new();
        }

        let len = slice.len();
        let ptr = Box::into_raw(slice) as *mut u8;

        if ptr as usize & 0x1 == 0 {
            let data = ptr as  usize| KIND_VEC;
            Bytes {
                ptr,
                len,
                data: AtomicPtr::new(data as *mut _),
                vtable: &PROMOTABLE_EVEN_VTABLE,
            }
        } else {
            Bytes {
                ptr,
                len,
                data: AtomicPtr::new(ptr as *mut _),
                vtable: &PROMOTABLE_ODD_VTABLE,
            }
        }
    }
}

from vec

impl From<Vec<u8>> for Bytes {
    fn from(vec: Vec<u8>) -> Bytes {
        let slice = vec.into_boxed_slice();
        slice.into()
    }
}

from string

impl From<String> for Bytes {
    fn from(s: String) -> Bytes {
        Bytes::from(s.into_bytes())
    }
}

总结

了解了 Bytes 中对于共享的字节的处理方法,包括共享和非共享的。

附录

标签:mut,bytes,0042,Bytes,len,源码,shared,data,ptr
From: https://www.cnblogs.com/jiangbo4444/p/16644970.html

相关文章

  • ConcurrentHashMap中的get和put源码分析
    get分析publicVget(Objectkey){//tab:指向数组Node<K,V>[]tab;//e:指向key对应的Node节点、p:Node<K,V>e,p;//n:数组长度、eh:key对应节点......
  • TypeError: Object of type 'bytes' is not JSON serializable
    转载自: https://blog.csdn.net/weixin_41951954/article/details/124838931   ......
  • 下载UE5源码
    要下载UE的源码首先需要在gethub上和自己的github账号关联EpicGame。怎么关联,好久了,我也忘记了。获取到下载权限后,建议直接下载压缩包,更快。文件实在是太庞大了,UE5有20G左......
  • Workshop 深圳站|实战+源码架构剖析带你揭开Appium的神秘面纱
    ⬇️点击“下方链接”,提升测试核心竞争力!>>更多技术文章分享和免费资料领取“工作坊(workshop)”一词最早出现在教育与心理学的研究领域之中。它是引发人们思考、探讨、......
  • GeoServer源码-运行
    GeoServer源码我们可以去github上去下载代码仓库地址版本选择:GeoServer2.19.6查看README.cd,有编译运行步骤  编译命令cdgeoservercdsrc#-X显示编译info......
  • 源码安装与yum安装的区别
    一,yum安装和源码(tar包)安装,方式的不同1,yum安装是将yum源中的rpm包下载到本地,安装这个rpm包。这个rpm包是别人编译安装好的二进制包。这种方式与其说是安装不如说是,更新来......
  • GeoServer源码分析
    参考地址:GeoServer源码解析和扩展(一)基础篇https://www.cnblogs.com/sillyemperor/p/1926093.htmlGeoServer源码解析和扩展(二)注册服务https://www.cnblogs.com/sillye......
  • vue3源码学习2-创建和渲染vnode
    创建vnode我们在第一节中在packages/runtime-core/src/apiCreateApp.ts文件的createAppAPI方法中,app.mount()时://通过createVNode方法创建了根组件的vnodeconstvnod......
  • SpringMvc请求流程源码解析
    目录SpringMvc请求流程图请求流程粗讲解方法细讲doDispatcher-->核心找到Handler#getHandlergetHandler(request)mapping.getHandler(request)getHandlerInternal()looku......
  • LinkedHashMap源码及LRU实现原理
    基本认识LinkedHashMap位于java.util包,于JDK1.4引入,属于JavaCollectionsFramework的成员。查看其UML关系如下图所示:HashMap在很多场景下都满足K-V的存取,而且在非多线......