<
BitMap
>
上一篇

多线程
下一篇

MySQL

大数据处理算法之一:BitMap

1.(1)通过存储2表示是十进制的数进制位

如图:image

(2)可以快速排序/查找:bitmap.set(11),会直接在11的位上置为1,查询的时候直接查询这个位置是否是1,可以快速查找。

使用场景:

a.大量的黑名单号码需要存储,并且频繁访问,每次发生短信,这样就可以把黑名单号码存储到bitmap里面,通过boolean bitmap.get(11)方法,判断是否存在

b.现在有五十亿个int类型的正整数,要从中找出重复的数并返回?

思路:循环数据,把数据存到bitmap中,每次都判断是否存在在bitmap中,使用set(重复的数据只会保存一个)装bitmap中存在的数据,返回set即可

(3)

     1G = 1024M

     1M = 1024KB

     1KB = 1024B(字节)

     1M =(1024 * 1024)字节Byte

     1字节 = 8个二进制位(bit)

注意:有些时候在实际中,为了计算方便,计算机行业绝大多数的存储硬件设备生产制造商将1024进制改成了1000进制

2.使用过的bitmap和bitset

(1)com.sleepycat.je.utilint 包下面有一个BitMap,添加的参数是long类型的,里面也用到java.util包下面的BitSet(添加的参数类型是int的)。

依赖如下:

<dependency>
    <groupId>com.sleepycat</groupId>
    <artifactId>je</artifactId>
    <version>5.0.73</version>
</dependency>

(2)BitMap底层也是通过BitSet, 存进来的数是与65535L做逻辑与运算,(65535L:二进制中表示是16个1,转换成10进制正好是65535。unsingn int 一个整数是2个字节,有2*8个字符)

// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)

package com.sleepycat.je.utilint;

import com.sleepycat.je.EnvironmentFailureException;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class BitMap {
    private static final int SEGMENT_SIZE = 16;
    private static final int SEGMENT_MASK = 65535;
    private Map<Long, BitSet> bitSegments = new HashMap();

    public BitMap() {
    }

    public void set(long index) throws IndexOutOfBoundsException {
        if(index < 0L) {
            throw new IndexOutOfBoundsException(index + " is negative.");
        } else {
            BitSet bitset = this.getBitSet(index, true);
            if(bitset == null) {
                throw EnvironmentFailureException.unexpectedState(index + " is out of bounds");
            } else {
                int useIndex = this.getIntIndex(index);
                bitset.set(useIndex);
            }
        }
    }

    public boolean get(long index) throws IndexOutOfBoundsException {
        if(index < 0L) {
            throw new IndexOutOfBoundsException(index + " is negative.");
        } else {
            BitSet bitset = this.getBitSet(index, false);
            if(bitset == null) {
                return false;
            } else {
                int useIndex = this.getIntIndex(index);
                return bitset.get(useIndex);
            }
        }
    }

    private BitSet getBitSet(long index, boolean allowCreate) {
        Long segmentId = Long.valueOf(index >> 16);
        BitSet bitset = (BitSet)this.bitSegments.get(segmentId);
        if(allowCreate && bitset == null) {
            bitset = new BitSet();
            this.bitSegments.put(segmentId, bitset);
        }

        return bitset;
    }

    private int getIntIndex(long index) {
        return (int)(index & 65535L);
    }

    int getNumSegments() {
        return this.bitSegments.size();
    }

    int cardinality() {
        int count = 0;

        BitSet b;
        for(Iterator iter = this.bitSegments.values().iterator(); iter.hasNext(); count += b.cardinality()) {
            b = (BitSet)iter.next();
        }

        return count;
    }
}

补充:左移«变大,左移多少位,就在后面加几个0;右移»变小,右移多少位,就在末尾砍掉几个数。

CMPP短信发送协议

(1)主要用于短信发送和短信接收

(2)长连接:一个TCP连接上可以连续发送多个数据包,在TCP链接保持期间,如果没有数据发送,需要发送数据链路包以维持此链接

(3)短连接:通信双方有数据交互时,就建立一个TCP链接,数据发送完成时,则断开此连接,每次TCP连接只完成一对cmpp消息的发送。

###关于CMPP CMPP协议 SMS-China CMPP github例子

Top
Foot