| 634 | } |
| 635 | |
| 636 | void FixedSizeClassStats::accumulate(int c, float w) { |
| 637 | auto it = class_weights_.find(c); |
| 638 | if (it != class_weights_.end()) { |
| 639 | it->second += w; |
| 640 | if (c == smallest_weight_class_) { |
| 641 | smallest_weight_class_ = argmin(class_weights_); |
| 642 | } |
| 643 | return; |
| 644 | } |
| 645 | |
| 646 | if (class_weights_.size() < n_) { |
| 647 | class_weights_.insert(it, std::pair<int, float>(c, w)); |
| 648 | if (class_weights_.size() == n_) { |
| 649 | // Can't assume last added has the smallest weight, because the |
| 650 | // w's might be all different. |
| 651 | smallest_weight_class_ = argmin(class_weights_); |
| 652 | } |
| 653 | return; |
| 654 | } |
| 655 | |
| 656 | // This is the slightly unintuitive heart of the SpaceSaving algorithm: |
| 657 | // if the map is full and we see a new class, we find the entry with the |
| 658 | // smallest weight and "take it over": we add our weight to its weight, |
| 659 | // and assign it all to the new seen class. |
| 660 | it = class_weights_.find(smallest_weight_class_); |
| 661 | float new_weight = it->second + w; |
| 662 | class_weights_.erase(it); |
| 663 | class_weights_[c] = new_weight; |
| 664 | smallest_weight_class_ = argmin(class_weights_); |
| 665 | } |
| 666 | |
| 667 | float FixedSizeClassStats::get_weight(int c) const { |
| 668 | // Every entry in class_weights_ might be overstated by as much as the |