我尝试使用MYSQL(如果需要,使用udf)实现按位过滤器
过滤器类似于AND,但我想使用掩码来构建新的位串... 让我用一个示例解释你:
假设我有一个存储8位流的blob表:
然后我有一个掩码用于在掩码值为1
时从数据中获取位因此得到以下预期结果:
有没有办法优化过滤,没有循环“掩码”的每一位,以获得“数据”行中的相应值...
澄清
我刚刚为帖子取了8位,但它更像是256字节
for Joe:为了澄清这个例子,掩码00101011被解释为:从位置3,5,7,8的数据字段获取位值,如果你从左到右读取掩码,从第1位枚举到第8位...希望这个澄清是“明确的”......
答案 0 :(得分:8)
您可以在MySQL中使用按位运算符:
http://dev.mysql.com/doc/refman/5.0/en/bit-functions.html
示例:
SELECT (data1 & b'00101011') as output1 FROM ......
快速测试:
SELECT (b'10110110' & b'00101011') as output1
这是一个按位AND
,带有你指定的掩码的二进制模式
有关更多玩具,请参阅以上链接。
答案 1 :(得分:8)
我知道做你想做的事的唯一方法是
SELECT ((data >> 2) & 8) | ((data >> 1) & 4) | (data & 3) FROM ...
显然,你必须根据你的面具构建表达式;这不是很难做,只是有点乏味 - 你基本上需要循环掩码中的位,如下所示:
var mask = 0b00101011;
var parts = new Array();
var shift = 0;
var unshift = 0;
while (mask > 0) {
while ((mask & 1) == 0) {
shift = shift + 1;
mask = mask >> 1;
}
submask = 0;
while ((mask & 1) == 1) {
submask = submask + (1 << unshift);
unshift = unshift + 1;
mask = mask >> 1;
}
parts.push( "((data >> " + shift + ") & " + submask + ")" );
}
var expr = parts.join( " | " );
console.log(expr);
上面的示例代码是在JavaScript中,因此您可以在此处将其作为代码段运行并获取:
((data >> 0) & 3) | ((data >> 1) & 4) | ((data >> 2) & 8)
登录到控制台,但移植到其他语言应该很容易。