|
| 1 | + |
| 2 | +#include<vector> |
| 3 | +#include<functional> |
| 4 | +#include<cmath> |
| 5 | + |
1 | 6 | #include"blob.h" |
2 | 7 | #include"stamp.h" |
3 | 8 | #include"stamp_atomic.h" |
4 | 9 | #include"galley.h" |
5 | | -#include<vector> |
6 | 10 |
|
7 | 11 |
|
8 | 12 | int |
@@ -151,4 +155,171 @@ GalleySeries::extract_internal(Blob &blob) |
151 | 155 | return res; |
152 | 156 | } |
153 | 157 |
|
| 158 | +/* |
| 159 | +class GalleyVector : public GalleyBase |
| 160 | +{ |
| 161 | + protected: |
| 162 | + std::vector<std::reference_wrapper<StampBase>> stamps; |
| 163 | + public: |
| 164 | + GalleyVector(std::vector<std::reference_wrapper<StampBase>> arg) : stamps(arg) {}; |
| 165 | + std::vector<Blob> extract_internal(Blob &blob); |
| 166 | + std::vector<std::string> ExtractStr(Blob &blob); |
| 167 | +// std::list<void *> ExtractBin(Blob &blob); |
| 168 | +
|
| 169 | + int minSize() override {return -2;}; // FIXME |
| 170 | + int maxSize() override {return -3;}; //FIXME /* Sereies always takes as much data as it can take*/ |
| 171 | +/*};*/ |
| 172 | + |
| 173 | +std::vector<Blob> |
| 174 | +GalleyVector::extract_internal(Blob &blob) |
| 175 | +{ |
| 176 | + std::vector<Blob> res; |
| 177 | +int fixed_total_size =0;// Summ of sizes of fixed parts of all stamps |
| 178 | +int max_varited_total_size =0;// Summ of sizes of variable parts of variated stamps |
| 179 | + ORACLE_STAMP oracle_stamp; |
| 180 | + |
| 181 | +bool has_variated_stamps =false; |
| 182 | +bool has_unbounded_stamps =false; |
| 183 | + |
| 184 | +/* Loop throight stamps calculating total sizes and seeing what kind of stamps do we have*/ |
| 185 | +for(StampBase & s : stamps) |
| 186 | + { |
| 187 | + fixed_total_size += s.minSize(); |
| 188 | +if (s.isVariated()) |
| 189 | + { |
| 190 | + max_varited_total_size += s.maxSize() - s.minSize(); |
| 191 | + has_variated_stamps =true; |
| 192 | + fixed_total_size += ORACLE_SIZE; |
| 193 | + } |
| 194 | +if (s.isUnbounded()) |
| 195 | + { |
| 196 | + has_unbounded_stamps =true; |
| 197 | + fixed_total_size += ORACLE_SIZE; |
| 198 | + } |
| 199 | + } |
| 200 | + |
| 201 | +/* If we have both variated and unbounded stamp we will need oracle to devide availabe data between them*/ |
| 202 | +if (has_variated_stamps && has_unbounded_stamps) |
| 203 | + fixed_total_size += ORACLE_SIZE; |
| 204 | + |
| 205 | +/* We will probably not use all data that can be teoretically consumed by variated stamps. |
| 206 | + This is a variable that will set limits to gariated stamps greed (will be rediced later*/ |
| 207 | +int varited_total_size_limit = max_varited_total_size; |
| 208 | + |
| 209 | +int avaliable_nonfixed_size = blob.Size() - fixed_total_size;/* The ammount of data available for non-fixed part of variated or unbounded stamps*/ |
| 210 | +if (varited_total_size_limit > avaliable_nonfixed_size) |
| 211 | + varited_total_size_limit = avaliable_nonfixed_size;/* Can't use more than we have*/ |
| 212 | + |
| 213 | + |
| 214 | +if (has_variated_stamps && has_unbounded_stamps) |
| 215 | + { |
| 216 | +/* try do devide available data between variated and unbounded stamps*/ |
| 217 | +/* if predicted variated size is smaller than varited_total_size_limit we will decrice that limit*/ |
| 218 | + |
| 219 | + ORACLE_TYPE * oracle = (ORACLE_TYPE *) blob.ShiftSingleStampBin(oracle_stamp); |
| 220 | +int predicted_variated_limit =round ((double) *oracle / (double) ORACLE_MAX * (double) (avaliable_nonfixed_size)); |
| 221 | +free(oracle); |
| 222 | + |
| 223 | +if (varited_total_size_limit > predicted_variated_limit) |
| 224 | + varited_total_size_limit = predicted_variated_limit; |
| 225 | + } |
| 226 | + |
| 227 | +/* now fetching oracles for non-fixed stamps and calculating total sized and modifiers*/ |
| 228 | + |
| 229 | +double predicted_variated_total_size =0; |
| 230 | +double total_unbounded_modifiers =0; |
| 231 | + |
| 232 | + std::vector<double> size_modifiers; |
| 233 | +for(StampBase & s : stamps) |
| 234 | + { |
| 235 | + ORACLE_TYPE o_value =0; |
| 236 | +double modifier =0; |
| 237 | +if (!s.isFixedSize()) |
| 238 | + { |
| 239 | + ORACLE_TYPE * oracle = (ORACLE_TYPE *) blob.ShiftSingleStampBin(oracle_stamp); |
| 240 | + o_value = * oracle; |
| 241 | +free(oracle); |
| 242 | + modifier = (double) o_value / (double) ORACLE_MAX; |
| 243 | +if (s.isUnbounded()) |
| 244 | + { |
| 245 | + total_unbounded_modifiers += modifier; |
| 246 | + }else |
| 247 | + { |
| 248 | + predicted_variated_total_size += (s.maxSize() - s.minSize()) * modifier; |
| 249 | + } |
| 250 | + } |
| 251 | + size_modifiers.push_back(modifier); |
| 252 | + } |
| 253 | +double k_variated =1; |
| 254 | +double k_unbounded =1; |
| 255 | + |
| 256 | +/* predicted_variated_total_size is sum of "predicted" sized of variated_size stamp data. We may proportially shrink it, so it is fit the availabe data, if we have too few data available |
| 257 | + but we may not enflate it, as it can grow size of some elements beyond it's maxSize(). But here we do round, that might round it up, |
| 258 | + hoping that there would be no harm in it (in rare cases (if ever) size of element's data can became one byte bigger than maxSize() and this byte will be ignored) |
| 259 | +*/ |
| 260 | + |
| 261 | +int final_variated_total_size; |
| 262 | +int final_unbounded_total_size; |
| 263 | + |
| 264 | +if (predicted_variated_total_size < varited_total_size_limit) |
| 265 | + final_variated_total_size =round(predicted_variated_total_size);/*round up the prediction for actual use*/ |
| 266 | +else |
| 267 | + final_variated_total_size = varited_total_size_limit;/* if prediction is out of limits will use limits as boundaries*/ |
| 268 | + |
| 269 | +if (has_variated_stamps) |
| 270 | + k_variated = final_variated_total_size / predicted_variated_total_size;/* will later deflate variated stamps predicted size with k_variated so they in sum will fit the limits*/ |
| 271 | + |
| 272 | + final_unbounded_total_size = avaliable_nonfixed_size - final_variated_total_size;/* the rest will be used by unbounded stamps*/ |
| 273 | +if (has_unbounded_stamps) |
| 274 | + k_unbounded = final_unbounded_total_size / total_unbounded_modifiers;/* calculate the proportion in which modifiers will be mapped to sizes to use all space*/ |
| 275 | + |
| 276 | +double variated_remainder =0; |
| 277 | +double unbounded_remainder =0; |
| 278 | + |
| 279 | +/* Now loop across stamps calculating data size for non-fixed stams using predicted modifiers and calculated coefficients,*/ |
| 280 | +/* chopping this sizes out of the blob and saving them a result vector*/ |
| 281 | +for(int i=0; i<stamps.size();i++) |
| 282 | + { |
| 283 | + StampBase &s = stamps[i]; |
| 284 | +double modifier = size_modifiers[i]; |
| 285 | +int el_size; |
| 286 | +if (s.isFixedSize()) |
| 287 | + { |
| 288 | + el_size = s.minSize(); |
| 289 | + } |
| 290 | +if (s.isVariated()) |
| 291 | + { |
| 292 | +double len = (s.maxSize() - s.minSize()) * modifier * k_variated + variated_remainder; |
| 293 | + el_size =round(len); |
| 294 | + variated_remainder = len - el_size; |
| 295 | + el_size += s.minSize(); |
| 296 | + } |
| 297 | +if (s.isUnbounded()) |
| 298 | + { |
| 299 | +double len = modifier * k_unbounded + unbounded_remainder; |
| 300 | + el_size =round(len); |
| 301 | + unbounded_remainder = len - el_size; |
| 302 | + el_size +=s.minSize(); |
| 303 | + } |
| 304 | + Blob blob2 = blob.ShiftBytes(el_size); |
| 305 | + res.push_back(blob2); |
| 306 | + } |
| 307 | +return res; |
| 308 | +} |
| 309 | + |
| 310 | +std::vector<std::string> |
| 311 | +GalleyVector::ExtractStr(Blob &blob) |
| 312 | +{ |
| 313 | + std::vector<std::string> res; |
| 314 | + std::vector<Blob> blobs =extract_internal(blob); |
| 315 | +for(int i=0; i<stamps.size(); i++) |
| 316 | + { |
| 317 | + Blob blob = blobs[i]; |
| 318 | + StampBase & stamp = stamps[i]; |
| 319 | + std::string str= blob.ShiftSingleStampStr(stamp); |
| 320 | + res.push_back(str); |
| 321 | + } |
| 322 | +return res; |
| 323 | +} |
| 324 | + |
154 | 325 |
|