search——bitmap的交并差补,加速版,位运算

package main

import (
	"bytes"
	"fmt"
)

const machineWord = 32 << (^uint(0) >> 63) //确定平台的无符号类型是32位还是64位: (32 << (^uint(0) >> 63))

type BitMap []uint

func (b *BitMap) Has(x int) bool {
	word, bit := x/machineWord, x%machineWord
	return word < len(*b) && (*b)[word]&(1<<bit) != 0
}

func (b *BitMap) Add(x int) {
	word, bit := x/machineWord, x%machineWord
	for word >= len(*b) {
		*b = append(*b, 0, 0, 0, 0)
	}
	(*b)[word] |= 1 << bit
}

func (b *BitMap) IntersectionSet(n *BitMap) *BitMap { // 交集
	small, big := b, n
	if len(*small) > len(*big) {
		small, big = big, small
	}
	intersection := small.Copy()
	for i := 0; i < len(*small); i++ {
		(*intersection)[i] &= (*big)[i]
	}
	return intersection
}

func (b *BitMap) UnionSet(n *BitMap) *BitMap {
	var small, big = b, n
	if len(*small) > len(*big) {
		small, big = big, small
	}
	union := big.Copy()
	for i := 0; i < len(*small); i++ {
		(*union)[i] |= (*small)[i]
	}
	return union
}

func (b *BitMap) SubtractionSet(n *BitMap) *BitMap {
	sub := b.Copy()
	for i := 0; i < len(*b) && i < len(*n); i++ {
		(*sub)[i] &= ^(*n)[i]
	}
	return sub
}

func (b *BitMap) ComplementSet(n *BitMap) *BitMap {
	if len(*b) < len(*n) {
		return &BitMap{}
	}
	com := b.Copy()
	for i := 0; i < len(*n); i++ {
		if (*com)[i]&(*n)[i] == (*n)[i] {
			(*com)[i] ^= (*n)[i]
		} else {
			return &BitMap{}
		}
	}
	return com
}

func (b *BitMap) String() string {
	var buf bytes.Buffer
	buf.WriteByte('[')
	for i, word := range *b {
		if word == 0 {
			continue
		}
		for j := 0; j < machineWord; j++ {
			if word&(1<<uint(j)) != 0 {
				if buf.Len() > 1 {
					buf.WriteByte(' ')
				}
				_, _ = fmt.Fprintf(&buf, "%d", machineWord*i+j)
			}
		}
	}
	buf.WriteByte(']')
	return buf.String()
}

func (b *BitMap) Len() int {
	return len(*b)
}

func (b *BitMap) Remove(x int) {
	word, bit := x/machineWord, x%machineWord
	if word >= len(*b) {
		return
	}
	(*b)[word] &^= 1 << bit
}

func (b *BitMap) Clear() {
	*b = (*b)[:0]
}

func (b *BitMap) Copy() *BitMap {
	n := make(BitMap, len(*b))
	copy(n, *b)
	return &n
}

func main() {
	var x, y BitMap
	x.Add(1)
	x.Add(2)
	x.Add(3)
	x.Add(9)
	x.Add(144)
	x.Add(1 << 2)
	x.Add(7)
	x.Add(99999999)
	y.Add(1)
	y.Add(2)
	y.Add(7)
	y.Add(99999999)

	fmt.Println("x", &x)
	fmt.Println("y", &y)
	fmt.Println("x y 交集", x.IntersectionSet(&y))
	fmt.Println("x y 并集", x.UnionSet(&y))
	fmt.Println("x y 差集", x.SubtractionSet(&y))
	fmt.Println("y x 差集", y.SubtractionSet(&x))
	fmt.Println("x y 补集", x.ComplementSet(&y))
	fmt.Println("y x 补集", y.ComplementSet(&x))
	x.Clear()
	//fmt.Println(&x)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Elasticsearch是一个基于Lucene的全文搜索引擎,它使用多种数据结构来加速搜索和聚合操作。其中包括roaring bitmap和skipList。 Roaring bitmap是一种高效的位图数据结构,用于表示大量的整数集合。它可以在非常小的内存空间中存储非常大的整数集合,同时支持快速的集合操作,如并集、集和补集等。在Elasticsearch中,Roaring bitmap常用于过滤器和聚合操作中,以提高查询性能。 例如,如果我们需要查找所有年龄在18到35岁之间的用户,可以使用Roaring bitmap来存储所有年龄在这个范围内的用户ID。然后,在查询时,只需要将查询条件转换为一组Roaring bitmap,然后进行位图运算即可快速地找到匹配的用户。 SkipList是一种高效的有序数据结构,类似于平衡树,但比平衡树更简单和高效。它可以在O(log n)的时间内进行插入、删除和查找操作,同时支持范围查找和迭代器等高级功能。在Elasticsearch中,SkipList常用于维护有序的文档ID列表和字段值列表,以加速排序和聚合操作。 例如,在对文档进行排序时,可以使用SkipList来维护文档ID和排序键的映射关系,然后使用快速排序算法对文档ID进行排序。类似地,在进行字段聚合操作时,可以使用SkipList来维护字段值和文档ID的映射关系,以快速计算聚合结果。 总之,Roaring bitmap和SkipList是Elasticsearch中重要的数据结构,它们可以帮助提高搜索和聚合操作的性能和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

metabit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值