private ColumnRowMapping MoveKeyEntry(List <Row?> rows, int existingRowIndex, TKey oldKey, TKey newKey, Dictionary <int, HashSet <int> > columnRowsToJoinRows, ColumnRowMapping keyRowsMapping, Dictionary <TKey, ColumnRowMapping> rowsByKey) { throw new NotImplementedException(); // Clear all matching left key entries // If inner mode optionally remove the rows too // Run the usual process for creating a mapping with the new key (including new rows being added) // Note: What will happen with non contiguous row ids!? Should I set to null for the time being? // The index will no longer match the RowId. Set to null and keep a list(queue) of old keys to reuse? // Undo the mapping on the existing column mapping rowsByKey[oldKey].ColRowMappings.FirstOrDefault(); // Redo the mapping for the new column mapping // Change the key on the Row entry var row = rows[existingRowIndex].Value; row.Key = newKey; rows[existingRowIndex] = row; }
private void AddNewRowMapping(int columnRowIndex, JoinSide side, ColumnRowMapping keyRowsMapping, List <RowToUpdate> updateRows, TKey key, Dictionary <int, HashSet <int> > otherColumnRowsToJoinRows, Dictionary <int, HashSet <int> > columnRowsToJoinRows) { // For each distinct row on the other side we need to create a new row and link ourselves var otherRows = GetDistinctOtherRows(keyRowsMapping, side); var otherRowIds = otherRows.ToArray(); foreach (var otherRowId in otherRowIds) { int?joinedRowId = GetNewRowId(); var joinRow = CreateNewLinkedJoinRow(columnRowIndex, joinedRowId.Value, key, otherRowId, side); keyRowsMapping.ColRowMappings.Add(joinRow); AddNewRow(joinRow, updateRows, joinedRowId.Value); // Update the reverse lookup columnRowsToJoinRows.GetOrAddNew(columnRowIndex).Add(joinedRowId.Value); otherColumnRowsToJoinRows.GetOrAddNew(otherRowId.Value).Add(joinedRowId.Value); } // If there are no matching entries on the other side we still need to add a row and mapping if (otherRowIds.Length == 0) { UpdateNewKeyInExistingMapping(columnRowIndex, side, key, updateRows, columnRowsToJoinRows, keyRowsMapping); } }
private static IEnumerable <int?> GetDistinctOtherRows(ColumnRowMapping keyRowsMapping, JoinSide side) { if (side == JoinSide.Left) { return(keyRowsMapping.ColRowMappings.Where(r => r.RightRowId.HasValue).Select(r => r.RightRowId).Distinct()); } return(keyRowsMapping.ColRowMappings.Where(r => r.LeftRowId.HasValue).Select(r => r.LeftRowId).Distinct()); }
private ColumnRowMapping UpdateNewKey(int columnRowIndex, JoinSide side, TKey key, List <RowToUpdate> updateRows, Dictionary <int, HashSet <int> > columnRowsToJoinRows) { // First time this key has been used so create a new (unlinked on the other side) var keyRowsMapping = new ColumnRowMapping { ColRowMappings = new List <Row>() }; UpdateNewKeyInExistingMapping(columnRowIndex, side, key, updateRows, columnRowsToJoinRows, keyRowsMapping); return(keyRowsMapping); }
private void UpdateNewKeyInExistingMapping(int columnRowIndex, JoinSide side, TKey key, List <RowToUpdate> updateRows, Dictionary <int, HashSet <int> > columnRowsToJoinRows, ColumnRowMapping keyRowsMapping) { var shouldAddUnlinkedRow = ShouldAddUnlinkedRow(side); var joinedRowId = shouldAddUnlinkedRow ? GetNewRowId() : (int?)null; var joinRow = CreateNewJoinRow(columnRowIndex, key, joinedRowId, side); keyRowsMapping.ColRowMappings.Add(joinRow); if (shouldAddUnlinkedRow) { AddNewRow(joinRow, updateRows, joinedRowId.Value); // Update the reverse lookup columnRowsToJoinRows.GetOrAddNew(columnRowIndex).Add(joinedRowId.Value); } }
private void LinkNewItemToUnlinkedRows(int columnRowIndex, JoinSide side, ColumnRowMapping keyRowsMapping, List <RowToUpdate> updateRows, Dictionary <int, HashSet <int> > otherColumnRowsToJoinRows, Dictionary <int, HashSet <int> > columnRowsToJoinRows, int i) { int?joinedRowId; // Link the row to the joined row. var rowToLink = keyRowsMapping.ColRowMappings[i]; LinkRow(ref rowToLink, columnRowIndex, side); // We need to create the new row here (when we link) if (!rowToLink.RowId.HasValue) { joinedRowId = GetNewRowId(); rowToLink.RowId = joinedRowId; // Can't forget to update the existing row object with the new id AddNewRow(rowToLink, updateRows, joinedRowId.Value); // Need to update the reverse mapping for the other side too as it wasn't done before var otherRowId = side == JoinSide.Left ? rowToLink.RightRowId : rowToLink.LeftRowId; otherColumnRowsToJoinRows.GetOrAddNew(otherRowId.Value).Add(joinedRowId.Value); } else { updateRows.Add(new RowToUpdate { RowIndex = rowToLink.RowId.Value, Type = RowToUpdate.RowUpdateType.Link }); joinedRowId = rowToLink.RowId; } keyRowsMapping.ColRowMappings[i] = rowToLink; _rows[joinedRowId.Value] = rowToLink; // Update the reverse lookup columnRowsToJoinRows.GetOrAddNew(columnRowIndex).Add(joinedRowId.Value); }
private void UpdateNewRow(int columnRowIndex, JoinSide side, ColumnRowMapping keyRowsMapping, List <RowToUpdate> updateRows, TKey key, Dictionary <int, HashSet <int> > otherColumnRowsToJoinRows, Dictionary <int, HashSet <int> > columnRowsToJoinRows) { // Other side rows exist with no mapping - try to join to an unlinked one var unlinkedIndex = keyRowsMapping.ColRowMappings.FindIndex(IsRowUnlinked(side)); if (unlinkedIndex >= 0) { for (var i = unlinkedIndex; i < keyRowsMapping.ColRowMappings.Count; i++) { LinkNewItemToUnlinkedRows(columnRowIndex, side, keyRowsMapping, updateRows, otherColumnRowsToJoinRows, columnRowsToJoinRows, i); } } // No unlinked - add new mappings and rows for each row on the other side else { AddNewRowMapping(columnRowIndex, side, keyRowsMapping, updateRows, key, otherColumnRowsToJoinRows, columnRowsToJoinRows); } }
private void UpdateExistingRow(int columnRowIndex, JoinSide side, ColumnRowMapping keyRowsMapping, HashSet <int> existingRowIndeces, TKey key, Dictionary <int, HashSet <int> > columnRowsToJoinRows) { // Same key as before if (keyRowsMapping.ColRowMappings.Any(FindKeyByRow(columnRowIndex, side))) { // Do nothing } // Key has changed else { foreach (var rowId in existingRowIndeces) { var oldKey = _rows[rowId].Value.Key; // TODO: Need to possibly alter other keyRowMappings - not possible with current method signature. keyRowsMapping = MoveKeyEntry(_rows, rowId, oldKey, key, columnRowsToJoinRows, keyRowsMapping, _rowsByKey); } } }