/*
 * NonlinearCompressedBitParallelIndexConstruction.h
 *
 *  Created on: 22. 8. 2017
 *      Author: Jan Travnicek
 */

#ifndef ARBOLOGY_NONLINEAR_COMPRESSED_BIT_PARALLEL_INDEX_CONSTRUCTION_H_
#define ARBOLOGY_NONLINEAR_COMPRESSED_BIT_PARALLEL_INDEX_CONSTRUCTION_H_

#include <indexes/arbology/NonlinearCompressedBitParallelTreeIndex.h>
#include <tree/ranked/PrefixRankedBarTree.h>
#include <exception/CommonException.h>
#include <tree/properties/SubtreeJumpTable.h>
#include <tree/properties/ExactSubtreeRepeatsNaive.h>

namespace arbology {

namespace indexing {

/**
 * Constructs a nonlinear compressed bit parallel index for given tree.
 *
 */

class NonlinearCompressedBitParallelIndexConstruction {
public:
	/**
	 * Creates nonlinear compressed bit parallel index for trees
	 * @param tree tree to construct the index for
	 * @return the index
	 */
	template < class SymbolType >
	static indexes::arbology::NonlinearCompressedBitParallelTreeIndex < SymbolType > construct ( const tree::PrefixRankedBarTree < SymbolType > & w );
};

template < class SymbolType >
indexes::arbology::NonlinearCompressedBitParallelTreeIndex < SymbolType > NonlinearCompressedBitParallelIndexConstruction::construct ( const tree::PrefixRankedBarTree < SymbolType > & w ) {
	ext::map < common::ranked_symbol < SymbolType >, common::SparseBoolVector > res;

	for ( const common::ranked_symbol < SymbolType > & symbol : w.getAlphabet ( ) )
		res [ symbol ].resize ( w.getContent ( ).size ( ) );

	for ( unsigned i = 0; i < w.getContent ( ).size ( ); ++i )
		res [ w.getContent ( ) [ i ] ] [ i ] = true;

	ext::vector < common::ranked_symbol < unsigned > > content = tree::properties::ExactSubtreeRepeatsNaive::repeats ( w ).getContent ( );

	ext::vector < unsigned > repeats;
	for ( const common::ranked_symbol < unsigned > & symbol : content )
		repeats.push_back ( symbol.getSymbol ( ) );

	return indexes::arbology::NonlinearCompressedBitParallelTreeIndex < SymbolType > ( w.getAlphabet ( ), std::move ( res ), tree::properties::SubtreeJumpTable::compute ( w ), std::move ( repeats ) );
}

} /* namespace indexing */

} /* namespace arbology */

#endif /* ARBOLOGY_NONLINEAR_COMPRESSED_BIT_PARALLEL_INDEX_CONSTRUCTION_H_ */
