/*
 * CompressedBitParallelIndexConstruction.h
 *
 *  Created on: 6. 2. 2017
 *      Author: Jan Travnicek
 */

#ifndef ARBOLOGY_COMPRESSED_BIT_PARALLEL_INDEX_CONSTRUCTION_H_
#define ARBOLOGY_COMPRESSED_BIT_PARALLEL_INDEX_CONSTRUCTION_H_

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

namespace arbology {

namespace indexing {

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

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

	template < class SymbolType >
	static indexes::arbology::CompressedBitParallelTreeIndex < SymbolType > construct ( const tree::PrefixRankedBarTree < SymbolType > & w );
};

template < class SymbolType >
indexes::arbology::CompressedBitParallelTreeIndex < SymbolType > CompressedBitParallelIndexConstruction::construct ( const tree::PrefixRankedTree < 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;

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

template < class SymbolType >
indexes::arbology::CompressedBitParallelTreeIndex < SymbolType > CompressedBitParallelIndexConstruction::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;

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

} /* namespace indexing */

} /* namespace arbology */

#endif /* ARBOLOGY_COMPRESSED_BIT_PARALLEL_INDEX_CONSTRUCTION_H_ */
