//A column under a <Node> (or <View>) element is either a declaration (build meta data only) or defines an entry in the parent's ViewColumnNode
            public void BuildNodeValue(ViewTable.Builder.BuildingData buildingData, ViewTable vTable, ViewTable.Builder.Node node, long row, ViewTable parentViewTable, Operation.ExpressionParsingContext expressionParsingContext, ref Database.MetaColumn metaColum)
            {
                BuildOrUpdateDeclaration(buildingData, vTable, ref metaColum, expressionParsingContext);

                //If the parent's node data type is Node
                if (node.parent != null && node.parent.data.type == ViewTable.Builder.Node.Data.DataType.Node)
                {
                    // this column is an entry in the parent's column
                    var option = new Operation.Expression.ParseIdentifierOption(buildingData.Schema, parentViewTable, true, true, metaColum != null ? metaColum.Type.scriptingType : null, expressionParsingContext);
                    option.formatError = (string s, Operation.Expression.ParseIdentifierOption opt) =>
                    {
                        return(FormatErrorContextInfo(buildingData.Schema, parentViewTable) + " : " + s);
                    };
                    Operation.Expression expression = Operation.Expression.ParseIdentifier(value, option);

                    //if the meta column does not have a type defined yet, define it as the expression's type.
                    if (metaColum.Type.scriptingType == null)
                    {
                        DataMatchMethod matchMethod = expression.type == typeof(string) ? DataMatchMethod.AsString : DataMatchMethod.AsNumber;
                        metaColum.Type = new MetaType()
                        {
                            scriptingType = expression.type, comparisonMethod = matchMethod
                        };
                    }
                    ViewColumnNode.IViewColumnNode column = BuildOrGetColumnNode(parentViewTable, metaColum, name, expressionParsingContext);
                    column.SetEntry(row, expression, m_MetaLink);
                }
            }
Exemplo n.º 2
0
        public override int Compare(long rowLhs, Operation.Expression expression, long rowRhs)
        {
            Operation.Operation.ComparableComparator comparator = Operation.Operation.GetComparator(type, expression.type);
            var val1   = GetRowValue(rowLhs);
            var val2   = expression.GetComparableValue(rowRhs);
            int result = comparator(val1, val2);

            return(result);
        }
Exemplo n.º 3
0
 // Set a Node value to the merged result of it's sub entries
 public static void BuildNodeValueDefault(ViewTable.Builder.Node node, long row, ViewSchema vs, Database.Schema baseSchema, ViewTable parentViewTable, Operation.ExpressionParsingContext expressionParsingContext, Database.MetaColumn metaColumn)
 {
     //set the entry for merge column
     if (metaColumn.DefaultMergeAlgorithm != null && metaColumn.Type != null)
     {
         ViewColumnNode.IViewColumnNode column     = BuildOrGetColumnNode(parentViewTable, metaColumn, metaColumn.Name, expressionParsingContext);
         Operation.Expression           expression = Operation.ColumnCreator.CreateTypedExpressionColumnMerge(metaColumn.Type, parentViewTable, row, column.GetColumn(), metaColumn);
         column.SetEntry(row, expression, null);
     }
 }
Exemplo n.º 4
0
            public IViewColumn Build(ViewTable.Builder.Node node, ViewSchema vs, Database.Schema baseSchema, ViewTable vTable, Operation.ExpressionParsingContext expressionParsingContext, ref Database.MetaColumn metaColumn)
            {
                // Check if we have a type mismatch
                Type columnValueType = metaColumn != null ? metaColumn.Type : null;

                if (value.type != null)
                {
                    if (columnValueType != null && columnValueType != value.type)
                    {
                        DebugUtility.LogWarning("While building column '" + name + "' : "
                                                + "Cannot override type from '" + columnValueType.Name
                                                + "' to '" + value.type.Name + "'");
                    }
                    columnValueType = value.type;
                }

                // Parse expression value
                Operation.Expression.ParseIdentifierOption parseOpt = new Operation.Expression.ParseIdentifierOption(vs, vTable, true, false, columnValueType, expressionParsingContext);
                parseOpt.formatError = (string s, Operation.Expression.ParseIdentifierOption opt) => {
                    return(FormatErrorContextInfo(vs, vTable) + " : " + s);
                };

                Operation.Expression expression = Operation.Expression.ParseIdentifier(value, parseOpt);


                // Build declaration with the type we've just parsed
                BuildOrUpdateDeclaration(ref metaColumn, expression.type);

                IViewColumn result = (IViewColumn)Operation.ColumnCreator.CreateViewColumnExpression(expression);
                ViewColumn  vc     = new ViewColumn();

                vc.m_MetaLink     = m_MetaLink;
                vc.viewTable      = vTable;
                vc.ParsingContext = expressionParsingContext;
                result.SetColumn(vc, null);
                return(result);
            }
Exemplo n.º 5
0
            //A column under a <Node> (or <View>) element is either a declaration (build meta data only) or defines an entry in the parent's ViewColumnNode
            public void BuildNodeValue(ViewTable.Builder.Node node, long row, ViewSchema vs, Database.Schema baseSchema, ViewTable parentViewTable, Operation.ExpressionParsingContext expressionParsingContext, ref Database.MetaColumn metaColum)
            {
                BuildOrUpdateDeclaration(ref metaColum);

                //If the parent's node data type is Node
                if (node.parent != null && node.parent.data.type == ViewTable.Builder.Node.Data.DataType.Node)
                {
                    // this column is an entry in the parent's column
                    var option = new Operation.Expression.ParseIdentifierOption(vs, parentViewTable, true, true, metaColum != null ? metaColum.Type : null, expressionParsingContext);
                    option.formatError = (string s, Operation.Expression.ParseIdentifierOption opt) =>
                    {
                        return(FormatErrorContextInfo(vs, parentViewTable) + " : " + s);
                    };
                    Operation.Expression expression = Operation.Expression.ParseIdentifier(value, option);

                    //if the meta column does not have a type defined yet, define it as the expression's type.
                    if (metaColum.Type == null)
                    {
                        metaColum.Type = expression.type;
                    }
                    ViewColumnNode.IViewColumnNode column = BuildOrGetColumnNode(parentViewTable, metaColum, name, expressionParsingContext);
                    column.SetEntry(row, expression, m_MetaLink);
                }
            }
Exemplo n.º 6
0
 void ViewColumnNode.IViewColumnNode.SetEntry(long row, Operation.Expression exp, TableLink link)
 {
     m_Cache.SetEntryDirty((int)row);
     entries[(int)row]     = exp as Operation.TypedExpression <DataT>;
     linkEntries[(int)row] = link;
 }
Exemplo n.º 7
0
 //returning indice array is always in ascending index order
 public abstract long[] GetMatchIndex(ArrayRange rowRange, Operation.Operator op, Operation.Expression exp, long expRowFirst, bool rowToRow);
Exemplo n.º 8
0
 public abstract long GetFirstMatchIndex(Operation.Operator op, Operation.Expression exp, long expRowFirst);
 public void Add(string key, Operation.Expression value)
 {
     m_Parameters.Add(key, value);
 }
Exemplo n.º 10
0
 public abstract int Compare(long rowLhs, Operation.Expression exp, long rowRhs);
 void ViewColumnNode.IViewColumnNode.SetEntry(long row, Operation.Expression exp, TableLink link)
 {
 }
 public bool TryGet(string key, out Operation.Expression value)
 {
     return(m_Parameters.TryGetValue(key, out value));
 }
Exemplo n.º 13
0
            public override long[] GetMatchIndex(ArrayRange rowRange, Operation.Operator operation, Operation.Expression expression, long expressionRowFirst, bool rowToRow)
            {
                if (expression.type != type)
                {
                    return(base.GetMatchIndex(rowRange, operation, expression, expressionRowFirst, rowToRow));
                }
                Update();
                Operation.TypedExpression <int> typedExpression = expression as Operation.TypedExpression <int>;
                long count          = rowRange.Count;
                var  matchedIndices = new List <long>(128);

                if (rowToRow)
                {
                    for (long i = 0; i != count; ++i)
                    {
                        var lhs = m_Cache[rowRange[i]];
                        var rhs = typedExpression.GetValue(expressionRowFirst + i);
                        if (Operation.Operation.Match(operation, lhs, rhs))
                        {
                            matchedIndices.Add(rowRange[i]);
                        }
                    }
                }
                else
                {
                    if (Operation.Operation.IsOperatorOneToMany(operation))
                    {
                        for (int i = 0; i != count; ++i)
                        {
                            var leftValue = m_Cache[rowRange[i]];
                            if (Operation.Operation.Match(operation, leftValue, typedExpression, expressionRowFirst))
                            {
                                matchedIndices.Add(rowRange[i]);
                            }
                        }
                    }
                    else
                    {
                        var valueRight = typedExpression.GetValue(expressionRowFirst);
                        //Optimization for equal operation when querying on all data
                        if (rowRange.IsSequence && operation == Operation.Operator.Equal)
                        {
                            //use the sorted index to trim down invalid values
                            long[] sortedIndex     = GetSortIndexAsc();
                            int    lowerIndexIndex = LowerBoundIndex(sortedIndex, (int)rowRange.Sequence.First, (int)rowRange.Count, valueRight);
                            int    upperIndexIndex = (int)rowRange.Sequence.Last;
                            for (int i = lowerIndexIndex; i < upperIndexIndex; ++i)
                            {
                                if (m_Cache[sortedIndex[i]] == valueRight)
                                {
                                    matchedIndices.Add(sortedIndex[i]);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            for (int i = 0; i != count; ++i)
                            {
                                var leftValue = m_Cache[rowRange[i]];
                                if (Operation.Operation.Match(operation, leftValue, valueRight))
                                {
                                    matchedIndices.Add(rowRange[i]);
                                }
                            }
                        }
                    }
                }

                var matchedIndicesArray = matchedIndices.ToArray();

                return(matchedIndicesArray);
            }
        public override long GetFirstMatchIndex(Operation.Operator operation, Operation.Expression expression, long expRowFirst)
        {
            Update();
            long[] sortedIndex = GetSortIndexAsc();

            Operation.Operation.ComparableComparator comparator = Operation.Operation.GetComparator(type, expression.type);
            var val2 = expression.GetComparableValue(expRowFirst);

            long firstMatchIndex = -1;

            switch (operation)
            {
            case Operation.Operator.Less:
            {
                long iFirst = sortedIndex[0];
                var  val1   = GetRowValue(iFirst);
                int  result = comparator(val1, val2);
                if (result < 0)
                {
                    firstMatchIndex = iFirst;
                }
                break;
            }

            case Operation.Operator.LessEqual:
            {
                long iFirst = sortedIndex[0];
                var  val1   = GetRowValue(iFirst);
                int  result = comparator(val1, val2);
                if (result <= 0)
                {
                    firstMatchIndex = iFirst;
                }
                break;
            }

            case Operation.Operator.Equal:
            {
                long iFirstGreaterEqual = LowerBound(val2, comparator);
                if (iFirstGreaterEqual < sortedIndex.Length)
                {
                    long index            = sortedIndex[iFirstGreaterEqual];
                    var  val1             = GetRowValue(index);
                    int  comparisonResult = comparator(val1, val2);
                    if (comparisonResult == 0)
                    {
                        firstMatchIndex = index;
                    }
                }
                break;
            }

            case Operation.Operator.GreaterEqual:
            {
                long iFirstGreaterEqual = LowerBound(val2, comparator);
                if (iFirstGreaterEqual < sortedIndex.Length)
                {
                    firstMatchIndex = sortedIndex[iFirstGreaterEqual];
                }
                break;
            }

            case Operation.Operator.Greater:
            {
                long iFirstGreater = UpperBound(val2, comparator);
                if (iFirstGreater < sortedIndex.Length)
                {
                    firstMatchIndex = sortedIndex[iFirstGreater];
                }
                break;
            }
            }
            return(firstMatchIndex);
        }
        public override long[] GetMatchIndex(ArrayRange rowRange, Operation.Operator operation, Operation.Expression expression, long expressionRowFirst, bool rowToRow)
        {
            Update();
            long count = rowRange.Count;

            long[] matchedIndices          = new long[count];
            long   indexOflastMatchedIndex = 0;

            Operation.Operation.ComparableComparator comparator = Operation.Operation.GetComparator(type, expression.type);
            if (rowToRow)
            {
                for (long i = 0; i != count; ++i)
                {
                    var leftValue = GetRowValue(rowRange[i]);
                    if (Operation.Operation.Match(operation, comparator, leftValue, expression, expressionRowFirst + i))
                    {
                        matchedIndices[indexOflastMatchedIndex] = rowRange[i];
                        ++indexOflastMatchedIndex;
                    }
                }
            }
            else
            {
                if (Operation.Operation.IsOperatorOneToMany(operation))
                {
                    for (int i = 0; i != count; ++i)
                    {
                        var leftValue = GetRowValue(rowRange[i]);
                        if (Operation.Operation.Match(operation, comparator, leftValue, expression, expressionRowFirst))
                        {
                            matchedIndices[indexOflastMatchedIndex] = rowRange[i];
                            ++indexOflastMatchedIndex;
                        }
                    }
                }
                else
                {
                    var valueRight = expression.GetComparableValue(expressionRowFirst);
                    for (int i = 0; i != count; ++i)
                    {
                        var leftValue = GetRowValue(rowRange[i]);
                        if (Operation.Operation.Match(operation, comparator, leftValue, valueRight))
                        {
                            matchedIndices[indexOflastMatchedIndex] = rowRange[i];
                            ++indexOflastMatchedIndex;
                        }
                    }
                }
            }

            if (indexOflastMatchedIndex != count)
            {
                System.Array.Resize(ref matchedIndices, (int)indexOflastMatchedIndex);
            }

            return(matchedIndices);
        }
Exemplo n.º 16
0
        protected long[] GetMatchIndex(ArrayRange indices, Operation.Matcher matcher, Operation.Expression exp)
        {
            //translate group matches to row matches
            if (m_Table.m_RowData.Length == m_Table.m_GroupRowDataRange.Length)
            {
                //all group are closed, group matches are == to row matches
                return(matcher.GetMatchIndex(exp, indices));
            }
            else
            {
                //some group are expanded
                bool   matchAllData = indices.IsSequence && indices.Count == m_Table.m_RowData.Length;
                long[] groupMatches;
                if (matchAllData)
                {
                    //when asking to test all data, test all group
                    groupMatches = matcher.GetMatchIndex(exp, new ArrayRange(0, m_Column.GetRowCount()));
                }
                else
                {
                    //when asking to test only a subset of the data, test only the groups that fall in the indices range
                    var l = new System.Collections.Generic.List <long>((int)indices.Count);
                    for (int i = 0; i != indices.Count; ++i)
                    {
                        var row = indices[i];
                        if (m_Table.m_RowData[row].isGroupHead())
                        {
                            l.Add(m_Table.m_RowData[row].groupIndex);
                        }
                    }

                    groupMatches = matcher.GetMatchIndex(exp, new ArrayRange(l.ToArray()));
                }

                // translate from a list of group index to a list of index including the group's subdata
                var matches = new System.Collections.Generic.List <long>(m_Table.m_RowData.Length);
                for (int i = 0; i != groupMatches.Length; ++i)
                {
                    var groupIndex = groupMatches[i];
                    var groupRange = m_Table.m_GroupRowDataRange[groupIndex];
                    for (long j = groupRange.First; j != groupRange.Last; ++j)
                    {
                        matches.Add(j);
                    }
                }
                return(matches.ToArray());
            }
        }
Exemplo n.º 17
0
            public override long[] GetMatchIndex(ArrayRange rowRange, Operation.Operator operation, Operation.Expression expression, long expressionRowFirst, bool rowToRow)
            {
                if (expression.type != type)
                {
                    return(base.GetMatchIndex(rowRange, operation, expression, expressionRowFirst, rowToRow));
                }
                using (Profiling.GetMarker(Profiling.MarkerId.ColumnMatchQueryInt).Auto())
                {
                    Update();
                    Operation.TypedExpression <int> typedExpression = expression as Operation.TypedExpression <int>;
                    long count          = rowRange.Count;
                    var  matchedIndices = new List <long>(128);
                    if (rowToRow)
                    {
                        for (long i = 0; i != count; ++i)
                        {
                            var lhs = m_Cache[rowRange[i]];
                            var rhs = typedExpression.GetValue(expressionRowFirst + i);
                            if (Operation.Operation.Match(operation, lhs, rhs))
                            {
                                matchedIndices.Add(rowRange[i]);
                            }
                        }
                    }
                    else
                    {
                        if (Operation.Operation.IsOperatorOneToMany(operation))
                        {
                            for (int i = 0; i != count; ++i)
                            {
                                var leftValue = m_Cache[rowRange[i]];
                                if (Operation.Operation.Match(operation, leftValue, typedExpression, expressionRowFirst))
                                {
                                    matchedIndices.Add(rowRange[i]);
                                }
                            }
                        }
                        else
                        {
                            var valueRight = typedExpression.GetValue(expressionRowFirst);
                            //Optimization for equal operation when querying on all data
                            if (rowRange.IsSequence && operation == Operation.Operator.Equal)
                            {
                                //use the sorted index to trim down invalid values
                                long[] sortedIndex     = GetSortIndexAsc();
                                int    lowerIndexIndex = LowerBoundIndex(sortedIndex, (int)rowRange.Sequence.First, (int)rowRange.Count, valueRight);
                                int    upperIndexIndex = (int)rowRange.Sequence.Last;
                                for (int i = lowerIndexIndex; i < upperIndexIndex; ++i)
                                {
                                    if (m_Cache[sortedIndex[i]] == valueRight)
                                    {
                                        matchedIndices.Add(sortedIndex[i]);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
#if PROFILER_DEBUG_TEST
                                {
                                    //Test to validate if optimization works
                                    int matchCount = 0;
                                    for (int i = 0; i != count; ++i)
                                    {
                                        var leftValue = m_Cache[rowRange[i]];
                                        if (Operation.Operation.Match(operation, leftValue, valueRight))
                                        {
                                            ++matchCount;
                                            if (matchedIndices.FindIndex(x => x == rowRange[i]) < 0)
                                            {
                                                UnityEngine.Debug.LogError("GetMatchIndex Optimization failure on index " + rowRange[i]);
                                            }
                                        }
                                    }
                                    if (matchCount != matchedIndices.Count)
                                    {
                                        UnityEngine.Debug.LogError("GetMatchIndex Optimization failure on match count " + matchCount + " != " + matchedIndices.Count);
                                    }
                                }
#endif
                            }
                            else
                            {
                                for (int i = 0; i != count; ++i)
                                {
                                    var leftValue = m_Cache[rowRange[i]];
                                    if (Operation.Operation.Match(operation, leftValue, valueRight))
                                    {
                                        matchedIndices.Add(rowRange[i]);
                                    }
                                }
                            }
                        }
                    }

                    var matchedIndicesArray = matchedIndices.ToArray();

#if MEMPROFILER_DEBUG_INFO
                    Algorithm.DebugLog("GetMatchIndex : indexCount " + rowRange.Count
                                       + " op:" + Operation.Operation.OperatorToString(operation)
                                       + " Exp():" + expression.GetValueString(expressionRowFirst, DefaultDataFormatter.Instance)
                                       + " expRowFirst:" + expressionRowFirst
                                       + " Column:" + this.GetDebugString(rowRange[0])
                                       + " Expression:" + expression.GetDebugString(expressionRowFirst)
                                       + " Result Count:" + (matchedIndices != null ? matchedIndices.Length : 0));
#endif

                    return(matchedIndicesArray);
                }
            }
Exemplo n.º 18
0
        public override long[] GetMatchIndex(ArrayRange rowRange, Operation.Operator operation, Operation.Expression expression, long expressionRowFirst, bool rowToRow)
        {
            using (Profiling.GetMarker(Profiling.MarkerId.ColumnMatchQuery).Auto())
            {
                Update();
                long   count                   = rowRange.Count;
                long[] matchedIndices          = new long[count];
                long   indexOflastMatchedIndex = 0;
                Operation.Operation.ComparableComparator comparator = Operation.Operation.GetComparator(type, expression.type);
                if (rowToRow)
                {
                    for (long i = 0; i != count; ++i)
                    {
                        var leftValue = GetRowValue(rowRange[i]);
                        if (Operation.Operation.Match(operation, comparator, leftValue, expression, expressionRowFirst + i))
                        {
                            matchedIndices[indexOflastMatchedIndex] = rowRange[i];
                            ++indexOflastMatchedIndex;
                        }
                    }
                }
                else
                {
                    if (Operation.Operation.IsOperatorOneToMany(operation))
                    {
                        for (int i = 0; i != count; ++i)
                        {
                            var leftValue = GetRowValue(rowRange[i]);
                            if (Operation.Operation.Match(operation, comparator, leftValue, expression, expressionRowFirst))
                            {
                                matchedIndices[indexOflastMatchedIndex] = rowRange[i];
                                ++indexOflastMatchedIndex;
                            }
                        }
                    }
                    else
                    {
                        var valueRight = expression.GetComparableValue(expressionRowFirst);
                        for (int i = 0; i != count; ++i)
                        {
                            var leftValue = GetRowValue(rowRange[i]);
                            if (Operation.Operation.Match(operation, comparator, leftValue, valueRight))
                            {
                                matchedIndices[indexOflastMatchedIndex] = rowRange[i];
                                ++indexOflastMatchedIndex;
                            }
                        }
                    }
                }

                if (indexOflastMatchedIndex != count)
                {
                    System.Array.Resize(ref matchedIndices, (int)indexOflastMatchedIndex);
                }

#if MEMPROFILER_DEBUG_INFO
                Algorithm.DebugLog("GetMatchIndex : indexCount " + rowRange.Count
                                   + " op:" + Operation.Operation.OperatorToString(operation)
                                   + " Exp():" + expression.GetValueString(expressionRowFirst, DefaultDataFormatter.Instance)
                                   + " expRowFirst:" + expressionRowFirst
                                   + " Column:" + this.GetDebugString(rowRange[0])
                                   + " Expression:" + expression.GetDebugString(expressionRowFirst)
                                   + " Result Count:" + (matchedIndices != null ? matchedIndices.Length : 0));
#endif

                return(matchedIndices);
            }
        }
Exemplo n.º 19
0
        public override long GetFirstMatchIndex(Operation.Operator operation, Operation.Expression expression, long expRowFirst)
        {
            using (Profiling.GetMarker(Profiling.MarkerId.ColumnFirstMatchQuery).Auto())
            {
                Update();
                long[] sortedIndex = GetSortIndexAsc();

                Operation.Operation.ComparableComparator comparator = Operation.Operation.GetComparator(type, expression.type);
                var val2 = expression.GetComparableValue(expRowFirst);

                long firstMatchIndex = -1;
                switch (operation)
                {
                case Operation.Operator.Less:
                {
                    long iFirst = sortedIndex[0];
                    var  val1   = GetRowValue(iFirst);
                    int  result = comparator(val1, val2);
                    if (result < 0)
                    {
                        firstMatchIndex = iFirst;
                    }
                    break;
                }

                case Operation.Operator.LessEqual:
                {
                    long iFirst = sortedIndex[0];
                    var  val1   = GetRowValue(iFirst);
                    int  result = comparator(val1, val2);
                    if (result <= 0)
                    {
                        firstMatchIndex = iFirst;
                    }
                    break;
                }

                case Operation.Operator.Equal:
                {
                    long iFirstGreaterEqual = LowerBound(val2, comparator);
                    if (iFirstGreaterEqual < sortedIndex.Length)
                    {
                        long index            = sortedIndex[iFirstGreaterEqual];
                        var  val1             = GetRowValue(index);
                        int  comparisonResult = comparator(val1, val2);
                        if (comparisonResult == 0)
                        {
                            firstMatchIndex = index;
                        }
                    }
                    break;
                }

                case Operation.Operator.GreaterEqual:
                {
                    long iFirstGreaterEqual = LowerBound(val2, comparator);
                    if (iFirstGreaterEqual < sortedIndex.Length)
                    {
                        firstMatchIndex = sortedIndex[iFirstGreaterEqual];
                    }
                    break;
                }

                case Operation.Operator.Greater:
                {
                    long iFirstGreater = UpperBound(val2, comparator);
                    if (iFirstGreater < sortedIndex.Length)
                    {
                        firstMatchIndex = sortedIndex[iFirstGreater];
                    }
                    break;
                }
                }
#if (PROFILER_DEBUG_TEST)
                {
                    long count      = sortedIndex.Length;
                    long resultTest = -1;
                    for (long i = 0; i != count; ++i)
                    {
                        long index            = sortedIndex[i];
                        var  val              = GetRowValue(index);
                        int  comparisonResult = comparator(val, val2);
                        bool matchResult      = Operation.Operation.Match(operation, comparisonResult);
                        if (matchResult)
                        {
                            resultTest = index;
                            break;
                        }
                    }
                    UnityEngine.Debug.Assert(resultTest == firstMatchIndex);
                    if (resultTest >= 0)
                    {
                        var  val1             = GetRowValue(resultTest);
                        int  comparisonResult = comparator(val1, val2);
                        bool resultMatch      = Operation.Operation.Match(operation, comparisonResult);
                        UnityEngine.Debug.Assert(resultMatch);
                    }
                }
#endif

#if MEMPROFILER_DEBUG_INFO
                Algorithm.DebugLog("GetFirstMatchIndex :"
                                   + " op:" + Operation.Operation.OperatorToString(operation)
                                   + " Exp():" + expression.GetValueString(expRowFirst, DefaultDataFormatter.Instance)
                                   + " expRowFirst:" + expRowFirst
                                   + " Column:" + this.GetDebugString(0)
                                   + " Expression:" + expression.GetDebugString(expRowFirst)
                                   + " Result:" + firstMatchIndex);
#endif
                return(firstMatchIndex);
            }
        }