稀疏数据压缩查询方法:Rank & Select 操作

简介: 1.稀疏数据的例子   对于网络图对应的节点关联矩阵、数据生成的哈希表等,这些存储起来是稀疏的,这样我们就会想到需要压缩空间。但是在压缩存储空间的同时,还要支持高效的查询操作。   Rank & Select 就可以对稀疏的数据进行压缩,还能支持高效的查询操作。

1.稀疏数据的例子

  对于网络图对应的节点关联矩阵、数据生成的哈希表,这些存储起来是稀疏的,这样我们就会想到需要压缩空间。但是在压缩存储空间的同时,还要支持高效的查询操作。

  Rank & Select 就可以对稀疏的数据进行压缩,还能支持高效的查询操作。

2.Rank & Select 操作压缩稀疏数据原理

  以下图为例子,假如是经过哈希后得到的哈希数组:

  

  构造数组A和B:

    Vec-A:1010100110001    (每个位置一个比特位,1:有数据,0:无数据)

     Num-B:12  2  23  11  12  1  (数据按原来的相对顺序,保存为一个数组)

  (1)Rank:

    针对Vec-A数组而言,记录每个位置前面(包括本位)有多少个1,也就是对应之前有多少个有效数字。这样做的目的是使得,数组中的有效数字的排名与在Num-B中的位置一致。

  (2)Select:

    根据查询数据在Vec-A上面的Rank排名,在Num-B中查询数据。

  (3)Rank & Select

    

    eg1:位置4对应的位置没有数据,所以在Vec-A中标记为0;

    eg2:位置5对应的位置有数据23,所以在Vec-A中标记为1。Vec-A(5)对应的rank为3,说明包含自己在内之前一共有3个数据,且在位置5对应的数据保存在Num-B的第3为,即Select(5)=Num-B(Rank(5))

4.使用SSE指令高效计算Rank

  SIMD,单指令多数据,就是一条指令由多个执行单元同时并行执行操作多个数据

  SSE是指令集的简称,它包括70条指令,其中包含SIMD浮点计算、以及额外的SIMD整数和高速缓存控制指令。就是说SSE中存在指令,是SIMD指令,使得多核CPU可以高效执行。

  SSE指令 int _mm_popcnt_u32 (unsigned int a); 返回32为无符号整形 a 中bit位为1的位的个数。

5.Rank & Select 简单示例

  实例程序就是上面图中的例子,13个位置(1,2,3,..,14),6个有效位置。对其进行使用rank & select,进行压缩、并支持查询。

  例子较小,没有使用SSE指令,只是对rank select操作的简单说明。

 1 #include <iostream>
 2 #include <string.h>
 3 #include <bitset>
 4 using namespace std;
 5 
 6 /**
 7 设置原始数组num以及设置对应在ver_A的比特位
 8 num:保存原始数据的数组
 9 n:数组大小
10 ver_A:标记有效数字位向量
11 */
12 int initNumVer(int *num,int *ver_A,int n){
13     memset(num,0,sizeof(int)*n);
14     num[1] = 12;    *ver_A |= (1<<1);
15     num[3] = 2;     *ver_A |= (1<<3);
16     num[5] = 23;    *ver_A |= (1<<5);
17     num[8] = 11;    *ver_A |= (1<<8);
18     num[9] = 12;    *ver_A |= (1<<9);
19     num[13] = 1;    *ver_A |= (1<<13);
20     return 0;
21 }
22 
23 /**
24 ver_A:位向量
25 rank:排名
26 num_B:压缩后的数组
27 pos:要查的位置
28 */
29 int query(int *ver_A,int *rank,int *num_B,int pos){
30     if((*ver_A&(1<<pos)) == 0)
31         return 0;
32     else
33         return num_B[rank[pos]];
34 }
35 
36 int main (){
37     const int n = 14;
38     int  ver_A = 0;
39     int *num = new int[n];
40     int *rank = new int[n];
41     int *num_B = new int[7];    ///例子中有效数字6个,num_B[0]不使用
42 
43     ///设置原始数组num以及设置对应在ver_A的比特位
44     initNumVer(num,&ver_A,14);
45 
46     ///设置rank与压缩后的数组num_B
47     for(int i=0,j=0;i<n;i++){
48         if( (ver_A&(1<<i)) != 0)
49             num_B[++j] = num[i];
50         rank[i]=j;
51     }
52 
53     ///查询第4、5个数
54     cout<<"第4个数:"<<query(&ver_A,rank,num_B,4)<<endl;
55     cout<<"第5个数:"<<query(&ver_A,rank,num_B,5)<<endl;
56 
57     delete [] num;
58     delete [] rank;
59     delete [] num_B;
60     return 0;
61 }
View Code

6.注意

  (1)程序中以一维数组为例,其实多维数组也是连续存储,也可以理解为“一维数组”。

  (2)SSE指令时间复杂度为O(1),但是SSE指令操作位数有限。

  (3)如果Vec-A比特向量很长时,可以先计算一些rank数据保存下来(空间换时间),也可以达到计算任意位置rank操作时间复杂度为O(1)。

 

本文连接:http://www.cnblogs.com/xudong-bupt/p/3787658.html

参考链接:

SIMD : http://en.wikipedia.org/wiki/SIMD

_mm_popcnt_u32: http://msdn.microsoft.com/zh-cn/library/bb514083.aspx

SSE: http://en.wikipedia.org/wiki/SSE5

 

相关文章
|
8月前
|
SQL XML Java
Mybatis中选择语句的使用:<choose>标签、分区排序 Row_num() over ()函数的使用呢
Mybatis中选择语句的使用:<choose>标签、分区排序 Row_num() over ()函数的使用呢
67 0
|
关系型数据库 PostgreSQL
PostgreSQL listagg within group (order by) 聚合兼容用法 string_agg ( order by) - 行列变换,CSV构造...
标签 PostgreSQL , order-set agg , listagg , string_agg , order 背景 listagg — Rows to Delimited Strings The listagg function transforms values from a g...
6290 0
|
8月前
|
SQL 数据库管理
SQL基础题----基本的SELECT语句、order by排序
SQL基础题----基本的SELECT语句 ambiguous 模糊
231 1
|
SQL
解决union查询order by 排序失效的问题
解决union查询order by 排序失效的问题
247 0
|
SQL Oracle 关系型数据库
SQL学习之使用order by 按照指定顺序排序或自定义顺序排序
我们通常需要根据客户需求对于查询出来的结果给客户提供自定义的排序方式,那么我们通常sql需要实现方式都有哪些,参考更多资料总结如下(不完善的和错误望大家指出): 一、如果我们只是对于在某个程序中的应用是需要按照如下的方式排序,我们只需在SQL语句级别设置排序方式:
764 0
|
SQL 数据挖掘 Python
SQL练习:2(简单)+1(中等),常规题(group by\order by\avg...)
SQL练习:2(简单)+1(中等),常规题(group by\order by\avg...)
209 0
SQL练习:2(简单)+1(中等),常规题(group by\order by\avg...)
|
SQL 存储 Oracle
PostgreSQL 分页, offset, 返回顺序, 扫描方法原理(seqscan, index scan, index only scan, bitmap scan, parallel xx scan),游标
PostgreSQL 分页, offset, 返回顺序, 扫描方法原理(seqscan, index scan, index only scan, bitmap scan, parallel xx scan),游标
3865 0
|
SQL 数据挖掘 数据库
DataFrame多表合并拼接函数concat、merge参数详解+代码操作展示
DataFrame多表合并拼接函数concat、merge参数详解+代码操作展示
878 0
DataFrame多表合并拼接函数concat、merge参数详解+代码操作展示
|
关系型数据库 MySQL 数据库
select distinct去掉重复查询结果|学习笔记
快速学习select distinct去掉重复查询结果
278 0