package org.maachang.rimdb.index ;

import org.maachang.rimdb.util.NOKeyValue;

/**
 * 行マスクインデックス.
 * 
 * @version 2014/06/29
 * @author  masahito suzuki
 * @since   rimdb-1.00
 */
public final class MaskLine {
    
    public final int[] index ;
    public final int[] maskList ;
    public final int length ;
    public final int count ;
    
    /**
     * 行一覧を元に、行マスクインデックス群を生成.
     * @param line 対象の行一覧を設定します.
     * @return LineMaskIndex[] 行マスクインデックス群が返却されます.
     */
    public static final MaskLine[] create( final int[][] line ) {
        int cnt = 0 ;
        final int len = line.length ;
        MaskLine[] ret = new MaskLine[ len ] ;
        for( int i = 0 ; i < len ; i ++ ) {
            ret[ i ] = new MaskLine( line[ i ],cnt ) ;
            cnt += ret[ i ].length ;
        }
        return ret ;
    }
    
    /**
     * コンストラクタ.
     * @param line 対象１インデックスのライン情報を設定します.
     * @param cnt 前回項目数を設定します.
     */
    protected MaskLine( final int[] line,int cnt ) {
        
        Mask n ;
        int i,no,key ;
        int len = line.length ;
        NOKeyValue<Mask> list = new NOKeyValue<Mask>( len ) ;
        
        for( i = 0 ; i < len ; i ++ ) {
            key = ( no = line[ i ] ) >> 5 ;
            if( ( n = list.get( key ) ) == null ) {
                list.put( key,new Mask( 1 << ( no & 31 ) ) ) ;
            }
            else {
                n.value |= 1 << ( no & 31 ) ;
            }
        }
        
        len = list.size() ;
        int[] idx = new int[ len ] ;
        int[] msk = new int[ len ] ;
        
        i = 0 ;
        list.reset() ;
        while( list.hasNext() ) {
            idx[ i ] = list.next() ;
            msk[ i ++ ] = list.nextValue().value ;
        }
        
        index = idx ;
        maskList = msk ;
        length = line.length ;
        count = cnt ;
    }
    
}

