Android Utils 之 Vector 学习笔记(一)—— VectorImpl 代码分析

本文分析了Android中VectorImpl的代码,包括排序、扩充和收缩等核心函数。首先介绍VectorImpl的基本结构,然后详细解析了排序函数的插入排序实现,以及扩充和收缩函数的内存管理和元素移动操作。通过对这些关键函数的分析,加深了对VectorImpl的理解,为高效使用和避免数据混乱提供了依据。
摘要由CSDN通过智能技术生成

前言

在维护 Android Framework 层时,常常能看到对 KeyedVectorDefaultKeyedVector 的使用。并且我们内部的服务框架也有用到 KeyedVector 这个结构。但在维护项目的过程中,我们发现它可能会导致数据处理顺序出现混乱的情况,我认为这一定是因为我们对这个结构不够了解导致的。关于这个结构内部的具体实现,我觉得我有必要去了解清楚,以便在后续的使用中能够发挥出它的最大功效,并且避免一些出问题的情况。

根据引用的头文件名,我们可以到 Android 源码目录下的 system/core/libutils/include 中找到相应的头文件。

浏览相关头文件,可以看到在 Android 内置的 Utils 中,有四种可用的 Vector 结构:

  1. Vector
  2. SortedVector
  3. KeyedVector
  4. DefaultKeyedVector

这些类之间的关系如下图:
@图1. 简单类图

由图可知:

  • VectorSortedVector 分别继承自抽象类 VectorImplSortedVectorImpl(而后者又是前者的子类),这两个抽象类实现了一些重要的底层操作。
  • VectorSortedVector 之间具有依赖关系(后者成员函数中有前者类型的参数)。
  • KeyedVector 相对独立,它与 SortedVector 是关联关系(前者有一个后者类型的成员变量)。
  • DefaultKeyedVector 继承自 KeyedVector,而根据代码来看,它们之间没有多少差异。

首先要读懂 VectorImplSortedVectorImpl,然后再看 VectorSortedVector。最后就要看我的重点 KeyedVector,这时候应该就有一个比较清晰的理解了。DefaultKeyedVector 差别不大,和 KeyedVector 一起看就行。


相关文章


头文件

文件路径:system\core\libutils\include\utils\VectorImpl.h

概览:

  • 开头的注释内容:这个类是实现 Vector 类的核心部分。它能保证逆向二进制兼容,并且减少代码量。考虑性能原因,将 mStoragemCount 两个内部字段暴露出来,它们是固定不变的。
  • 第 13~17 行:传入构造函数的标志位,表示是否为 trivial 类型。其中,ctor 表示构造函数,dtor 即是析构,copy 则表示拷贝。
  • 第 24 行:子类析构时必须调用的函数,涉及到内存空间的释放与内部成员重置。
  • 第 29 行:用于以 C 语言数组风格返回 Vector 的访问指针,但不能对其进行编辑操作
  • 第 30 行:用于以 C 语言数组风格返回 Vector,并且可以对内容进行编辑
  • 第 40~43 行:用于往当前 Vector 中插入(或末尾追加)另一个 Vector(或数组)
  • 第 46~57 行:用于增加、插入、替换以及删除 Vector 中的单个元素
  • 第 58 行:用于清空(重置) Vector。
  • 第 60、61 行:用于查找 index 位置对应的元素,注意名带 edit 的返回的是可编辑的结果
  • 第 63~66 行:定义两个函数指针,用于指向自定义的比较函数。sort 函数则是基于比较函数进行排序。
  • 第 70 行:用于释放 mStorage 的存储空间。
  • 第 72~77 行:一组纯虚函数,在子类中必须进行具体实现。
  • 第 80、81 行:用于从 Vector 的 where 位置开始扩充(或收缩)
  • 第 83~88 行:这些内联函数与前面的那组纯虚函数是一一对应的,各自的功能已经由其函数名表述清楚了。
  • 第 92~96 行:内部成员变量,分别存储了 Vector 数据首地址、元素总数、关于 trivial 类型的标志,以及单个元素的数据大小
/*!
 * Implementation of the guts of the vector<> class
 * this ensures backward binary compatibility and
 * reduces code size.
 * For performance reasons, we expose mStorage and mCount
 * so these fields are set in stone.
 *
 */

class VectorImpl
{
public:
    enum { // flags passed to the ctor
        HAS_TRIVIAL_CTOR    = 0x00000001,
        HAS_TRIVIAL_DTOR    = 0x00000002,
        HAS_TRIVIAL_COPY    = 0x00000004,
    };

                            VectorImpl(size_t itemSize, uint32_t flags);
                            VectorImpl(const VectorImpl& rhs);
    virtual                 ~VectorImpl();

    /*! must be called from subclasses destructor */
            void            finish_vector();

            VectorImpl&     operator = (const VectorImpl& rhs);    

    /*! C-style array access */
    inline  const void*     arrayImpl() const       { return mStorage; }
            void*           editArrayImpl();

    /*! vector stats */
    inline  size_t          size() const        { return mCount; }
    inline  bool            isEmpty() const     { return mCount == 0; }
            size_t          capacity() const;
            ssize_t         setCapacity(size_t size);
            ssize_t         resize(size_t size);

            /*! append/insert another vector or array */
            ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);
            ssize_t         appendVector(const VectorImpl& vector);
            ssize_t         insertArrayAt(const void* array, size_t index, size_t length);
            ssize_t         appendArray(const void* array, size_t length);

            /*! add/insert/replace items */
            ssize_t         insertAt(size_t where, size_t numItems = 1);
            ssize_t         insertAt(const void* item, size_t where, size_t numItems = 1);
            void            pop();
            void            push();
            void            push(const void* item);
            ssize_t         add();
            ssize_t         add(const void* item);
            ssize_t         replaceAt(size_t index);
            ssize_t         replaceAt(const void* item, size_t index);

            /*! remove items */
            ssize_t         removeItemsAt(size_t index, size_t count = 1);
            void            clear();

            const void*     itemLocation(size_t index) const;
            void*           editItemLocation(size_t index);

            typedef int (*compar_t)(const void* lhs, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值