<commit_before>package org.drools.reteoo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.drools.base.evaluators.Operator;
import org.drools.common.InternalFactHandle;
import org.drools.common.InternalWorkingMemory;
import org.drools.rule.LiteralConstraint;
import org.drools.spi.Evaluator;
import org.drools.spi.FieldConstraint;
import org.drools.spi.FieldExtractor;
import org.drools.spi.PropagationContext;
import org.drools.util.LinkedList;
import org.drools.util.LinkedListNode;

public class CompositeObjectSinkAdapter
    implements
    ObjectSinkPropagator {

    private ObjectSinkNodeList otherSinks;
    private ObjectSinkNodeList hashedSinks;

    private LinkedList         hashedFieldIndexes;

    private Map                hashedSinkMap;

    private HashKey            hashKey;

    public CompositeObjectSinkAdapter() {
        this.hashKey = new HashKey();
    }

    public void addObjectSink(ObjectSink sink) {
        if ( sink.getClass() == AlphaNode.class ) {
            AlphaNode alphaNode = (AlphaNode) sink;
            FieldConstraint fieldConstraint = alphaNode.getConstraint();

            if ( fieldConstraint.getClass() == LiteralConstraint.class ) {
                LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
                Evaluator evaluator = literalConstraint.getEvaluator();

                if ( evaluator.getOperator() == Operator.EQUAL ) {
                    int index = literalConstraint.getFieldExtractor().getIndex();
                    FieldIndex fieldIndex = registerFieldIndex( index,
                                                                literalConstraint.getFieldExtractor() );

                    if ( this.hashedSinks == null ) {
                        this.hashedSinks = new ObjectSinkNodeList();
                    }

                    this.hashedSinks.add( (ObjectSinkNode) sink );

                    if ( !fieldIndex.isHashed() && fieldIndex.getCount() >= 3 ) {
                        // this is our third equal constraint for this field, so hash this index
                        hashSinks( fieldIndex );
                    }
                    return;
                }

            }
        }

        if ( this.otherSinks == null ) {
            this.otherSinks = new ObjectSinkNodeList();
        }

        this.otherSinks.add( (ObjectSinkNode) sink );
    }

    public void removeObjectSink(ObjectSink sink) {
        if ( sink.getClass() == AlphaNode.class ) {
            AlphaNode alphaNode = (AlphaNode) sink;
            FieldConstraint fieldConstraint = alphaNode.getConstraint();

            if ( fieldConstraint.getClass() == LiteralConstraint.class ) {
                LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
                Evaluator evaluator = literalConstraint.getEvaluator();
                Object value = literalConstraint.getField().getValue();

                if ( evaluator.getOperator() == Operator.EQUAL ) {
                    int index = literalConstraint.getFieldExtractor().getIndex();
                    FieldIndex fieldIndex = unregisterFieldIndex( index );
                    this.hashedSinks.remove( (ObjectSinkNode) sink );

                    if ( this.hashedSinks.isEmpty() ) {
                        this.hashedSinks = null;
                    }

                    if ( fieldIndex.isHashed() ) {
                        this.hashKey.setIndex( index );
                        this.hashKey.setValue( value );
                        hashedSinkMap.remove( this.hashKey );
                        if ( fieldIndex.getCount() <= 2 ) {
                            // we have less than three so unhash
                            unHashSinks( fieldIndex );
                        }
                    }

                    return;
                }
            }<commit_msg>JBRULES-484 refactor the core reteoo code for sinle and composite propagations -alpha node inexing bug fix<commit_after>package org.drools.reteoo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.drools.base.evaluators.Operator;
import org.drools.common.InternalFactHandle;
import org.drools.common.InternalWorkingMemory;
import org.drools.rule.LiteralConstraint;
import org.drools.spi.Evaluator;
import org.drools.spi.FieldConstraint;
import org.drools.spi.FieldExtractor;
import org.drools.spi.PropagationContext;
import org.drools.util.LinkedList;
import org.drools.util.LinkedListNode;

public class CompositeObjectSinkAdapter
    implements
    ObjectSinkPropagator {

    private ObjectSinkNodeList otherSinks;
    private ObjectSinkNodeList hashedSinks;

    private LinkedList         hashedFieldIndexes;

    private Map                hashedSinkMap;

    private HashKey            hashKey;

    public CompositeObjectSinkAdapter() {
        this.hashKey = new HashKey();
    }

    public void addObjectSink(ObjectSink sink) {
        if ( sink.getClass() == AlphaNode.class ) {
            AlphaNode alphaNode = (AlphaNode) sink;
            FieldConstraint fieldConstraint = alphaNode.getConstraint();

            if ( fieldConstraint.getClass() == LiteralConstraint.class ) {
                LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
                Evaluator evaluator = literalConstraint.getEvaluator();

                if ( evaluator.getOperator() == Operator.EQUAL ) {
                    int index = literalConstraint.getFieldExtractor().getIndex();
                    FieldIndex fieldIndex = registerFieldIndex( index,
                                                                literalConstraint.getFieldExtractor() );

                    if ( this.hashedSinks == null ) {
                        this.hashedSinks = new ObjectSinkNodeList();
                    }

                    if ( fieldIndex.getCount() >= 3 ) {
                        if ( !fieldIndex.isHashed() ) {
                            hashSinks( fieldIndex );
                       }
                        Object value = literalConstraint.getField().getValue();
                        hashedSinkMap.put( new HashKey( index,
                                                        value ),
                                           sink );    
                    } else {
                        this.hashedSinks.add( (ObjectSinkNode) sink );   
                    }
                    
                    if ( !fieldIndex.isHashed() && fieldIndex.getCount() >= 3 ) {
                        // this is our third equal constraint for this field, so hash this index
                        hashSinks( fieldIndex );
                    }
                    return;
                }

            }
        }

        if ( this.otherSinks == null ) {
            this.otherSinks = new ObjectSinkNodeList();
        }

        this.otherSinks.add( (ObjectSinkNode) sink );
    }

    public void removeObjectSink(ObjectSink sink) {
        if ( sink.getClass() == AlphaNode.class ) {
            AlphaNode alphaNode = (AlphaNode) sink;
            FieldConstraint fieldConstraint = alphaNode.getConstraint();

            if ( fieldConstraint.getClass() == LiteralConstraint.class ) {
                LiteralConstraint literalConstraint = (LiteralConstraint) fieldConstraint;
                Evaluator evaluator = literalConstraint.getEvaluator();
                Object value = literalConstraint.getField().getValue();

                if ( evaluator.getOperator() == Operator.EQUAL ) {
                    int index = literalConstraint.getFieldExtractor().getIndex();
                    FieldIndex fieldIndex = unregisterFieldIndex( index );
                    
                    if ( fieldIndex.isHashed() ) {
                        this.hashKey.setIndex( index );
                        this.hashKey.setValue( value );
                        hashedSinkMap.remove( this.hashKey );
                        if ( fieldIndex.getCount() <= 2 ) {
                            // we have less than three so unhash
                            unHashSinks( fieldIndex );
                        }
                    } else {
                        this.hashedSinks.remove( (ObjectSinkNode) sink );
                    }                   
                    
                    if ( this.hashedSinks.isEmpty() ) {
                        this.hashedSinks = null;
                    }

                    return;
                }
            }
{'fraction_non_alphanumeric': 0.08168430740911183, 'fraction_numerical': 0.0009203865623561896, 'mean_word_length': 1.584126040428062, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1920951', 'n_tokens_mistral': 2116, 'n_tokens_neox': 2028, 'n_words': 427}