向量
向量是一组有序排列的数据。本节介绍向量的创建、添加、读取和更新方式及使用示例。
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 提供两种添加向量数据的方式:
- 使用 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]
- 使用 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 提供三种读取向量数据的方式:
- 按照下标来读取,方法声明如下:
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
- 批量将数据复制到指定的缓冲区中,方法声明如下:
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 提供两种更新向量数据的方式:
- 按照下标来更新,方法声明如下:
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]
- 批量更新,方法声明如下:
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]