<commit_before>using Lucene.Net.Support;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lucene.Net.Search.Spans
{
    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    using AtomicReaderContext = Lucene.Net.Index.AtomicReaderContext;
    using IBits = Lucene.Net.Util.IBits;
    using IndexReader = Lucene.Net.Index.IndexReader;
    using Term = Lucene.Net.Index.Term;
    using TermContext = Lucene.Net.Index.TermContext;
    using ToStringUtils = Lucene.Net.Util.ToStringUtils;

    /// <summary>
    /// Matches the union of its clauses. </summary>
    public class SpanOrQuery : SpanQuery
    {
        private readonly IList<SpanQuery> clauses;
        private string field;

        /// <summary>
        /// Construct a SpanOrQuery merging the provided clauses. </summary>
        public SpanOrQuery(params SpanQuery[] clauses)
        {
            // copy clauses array into an ArrayList
            this.clauses = new List<SpanQuery>(clauses.Length);
            for (int i = 0; i < clauses.Length; i++)
            {
                AddClause(clauses[i]);
            }
        }

        /// <summary>
        /// Adds a clause to this query </summary>
        public void AddClause(SpanQuery clause)
        {
            if (field == null)
            {
                field = clause.Field;
            }
            else if (clause.Field != null && !clause.Field.Equals(field))
            {
                throw new System.ArgumentException("Clauses must have same field.");
            }
            this.clauses.Add(clause);
        }

        /// <summary>
        /// Return the clauses whose spans are matched. </summary>
        public virtual SpanQuery[] GetClauses()
        {
            return clauses.ToArray();
        }

        public override string Field
        {
            get
            {
                return field;
            }
        }

        public override void ExtractTerms(ISet<Term> terms)
        {
            foreach (SpanQuery clause in clauses)
            {
                clause.ExtractTerms(terms);
            }
        }

        public override object Clone()
        {
            int sz = clauses.Count;
            SpanQuery[] newClauses = new SpanQuery[sz];

            for (int i = 0; i < sz; i++)
            {
                newClauses[i] = (SpanQuery)clauses[i].Clone();
            }
            SpanOrQuery soq = new SpanOrQuery(newClauses);
            soq.Boost = Boost;
            return soq;
        }

        public override Query Rewrite(IndexReader reader)
        {
            SpanOrQuery clone = null;
            for (int i = 0; i < clauses.Count; i++)
            {
                SpanQuery c = clauses[i];
                SpanQuery query = (SpanQuery)c.Rewrite(reader);
                if (query != c) // clause rewrote: must clone
                {
                    if (clone == null)
                    {
                        clone = (SpanOrQuery)this.Clone();
                    }
                    clone.clauses[i] = query;
                }
            }
            if (clone != null)
            {
                return clone; // some clauses rewrote
            }
            else
            {
                return this; // no clauses rewrote
            }
        }

        public override string ToString(string field)
        {
            StringBuilder buffer = new StringBuilder();
            buffer.Append("spanOr([");
            IEnumerator<SpanQuery> i = clauses.GetEnumerator();
            bool first = true;
            while (i.MoveNext())
            {
                SpanQuery clause = i.Current;
                if (!first) buffer.Append(", ");
                buffer.Append(clause.ToString(field));
                first = false;
            }
            buffer.Append("])");
            buffer.Append(ToStringUtils.Boost(Boost));
            return buffer.ToString();
        }

        public override bool Equals(object o)
        {
            if (this == o)
            {
                return true;
            }
            if (o == null || this.GetType() != o.GetType())
            {
                return false;
            }

            SpanOrQuery that = (SpanOrQuery)o;

            if (!clauses.SequenceEqual(that.clauses))
            {
                return false;
            }

            return Boost == that.Boost;
        }

        public override int GetHashCode()
        {
            //If this doesn't work, hash all elemnts together instead. This version was used to reduce time complexity
            int h = clauses.Count == 0 ? 0 : HashHelpers.CombineHashCodes(clauses.First().GetHashCode(), clauses.Last().GetHashCode(), clauses.Count);
            h ^= (h << 10) | ((int)(((uint)h) >> 23));
            h ^= Number.SingleToRawInt32Bits(Boost);
            return h;
        }

        private class SpanQueue : Util.PriorityQueue<Spans>
        {
            private readonly SpanOrQuery outerInstance;

            public SpanQueue(SpanOrQuery outerInstance, int size)
                : base(size)
            {
                this.outerInstance = outerInstance;
            }

            protected internal override bool LessThan(Spans spans1, Spans spans2)
            {
                if (spans1.Doc == spans2.Doc)<commit_msg>Lucene.Net.Core.Search.Spans.SpanOrQuery: Changed clauses from IList<SpanQuery> to ValueList<SpanQuery> to ensure Equals() and GetHashCode() consider all clauses when comparing.<commit_after>using Lucene.Net.Support;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lucene.Net.Search.Spans
{
    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    using AtomicReaderContext = Lucene.Net.Index.AtomicReaderContext;
    using IBits = Lucene.Net.Util.IBits;
    using IndexReader = Lucene.Net.Index.IndexReader;
    using Term = Lucene.Net.Index.Term;
    using TermContext = Lucene.Net.Index.TermContext;
    using ToStringUtils = Lucene.Net.Util.ToStringUtils;

    /// <summary>
    /// Matches the union of its clauses. </summary>
    public class SpanOrQuery : SpanQuery
    {
        // LUCENENET NOTE: The hash code needs to be made from the hash codes of all elements. 
        // So, we force all subclasses to use ValueList<SpanQuery> instead of IList<SpanQuery> to ensure that logic is in place.
        private readonly ValueList<SpanQuery> clauses;
        private string field;

        /// <summary>
        /// Construct a SpanOrQuery merging the provided clauses. </summary>
        public SpanOrQuery(params SpanQuery[] clauses)
        {
            // copy clauses array into an ArrayList
            this.clauses = new ValueList<SpanQuery>(clauses.Length);
            for (int i = 0; i < clauses.Length; i++)
            {
                AddClause(clauses[i]);
            }
        }

        /// <summary>
        /// Adds a clause to this query </summary>
        public void AddClause(SpanQuery clause)
        {
            if (field == null)
            {
                field = clause.Field;
            }
            else if (clause.Field != null && !clause.Field.Equals(field))
            {
                throw new System.ArgumentException("Clauses must have same field.");
            }
            this.clauses.Add(clause);
        }

        /// <summary>
        /// Return the clauses whose spans are matched. </summary>
        public virtual SpanQuery[] GetClauses()
        {
            return clauses.ToArray();
        }

        public override string Field
        {
            get
            {
                return field;
            }
        }

        public override void ExtractTerms(ISet<Term> terms)
        {
            foreach (SpanQuery clause in clauses)
            {
                clause.ExtractTerms(terms);
            }
        }

        public override object Clone()
        {
            int sz = clauses.Count;
            SpanQuery[] newClauses = new SpanQuery[sz];

            for (int i = 0; i < sz; i++)
            {
                newClauses[i] = (SpanQuery)clauses[i].Clone();
            }
            SpanOrQuery soq = new SpanOrQuery(newClauses);
            soq.Boost = Boost;
            return soq;
        }

        public override Query Rewrite(IndexReader reader)
        {
            SpanOrQuery clone = null;
            for (int i = 0; i < clauses.Count; i++)
            {
                SpanQuery c = clauses[i];
                SpanQuery query = (SpanQuery)c.Rewrite(reader);
                if (query != c) // clause rewrote: must clone
                {
                    if (clone == null)
                    {
                        clone = (SpanOrQuery)this.Clone();
                    }
                    clone.clauses[i] = query;
                }
            }
            if (clone != null)
            {
                return clone; // some clauses rewrote
            }
            else
            {
                return this; // no clauses rewrote
            }
        }

        public override string ToString(string field)
        {
            StringBuilder buffer = new StringBuilder();
            buffer.Append("spanOr([");
            IEnumerator<SpanQuery> i = clauses.GetEnumerator();
            bool first = true;
            while (i.MoveNext())
            {
                SpanQuery clause = i.Current;
                if (!first) buffer.Append(", ");
                buffer.Append(clause.ToString(field));
                first = false;
            }
            buffer.Append("])");
            buffer.Append(ToStringUtils.Boost(Boost));
            return buffer.ToString();
        }

        public override bool Equals(object o)
        {
            if (this == o)
            {
                return true;
            }
            if (o == null || this.GetType() != o.GetType())
            {
                return false;
            }

            SpanOrQuery that = (SpanOrQuery)o;

            if (!clauses.Equals(that.clauses))
            {
                return false;
            }

            return Boost == that.Boost;
        }

        public override int GetHashCode()
        {
            //If this doesn't work, hash all elemnts together instead. This version was used to reduce time complexity
            int h = clauses.GetHashCode();
            h ^= (h << 10) | ((int)(((uint)h) >> 23));
            h ^= Number.SingleToRawInt32Bits(Boost);
            return h;
        }

        private class SpanQueue : Util.PriorityQueue<Spans>
        {
            private readonly SpanOrQuery outerInstance;

            public SpanQueue(SpanOrQuery outerInstance, int size)
                : base(size)
            {
                this.outerInstance = outerInstance;
            }

            protected internal override bool LessThan(Spans spans1, Spans spans2)
            {
                if (spans1.Doc == spans2.Doc)
{'fraction_non_alphanumeric': 0.09005792271681345, 'fraction_numerical': 0.0028564627469650082, 'mean_word_length': 1.4978200554894967, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5537856', 'n_tokens_mistral': 3281, 'n_tokens_neox': 3138, 'n_words': 948}