3 # Generate tables for GroupVarint32
4 # Copyright 2011 Facebook
6 # @author Tudor Bosman (tudorb@fb.com)
8 # Reference: http://www.stepanovpapers.com/CIKM_2011.pdf
10 # From 17 encoded bytes, we may use between 5 and 17 bytes to encode 4
11 # integers. The first byte is a key that indicates how many bytes each of
12 # the 4 integers takes:
14 # bit 0..1: length-1 of first integer
15 # bit 2..3: length-1 of second integer
16 # bit 4..5: length-1 of third integer
17 # bit 6..7: length-1 of fourth integer
19 # The value of the first byte is used as the index in a table which returns
20 # a mask value for the SSSE3 PSHUFB instruction, which takes an XMM register
21 # (16 bytes) and shuffles bytes from it into a destination XMM register
22 # (optionally setting some of them to 0)
24 # For example, if the key has value 4, that means that the first integer
25 # uses 1 byte, the second uses 2 bytes, the third and fourth use 1 byte each,
26 # so we set the mask value so that
49 from optparse import OptionParser
51 OUTPUT_FILE = "GroupVarintTables.cpp"
55 #include <folly/Portability.h>
62 #if (FOLLY_X64 || defined(__i386__)) && (FOLLY_SSE >= 2)
63 alignas(16) extern const uint64_t groupVarintSSEMasks[512] = {
67 for i in range(0, 256):
71 d = 1 + ((i >> (2 * j)) & 3)
72 # the j'th integer uses d bytes, consume them
74 vals[j] |= offset << (8 * k)
76 # set remaining bytes in result to 0
77 # 0xff: set corresponding byte in result to 0
79 vals[j] |= 0xff << (8 * k)
80 f.write(" 0x{1:08x}{0:08x}ULL, "
81 "0x{3:08x}{2:08x}ULL,\n".format(*vals))
84 "#endif /*#if (FOLLY_X64 || defined(__i386__)) && (FOLLY_SSE >= 2)*/\n"
86 "extern const uint8_t groupVarintLengths[] = {\n")
88 # Also compute total encoded lengths, including key byte
89 for i in range(0, 256):
90 offset = 1 # include key byte
92 d = 1 + ((i >> (2 * j)) & 3)
94 f.write(" {0},\n".format(offset))
104 parser = OptionParser()
105 parser.add_option("--install_dir", dest="install_dir", default=".",
106 help="write output to DIR", metavar="DIR")
107 parser.add_option("--fbcode_dir")
108 (options, args) = parser.parse_args()
109 f = open(os.path.join(options.install_dir, OUTPUT_FILE), "w")
113 if __name__ == "__main__":