向量

向量是一组有序排列的数据。本节介绍向量的创建、添加、读取和更新方式及使用示例。

Tip: 操作向量时,推荐使用批量处理的方式,可以减少虚函数调用的次数,提高效率。

创建向量

使用<Util.h>中提供的工具方法来创建向量,方法声明如下:

static Vector* createVector(DATA_TYPE type, INDEX size, INDEX capacity = 0, bool fast = true, int extraParam = 0, void* data = 0, bool containNull = false);

参数:

  • type:表示 Vector 中存储元素的类型,如 DT_INT,DT_DATE 等。
  • size:表示 Vector 的初始大小。如果设置不为0,则元素的内容随机。
  • capacity:表示 Vector 在构造时分配的容量。合理设置容量可以提高插入数据时的速度。
  • fast:该参数为保留参数,目前不起任何作用。
  • extraParam:在创建 Decimal 相关类型的 Vector 时使用,该参数可用来传入 Decimal 的 scale。
  • data:若已提前分配好可存放 capacity 个元素的内存,则可由该参数传入元素。用户不需要主动去释放这段内存,Vector 在析构时会通过 delete[]自动释放。
  • containNull:若传入了由用户申请的内存 data,则该参数表示 data 内存中前 size 个元素是否包含空值。true 表示包含,false 表示不包含。

例子如下:

VectorSP createDemoVector(){     //定义一个函数,后面会多次调用
    double* data = new double[10];
    for(int i = 0; i < 10; ++i){
        data[i] = i;
    }
    data[5] = getNullValue<double>();
    return Util::createVector(DT_DOUBLE, 10, 10, true, 0, data, true);   //创建一个类型为DOUBLE,初始容量为10,初始大小为10的向量,并且使用自己分配的可以容纳10个double数据的内存,其中有空值
}
VectorSP vi = Util::createVector(DT_INT, 0, 100);                     //创建一个类型为INT,初始容量为100,初始大小为0的向量
VectorSP vd = Util::createVector(DT_DECIMAL32, 0, 100, true, 5);          //创建一个类型为DECIMAL32(5),初始容量为100,初始大小为0的向量
VectorSP vdb = createDemoVector();         
std::cout << vdb->getString() << std::endl;               //[0,1,2,3,4,,6,7,8,9]

添加数据

API 提供两种添加向量数据的方式:

  1. 使用 append 方法添加数据,方法声明如下:
    bool append(const ConstantSP& value); //添加value到向量的末尾,其中value可以是标量或者向量 
    bool append(const ConstantSP& value, INDEX count); //如果value是标量,则添加count个value到向量的末尾;如果value是向量,则添加value的前count个元素到向量的末尾 
    bool append(const ConstantSP value, INDEX start, INDEX length); //value是另一个数组,添加其中[start, start + length)范围元素到向量的末尾 

    使用示例:

    VectorSP vi = Util::createVector(DT_INT, 0, 100);         //[] 
    vi->append(new Int(1));           //[1] 
    vi->append(new Int(4), 5);        //[1, 4, 4, 4, 4, 4]
    VectorSP vi2 = Util::createVector(DT_INT, 0, 100);        //[] 
    vi2->append(vi, 2, 3);             //[4, 4, 4] 
  2. 使用 appendInt, appendLong 等指定类型的方法来批量添加数据,方法声明如下:
    bool appendInt(int* buf, int len);
    bool appendLong(long long* buf, int len); bool appendDouble(double* buf, int len); ... 

    其中buf为数组首地址,len为待添加的数据个数。

    使用示例:

    VectorSP vi = Util::createVector(DT_INT, 0, 100);         //[]
    std::vector<int> v2{1, 2, 3, 4, 5}; 
    vi->appendInt(v2.data(), v2.size());                     //[1, 2, 3, 4, 5] 

读取数据

API 提供三种读取向量数据的方式:

  1. 按照下标来读取,方法声明如下:
    ConstantSP get(INDEX index) const; //返回下标为index位置上的元素 
    int getInt(INDEX index) const; //返回下标为index位置上元素的int值 
    long long getLong(INDEX index) const; //返回下标为index位置上元素的long值 
    ... 

    使用示例:

    VectorSP vi = createDemoVector(); //[0,1,2,3,4,,6,7,8,9] 
    ConstantSP e1 = vi->get(1);     //e1为DT_DOUBLE类型的标量,值是1
    double e2 = vi->getDouble(2);   //e2 = 2 
  2. 批量将数据复制到指定的缓冲区中,方法声明如下:
    bool getInt(INDEX start, int len, int* buf) const; //将向量中[start, start + len)范围的数据拷贝到buf指定的数组中,下同 
    bool getLong(INDEX start, int len, long long* buf) const; 
    ... 

    使用示例:

    VectorSP vi = createDemoVector();    //vi: [0,1,2,3,4,,6,7,8,9] 
    double buf[10]{}; vi->getDouble(0, 5, buf);        //buf: [0, 1, 2, 3, 4, 0, 0, 0, 0, 0]
    获取只读的缓冲区,从而批量读取数据,方法声明如下:
    const int* getIntConst(INDEX start, int len, int* buf) const //如果向量类型为DT_INT,则直接返回存放数据的首地址;否则,将数据转换为INT后拷贝到buf中,并返回buf 
    const long long* getLongConst(INDEX start, int len, long long* buf) //如果向量类型为DT_LONG,则直接返回存放数据的首地址;否则,将数据转换为LONG后拷贝到buf中,并返回buf 
    ... 

    使用示例:

    VectorSP vi = createDemoVector();     //vi: [0,1,2,3,4,,6,7,8,9] 
    double buf[10]{}; 
    const double* data = vi->getDoubleConst(0, 5, buf);      //data: [0, 1, 2, 3, 4] 

更新数据

API 提供两种更新向量数据的方式:

  1. 按照下标来更新,方法声明如下:
    bool set(INDEX index, const ConstantSP& value); //设置下标为index位置上的元素,下同 
    void setInt(INDEX index,int val); 
    void setLong(INDEX index,long long val);  
    ... 

    使用示例:

    VectorSP vi = createDemoVector();      //vi: [0,1,2,3,4,,6,7,8,9] 
    vi->set(1, new Double(100));       //vi: [0,100,2,3,4,,6,7,8,9] 
    vi->setDouble(2, 200);         //vi: [0,100,200,3,4,,6,7,8,9] 
  2. 批量更新,方法声明如下:
    bool setInt(INDEX start, int len, const int* buf); //设置向量中[start, start + len)范围内的元素,下同 
    bool setLong(INDEX start, int len, const long long* buf); 
    ... 
    double* getDoubleBuffer(INDEX start, int len, double* buf) //获取向量中存放数据的地址,需搭配上面的批量更新函数使用 
    float* getFloatBuffer(INDEX start, int len, float* buf)

    使用示例:

    VectorSP vi = createDemoVector();      //vi: [0,1,2,3,4,,6,7,8,9] 
    double buf_[5]; 
    auto buf = vi->getDoubleBuffer(0, 5, buf_); 
    for(int i = 0; i < 5; ++i){     
        buf[i] = buf[i] * 2;         //将前五个元素的值乘以2
    }                    
    vi->setDouble(0, 5, buf);       //vi: [0,2,4,6,8,,6,7,8,9]