/// <summary> /// Initializes a new instance of the <see cref="Scan"/> class. /// </summary> /// <param name="planOperator">The descriptive query plan operator that is the counterpart of this physical operator.</param> /// <param name="cursor">The triple cursor used for reading in triples.</param> /// <param name="inputSortOrder">The sort order the triples arrive in.</param> /// <param name="pattern">The Simple Access Pattern to match.</param> /// <param name="count">The number of triples to read.</param> public Scan(qp::Operator planOperator, TripleCursor cursor, SortOrder inputSortOrder, Triple <TripleItem, TripleItem, TripleItem> pattern, long count = -1) { m_planOperator = planOperator; #if DEBUG m_planOperator.StartCPUWork(); #endif m_cursor = cursor; m_inputOrder = inputSortOrder; m_pattern = pattern; if (count > -1) { m_isMiniBucket = true; m_count = count; } else { m_isMiniBucket = false; } // // identify the atoms in the given SAP to match m_patternAtoms = TriplePosition.None; if (m_pattern.S is Atom) { m_patternAtoms |= TriplePosition.S; } if (m_pattern.P is Atom) { m_patternAtoms |= TriplePosition.P; } if (m_pattern.O is Atom) { m_patternAtoms |= TriplePosition.O; } #if DEBUG m_planOperator.StopCPUWork(); #endif // // prepare the next set of output bindings TryReadNext(); }
/// <summary> /// Computes the variables present in the output stream (binding sets) generated by this /// operator. /// </summary> /// <param name="op">The operator instance.</param> /// <returns> /// The variables present in the binding sets outputted by this operator. /// </returns> public static long[] GetOutputVariables(this qp::Operator op) { if (op is qp::Sort) { return((op as qp::Sort).Input.GetOutputVariables()); } else if (op is qp::Scan) { return((op as qp::Scan).SelectPattern.GetVariables()); } else if (op is qp::HashJoin) { var opHash = op as qp::HashJoin; var vars = new HashSet <long>(); foreach (var v in opHash.Left.GetOutputVariables()) { vars.Add(v); } foreach (var v in opHash.Right.GetOutputVariables()) { vars.Add(v); } return(vars.ToArray()); } else if (op is qp::MergeJoin) { var opMerge = op as qp::MergeJoin; var vars = new HashSet <long>(); foreach (var v in opMerge.Left.GetOutputVariables()) { vars.Add(v); } foreach (var v in opMerge.Right.GetOutputVariables()) { vars.Add(v); } return(vars.ToArray()); } else { return(new long[] { }); } }
/// <summary> /// Initializes a new instance of the <see cref="MergeJoin"/> class. /// </summary> /// <param name="planOperator">The descriptive query plan operator that is the counterpart of this physical operator.</param> /// <param name="left">This operator's left input operator.</param> /// <param name="right">This operator's right input operator.</param> /// <param name="inputSortOrder">The input sort order for the join variables.</param> public MergeJoin(qp::Operator planOperator, Operator left, Operator right, Variable[] inputSortOrder) { if (inputSortOrder.Length == 0) { throw new ArgumentOutOfRangeException("inputSortOrder", "Provide a non-empty input sort ordering!"); } m_planOperator = planOperator; m_left = left; m_right = right; m_sortOrder = inputSortOrder; m_comparer = new BindingSetComparer(m_sortOrder); m_mode = ReadingMode.Advance; m_blockPos = 0; m_blockSize = 0; // // prepare the next set of output bindings TryReadNext(); }
/// <summary> /// Initializes a new instance of the <see cref="HashJoin"/> class. /// </summary> /// <param name="planOperator">The descriptive query plan operator that is the counterpart of this physical operator.</param> /// <param name="left">This operator's left input operator.</param> /// <param name="right">This operator's right input operator.</param> public HashJoin(qp::Operator planOperator, Operator left, Operator right) { m_planOperator = planOperator; #if DEBUG m_planOperator.StartCPUWork(); #endif m_left = left; m_right = right; m_tmpDbsCreated = false; m_joinVariables = new List <Variable>(); m_byteComparer = new ByteArrayComparer(1); m_chunkTable = new Dictionary <byte[], List <BindingSet> >(new ByteArrayEqualityComparer()); m_currentChunkList = new Queue <BindingSet>(); #if DEBUG m_planOperator.StopCPUWork(); #endif // // prepare the next set of output bindings TryReadNext(); }
/// <summary> /// Computes the sort order for the output generated by this operator. /// </summary> /// <param name="op">The operator instance.</param> /// <returns> /// An integer array representing the output sort order. /// </returns> public static long[] GetOutputSortOrder(this qp::Operator op) { if (op is qp::Sort) { return((op as qp::Sort).SortOrder); } else if (op is qp::Scan) { var opScan = op as qp::Scan; var order = new List <long>(); switch (opScan.Bucket) { case TriplePosition.None: break; case TriplePosition.S: if (opScan.SelectPattern.SType == Pattern.ItemType.Variable) { order.Add((long)opScan.SelectPattern.S); } if (opScan.SelectPattern.OType == Pattern.ItemType.Variable) { order.Add((long)opScan.SelectPattern.O); } if (opScan.SelectPattern.PType == Pattern.ItemType.Variable) { order.Add((long)opScan.SelectPattern.P); } break; case TriplePosition.P: if (opScan.SelectPattern.PType == Pattern.ItemType.Variable) { order.Add((long)opScan.SelectPattern.P); } if (opScan.SelectPattern.SType == Pattern.ItemType.Variable) { order.Add((long)opScan.SelectPattern.S); } if (opScan.SelectPattern.OType == Pattern.ItemType.Variable) { order.Add((long)opScan.SelectPattern.O); } break; case TriplePosition.O: if (opScan.SelectPattern.OType == Pattern.ItemType.Variable) { order.Add((long)opScan.SelectPattern.O); } if (opScan.SelectPattern.SType == Pattern.ItemType.Variable) { order.Add((long)opScan.SelectPattern.S); } if (opScan.SelectPattern.PType == Pattern.ItemType.Variable) { order.Add((long)opScan.SelectPattern.P); } break; default: break; } return(order.ToArray()); } else if (op is qp::HashJoin) { return(new long[] { }); } else if (op is qp::MergeJoin) { return((op as qp::MergeJoin).SortOrder); } else { return(new long[] { }); } }