/*
 * ExactSubtreeRepeats.cpp
 *
 *  Created on: 5. 5. 2017
 *      Author: Aleksandr Shatrovskii
 */

#include "ExactSubtreeRepeats.h"
#include <registration/AlgoRegistration.hpp>

namespace tree::properties {

void ExactSubtreeRepeats::assignLevel ( ext::deque < unsigned > S, unsigned l, ExactSubtreeRepeats::ExactSubtreeRepeatsAux & aux ) {

	std::queue < unsigned > Q4;
	ext::vector < ext::deque < unsigned > > An ( aux.treeSize );
	ext::vector < bool > Bn ( aux.treeSize );

	while ( !S.empty ( ) ) {
		unsigned i = S.front ( );
		S.pop_front ( );
		unsigned root = i + l - 1;

		if ( root < aux.treeSize - 1 )
			if ( aux.FC [ root ] ) {
				unsigned k = aux.H[aux.P[root]];
				An[k].push_back ( i );

				if ( ! Bn [ k ] ) {
					Bn[k] = true;
					Q4.push ( k );
				}
			}

	}

	while ( !Q4.empty ( ) ) {
		unsigned k = Q4.front ( );
		Q4.pop ( );
		aux.LA[k].push ( ext::make_pair ( An[k], l ) );

		/* This is line 15 (in paper) in the Assign-Level algorithm
		 * It has no effect here, as I made "An" local and the function ends right after the while loop.
		 * I leave it here to be consistent with the algorithm.
		 */
		/* Bn[k] = false;
		 * while ( !An[k].empty ( ) )
		 *	An[k].pop_front ( );
		 */
	}
}

}

namespace {

auto ExactRepeatsPostfixRankedTree = registration::AbstractRegister < tree::properties::ExactSubtreeRepeats, tree::PostfixRankedTree < unsigned >, const tree::PostfixRankedTree < > & > ( tree::properties::ExactSubtreeRepeats::repeats );

} /* namespace */
