docchi_diff/imp/write/
store_ids.rs1
2use std::collections::BTreeMap;
3use docchi_core::structs::{RustParam, Qv};
4
5#[derive(Debug)]
6pub(crate) enum StoredIDs{
7 Zero,
8 U64(u64),
9 Bits(Vec<u64>),
10 Numbers(Vec<usize>),
11}
12
13enum StoredIDsType{
14 U64, Bits, Numbers, Zero
15}
16
17pub(crate) fn store_ids<'a, T>(params : &'a BTreeMap<usize, &'a RustParam>, lists : &'a BTreeMap<usize, T>) -> StoredIDs{
18 let mut max : usize = 0;
19 let mut len_sum : usize = 0;
20 update_max_and_len(params, &mut max, &mut len_sum);
21 update_max_and_len(lists, &mut max, &mut len_sum);
22
23
24 match calc_type(max, len_sum){
25 StoredIDsType::Zero => StoredIDs::Zero,
26 StoredIDsType::U64 => StoredIDs::U64(get_u64(params, lists)),
27 StoredIDsType::Bits => StoredIDs::Bits(get_bits(params, lists, max)),
28 StoredIDsType::Numbers => StoredIDs::Numbers(get_numbers(params, lists, len_sum)),
29 }
30}
31
32pub(crate) fn store_ids_ref(refs : &BTreeMap<usize, &Qv<String>>) -> StoredIDs{
33 let mut max : usize = 0;
34 let mut len_sum : usize = 0;
35 update_max_and_len(refs, &mut max, &mut len_sum);
36
37 match calc_type(max, len_sum){
38 StoredIDsType::Zero => StoredIDs::Zero,
39 StoredIDsType::U64 =>{
40 let mut u = 0;
41 update_u64(refs, &mut u);
42 StoredIDs::U64(u)
43 }
44 StoredIDsType::Bits =>{
45 StoredIDs::Bits(get_bits_ref(refs, max))
46 },
47 StoredIDsType::Numbers => StoredIDs::Numbers(get_numbers_ref(refs, len_sum)),
48 }
49}
50
51
52fn get_u64<'a,T>(params : &'a BTreeMap<usize, &'a RustParam>, lists : &'a BTreeMap<usize,T>) -> u64{
53 let mut r : u64 = 0;
54 update_u64(params, &mut r);
55 update_u64(lists, &mut r);
56 r
57}
58
59fn update_u64<T>(map : &BTreeMap<usize, T>, r : &mut u64){
60 for &i in map.keys(){
61 *r |= 1 << i;
62 }
63}
64
65fn get_bits<'a, T>(params : &'a BTreeMap<usize, &'a RustParam>, lists : &'a BTreeMap<usize, T>, max : usize) -> Vec<u64> {
66 let len = max / 64 + 1;
67 let mut r : Vec<u64> = Vec::with_capacity(len);
68 for _ in 0..len{
69 r.push(0);
70 }
71
72 update_bits(params, &mut r);
73 update_bits(lists, &mut r);
74 return r;
75}
76
77fn get_bits_ref(refs : &BTreeMap<usize, &Qv<String>>, max : usize) -> Vec<u64> {
78 let len = max / 64 + 1;
79 let mut r : Vec<u64> = Vec::with_capacity(len);
80 for _ in 0..len{
81 r.push(0);
82 }
83
84 update_bits(refs, &mut r);
85 return r;
86}
87
88fn update_bits<T>(map : &BTreeMap<usize, T>, r : &mut Vec<u64>){
89 for &i in map.keys(){
90 let ind = i / 64;
91 let bit = i % 64;
92
93 unsafe {
94 *r.get_unchecked_mut(ind) |= 1 << bit;
95 }
96 }
97}
98
99fn get_numbers<'a, T>(params : &'a BTreeMap<usize, &'a RustParam>, lists : &'a BTreeMap<usize, T>, len : usize) -> Vec<usize> {
100 let mut r : Vec<usize> = Vec::with_capacity(len);
101 update_numbers(params, &mut r);
102 update_numbers(lists, &mut r);
103 r
104}
105
106fn get_numbers_ref(refs : &BTreeMap<usize, &Qv<String>>, len : usize) -> Vec<usize> {
107 let mut r : Vec<usize> = Vec::with_capacity(len);
108 update_numbers(refs, &mut r);
109 r
110}
111
112fn update_numbers<T>(map : &BTreeMap<usize, T>, r : &mut Vec<usize>){
113 for &i in map.keys(){
114 r.push(i);
115 }
116}
117
118fn calc_type(max : usize, len : usize)->StoredIDsType {
119 if len == 0 { return StoredIDsType::Zero; }
120
121 if max < 64 {
133 if len > max / 11 {
134 StoredIDsType::U64
135 } else {
136 StoredIDsType::Numbers
137 }
138 } else if max < 32768{
139 if len > max / 24 {
140 StoredIDsType::Bits
141 } else {
142 StoredIDsType::Numbers
143 }
144 } else if max < 8388608{
145 if len > max / 32 {
146 StoredIDsType::Bits
147 } else {
148 StoredIDsType::Numbers
149 }
150 } else if max < 2147483648{
151 if len > max / 40 {
152 StoredIDsType::Bits
153 } else {
154 StoredIDsType::Numbers
155 }
156 } else{
157 if len > max / 48 {
159 StoredIDsType::Bits
160 } else {
161 StoredIDsType::Numbers
162 }
163 }
164}
165
166fn update_max_and_len<T>(map : &BTreeMap<usize,T>, max : &mut usize, len : &mut usize){
167 let (max_t, len_t) = max_and_len(map);
168 *len += len_t;
169 *max = (*max).max(max_t);
170}
171
172fn max_and_len<T>(map : &BTreeMap<usize,T>) -> (usize, usize){
173 if map.len() == 0{ (0,0) }
174 else{
175 let (id,_) = map.iter().next_back().unwrap();
176 (*id, map.len())
177 }
178}