結合lucene談談日期的壓縮問題

提及日期值的壓縮,通常容易想到的辦法是將日期轉化成long類型,而後再經過變長整形進行壓縮,我算了一下按照毫秒來算最多佔用5個字節(能夠經過「談談變長整型」中的表查看),確實節省了部分空間,可是還有優化的餘地,由於實際狀況下日期可能只精確到秒、小時或者天。優化

lucene裏用1個字節header中的前3位表示可能出現的5種狀況:編碼

一、時間精確到毫秒   header前3位值爲000.net

二、時間精確到天      header前3位值爲110code

三、時間精確到小時   header前3位值爲100blog

四、時間精確到秒      header前3位值爲010get

五、最後一種狀況lucene是把long類型的值看成普通的值來對待,也就是可能有負數,所以首先把long值通過zigzag進行編碼將負數轉正,而後利用header剩下的5位存儲zigzag編碼後的5位值,若是剩餘的位值不等於0,header前3位值爲001,而且將剩餘的位值按照變長整形進行壓縮。lucene裏面的long類型便可對日期壓縮也可對普通的值壓縮,有興趣的能夠查看源碼:源碼

 int header; 
    if (l % SECOND != 0) {
      header = 0;
    } else if (l % DAY == 0) {
      header = DAY_ENCODING;
      l /= DAY;
    } else if (l % HOUR == 0) {
      header = HOUR_ENCODING;
      l /= HOUR;
    } else {
      header = SECOND_ENCODING;
      l /= SECOND;
    }it

    final long zigZagL = BitUtil.zigZagEncode(l);
    header |= (zigZagL & 0x1F); // last 5 bits
    final long upperBits = zigZagL >>> 5;
    if (upperBits != 0) {
      header |= 0x20;
    }
    out.writeByte((byte) header);
    if (upperBits != 0) {
      out.writeVLong(upperBits);
    }ast

相關文章
相關標籤/搜索