2727namespace kaldi {
2828
2929template <typename Token>
30- BucketQueue<Token>::BucketQueue(BaseFloat best_cost_estimate,
31- BaseFloat cost_scale) :
30+ BucketQueue<Token>::BucketQueue(BaseFloat cost_scale) :
3231 cost_scale_ (cost_scale) {
3332 // NOTE: we reserve plenty of elements to avoid expensive reallocations
3433 // later on. Normally, the size is a little bigger than (adaptive_beam +
35- // 5 ) * cost_scale.
34+ // 15 ) * cost_scale.
3635 int32 bucket_size = 100 ;
3736 buckets_.resize (bucket_size);
38- bucket_storage_begin_ = std::floor ((best_cost_estimate - 15 ) * cost_scale_);
39- first_occupied_vec_index_ = bucket_size;
37+ bucket_offset_ = 15 * cost_scale_;
38+ first_nonempty_bucket_index_ = bucket_size - 1 ;
39+ first_nonempty_bucket_ = &buckets_[first_nonempty_bucket_index_];
4040}
4141
4242template <typename Token>
4343void BucketQueue<Token>::Push(Token *tok) {
44- int32 bucket_index = std::floor (tok->tot_cost * cost_scale_);
45- size_t vec_index = static_cast < size_t >(bucket_index - bucket_storage_begin_) ;
46- if (vec_index >= buckets_.size ()) {
44+ size_t bucket_index = std::floor (tok->tot_cost * cost_scale_) +
45+ bucket_offset_ ;
46+ if (bucket_index >= buckets_.size ()) {
4747 int32 margin = 10 ; // a margin which is used to reduce re-allocate
4848 // space frequently
49- // A cast from unsigned to signed type does not generate a machine-code
50- // instruction
51- if (static_cast <int32>(vec_index) > 0 ) {
52- KALDI_WARN << " Have to reallocate the BucketQueue. Maybe need to reserve"
53- << " more elements in constructor. Push back." ;
54- buckets_.resize (static_cast <int32>(vec_index) + margin);
49+ if (static_cast <int32>(bucket_index) > 0 ) {
50+ buckets_.resize (bucket_index + margin);
5551 } else { // less than 0
56- KALDI_WARN << " Have to reallocate the BucketQueue. Maybe need to reserve"
57- << " more elements in constructor. Push front." ;
58- int32 increase_size = - static_cast <int32>(vec_index) + margin;
59- buckets_.resize (buckets_.size () + increase_size);
60- // translation
61- for (size_t i = buckets_.size () - 1 ; i >= increase_size; i--) {
62- buckets_[i].swap (buckets_[i - increase_size]);
63- }
64- bucket_storage_begin_ = bucket_storage_begin_ - increase_size;
65- vec_index = static_cast <int32>(vec_index) + increase_size;
66- first_occupied_vec_index_ = vec_index;
52+ int32 increase_size = - static_cast <int32>(bucket_index) + margin;
53+ buckets_.resize (buckets_.size () + increase_size);
54+ // translation
55+ for (size_t i = buckets_.size () - 1 ; i >= increase_size; i--) {
56+ buckets_[i].swap (buckets_[i - increase_size]);
57+ }
58+ bucket_offset_ = bucket_offset_ + increase_size * cost_scale_;
59+ bucket_index += increase_size;
60+ first_nonempty_bucket_index_ = bucket_index;
61+ first_nonempty_bucket_ = &buckets_[first_nonempty_bucket_index_];
6762 }
6863 }
6964 tok->in_queue = true ;
70- buckets_[vec_index].push_back (tok);
71- if (vec_index < first_occupied_vec_index_)
72- first_occupied_vec_index_ = vec_index;
65+ buckets_[bucket_index].push_back (tok);
66+ if (bucket_index < first_nonempty_bucket_index_) {
67+ first_nonempty_bucket_index_ = bucket_index;
68+ first_nonempty_bucket_ = &buckets_[first_nonempty_bucket_index_];
69+ }
7370}
7471
7572template <typename Token>
7673Token* BucketQueue<Token>::Pop() {
77- int32 vec_index = first_occupied_vec_index_;
78- while (vec_index < buckets_.size ()) {
79- Token* tok = buckets_[vec_index].back ();
80- // Remove the best token
81- buckets_[vec_index].pop_back ();
82-
83- if (buckets_[vec_index].empty ()) { // This bucket is empty. Update vec_index
84- int32 next_vec_index = vec_index + 1 ;
85- for (; next_vec_index < buckets_.size (); next_vec_index++) {
86- if (!buckets_[next_vec_index].empty ()) break ;
74+ while (true ) {
75+ if (!first_nonempty_bucket_->empty ()) {
76+ Token *ans = first_nonempty_bucket_->back ();
77+ first_nonempty_bucket_->pop_back ();
78+ if (ans->in_queue ) {
79+ ans->in_queue = false ;
80+ return ans;
8781 }
88- vec_index = next_vec_index;
89- first_occupied_vec_index_ = vec_index;
9082 }
83+ if (first_nonempty_bucket_->empty ()) {
84+ // In case, pop an empty BucketQueue
85+ if (first_nonempty_bucket_index_ == buckets_.size () - 1 ) {
86+ return NULL ;
87+ }
9188
92- if (tok->in_queue ) { // This is a effective token
93- tok->in_queue = false ;
94- return tok;
89+ first_nonempty_bucket_index_++;
90+ for (; first_nonempty_bucket_index_ < buckets_.size () - 1 ;
91+ first_nonempty_bucket_index_++) {
92+ if (!buckets_[first_nonempty_bucket_index_].empty ())
93+ break ;
94+ }
95+ first_nonempty_bucket_ = &buckets_[first_nonempty_bucket_index_];
96+ if (first_nonempty_bucket_index_ == buckets_.size () - 1 &&
97+ first_nonempty_bucket_->empty ()) {
98+ return NULL ;
99+ }
95100 }
96101 }
97- return NULL ;
98102}
99103
100104template <typename Token>
101105void BucketQueue<Token>::Clear() {
102- for (size_t i = 0 ; i < buckets_.size (); i++) {
106+ for (size_t i = first_nonempty_bucket_index_ ; i < buckets_.size (); i++) {
103107 buckets_[i].clear ();
104108 }
105- first_occupied_vec_index_ = buckets_.size ();
109+ first_nonempty_bucket_index_ = buckets_.size () - 1 ;
110+ first_nonempty_bucket_ = &buckets_[first_nonempty_bucket_index_];
106111}
107112
108113// instantiate this class once for each thing you have to decode.
@@ -111,7 +116,7 @@ LatticeFasterDecoderCombineTpl<FST, Token>::LatticeFasterDecoderCombineTpl(
111116 const FST &fst,
112117 const LatticeFasterDecoderCombineConfig &config):
113118 fst_ (&fst), delete_fst_(false ), config_(config), num_toks_(0 ),
114- cur_queue_(0 , config_.cost_scale) {
119+ cur_queue_(config_.cost_scale) {
115120 config.Check ();
116121 prev_toks_.reserve (1000 );
117122 cur_toks_.reserve (1000 );
@@ -122,7 +127,7 @@ template <typename FST, typename Token>
122127LatticeFasterDecoderCombineTpl<FST, Token>::LatticeFasterDecoderCombineTpl(
123128 const LatticeFasterDecoderCombineConfig &config, FST *fst):
124129 fst_ (fst), delete_fst_(true ), config_(config), num_toks_(0 ),
125- cur_queue_(0 , config_.cost_scale) {
130+ cur_queue_(config_.cost_scale) {
126131 config.Check ();
127132 prev_toks_.reserve (1000 );
128133 cur_toks_.reserve (1000 );
@@ -133,8 +138,6 @@ template <typename FST, typename Token>
133138LatticeFasterDecoderCombineTpl<FST, Token>::~LatticeFasterDecoderCombineTpl () {
134139 ClearActiveTokens ();
135140 if (delete_fst_) delete fst_;
136- // prev_toks_.clear();
137- // cur_toks_.clear();
138141}
139142
140143template <typename FST, typename Token>
@@ -819,7 +822,7 @@ void LatticeFasterDecoderCombineTpl<FST, Token>::ProcessForFrame(
819822 BaseFloat cur_cost = tok->tot_cost ;
820823 StateId state = tok->state_id ;
821824 if (cur_cost > cur_cutoff &&
822- num_toks_processed < config_.min_active ) { // Don't bother processing
825+ num_toks_processed > config_.min_active ) { // Don't bother processing
823826 // successors.
824827 break ; // This is a priority queue. The following tokens will be worse
825828 } else if (cur_cost + adaptive_beam < cur_cutoff) {
@@ -848,7 +851,7 @@ void LatticeFasterDecoderCombineTpl<FST, Token>::ProcessForFrame(
848851
849852 // "changed" tells us whether the new token has a different
850853 // cost from before, or is new.
851- if (changed && !new_tok-> in_queue ) {
854+ if (changed) {
852855 cur_queue_.Push (new_tok);
853856 }
854857 }
@@ -948,7 +951,7 @@ void LatticeFasterDecoderCombineTpl<FST, Token>::ProcessNonemitting(
948951 BaseFloat cur_cost = tok->tot_cost ;
949952 StateId state = tok->state_id ;
950953 if (cur_cost > cur_cutoff &&
951- num_toks_processed < config_.min_active ) { // Don't bother processing
954+ num_toks_processed > config_.min_active ) { // Don't bother processing
952955 // successors.
953956 break ; // This is a priority queue. The following tokens will be worse
954957 } else if (cur_cost + adaptive_beam < cur_cutoff) {
@@ -977,7 +980,7 @@ void LatticeFasterDecoderCombineTpl<FST, Token>::ProcessNonemitting(
977980
978981 // "changed" tells us whether the new token has a different
979982 // cost from before, or is new.
980- if (changed && !new_tok-> in_queue ) {
983+ if (changed) {
981984 cur_queue_.Push (new_tok);
982985 }
983986 }
0 commit comments