@@ -25,6 +25,10 @@ pub fn generate_enum_table(code_dir : &std::path::Path, name : &str, enum_values
2525 let column_bytes = column:: compress ( column, column_bits) ;
2626 let index_bytes = column:: compress ( index, index_bits) ;
2727
28+ // These are the number of bytes to read to read a value in a single read instruction.
29+ let index_bytes_to_read = ( ( index_bits + 7 ) / 8 + 1 ) . next_power_of_two ( ) ;
30+ let column_bytes_to_read = ( ( column_bits + 7 ) / 8 + 1 ) . next_power_of_two ( ) ;
31+
2832 let code_path = code_dir. join ( format ! ( "{}.rs" , & name) ) ;
2933 let mut fd = std:: fs:: File :: create ( & code_path) ?;
3034
@@ -36,21 +40,26 @@ pub fn generate_enum_table(code_dir : &std::path::Path, name : &str, enum_values
3640 write ! ( fd, "const {}_INDEX_BITS : usize = {};\n \n " , upper_name, index_bits) ?;
3741 write ! ( fd, "const {}_INDEX_BYTE_OFFSET : usize = {};\n \n " , upper_name, column_bytes. len( ) ) ?;
3842
39- write ! ( fd, "const {}_DATA: [u8; {}] = [\n " , upper_name, column_bytes. len( ) + index_bytes. len( ) ) ?;
43+ let data_bytes_len = column_bytes. len ( ) + index_bytes. len ( ) + index_bytes_to_read - 1 ;
44+ write ! ( fd, "const {}_DATA: [u8; {}] = [\n " , upper_name, data_bytes_len) ?;
4045 write ! ( fd, " // Column table" ) ?;
4146 for ( i, v) in column_bytes. iter ( ) . enumerate ( ) {
4247 if i % 32 == 0 {
43- write ! ( fd, "\n " ) ?;
48+ write ! ( fd, "\n " ) ?;
4449 }
4550 write ! ( fd, "{:3}," , v) ?;
4651 }
4752 write ! ( fd, "\n // Index table" ) ?;
4853 for ( i, v) in index_bytes. iter ( ) . enumerate ( ) {
4954 if i % 32 == 0 {
50- write ! ( fd, "\n " ) ?;
55+ write ! ( fd, "\n " ) ?;
5156 }
5257 write ! ( fd, "{:3}," , v) ?;
5358 }
59+ write ! ( fd, "\n // Padding to handle unaligned word reads.\n " ) ?;
60+ for _ in 1 ..index_bytes_to_read {
61+ write ! ( fd, "{:3}," , 0 ) ?;
62+ }
5463 write ! ( fd, "\n ];\n \n " ) ?;
5564
5665 write ! ( fd, "/// The {} attribute for Unicode code-points.\n " , camel_name) ?;
@@ -84,7 +93,6 @@ pub fn generate_enum_table(code_dir : &std::path::Path, name : &str, enum_values
8493 write ! ( fd, " let index_byte_offset = index_offset / 8;\n " ) ?;
8594 write ! ( fd, " let index_bit_offset = index_offset % 8;\n " ) ?;
8695 write ! ( fd, " let mut index: usize = 0;\n " ) ?;
87- let index_bytes_to_read = ( index_bits + 7 ) / 8 + 1 ;
8896 for i in ( 0 ..index_bytes_to_read) . rev ( ) {
8997 write ! ( fd, " index |= ({}_DATA[{}_INDEX_BYTE_OFFSET + index_byte_offset + {}] as usize) << {};\n " , upper_name, upper_name, i, i * 8 ) ?;
9098 }
@@ -96,7 +104,6 @@ pub fn generate_enum_table(code_dir : &std::path::Path, name : &str, enum_values
96104 write ! ( fd, " let column_bit_offset = column_offset % 8;\n \n " ) ?;
97105
98106 write ! ( fd, " let mut value: usize = 0;\n " ) ?;
99- let column_bytes_to_read = ( column_bits + 7 ) / 8 + 1 ;
100107 for i in ( 0 ..column_bytes_to_read) . rev ( ) {
101108 write ! ( fd, " value |= ({}_DATA[column_byte_offset + {}] as usize) << {};\n " , upper_name, i, i * 8 ) ?;
102109 }
@@ -107,7 +114,7 @@ pub fn generate_enum_table(code_dir : &std::path::Path, name : &str, enum_values
107114 for ( i, v) in enum_values. iter ( ) . enumerate ( ) {
108115 write ! ( fd, " {} => {}::{},\n " , i, camel_name, v) ?;
109116 }
110- write ! ( fd, " _ => panic!( \" Invalid value. \" ) \n " ) ?;
117+ write ! ( fd, " _ => {}::{}, \n " , camel_name , enum_values [ 0 ] ) ?;
111118 write ! ( fd, " }};\n " ) ?;
112119 write ! ( fd, "}}\n \n " ) ?;
113120
0 commit comments