List <TableUpdate> BuildTablesUpdate(Dictionary <uint, List <RowAction> > tablesTrans) { var keys = tablesTrans.Keys; var updates = new List <TableUpdate>(keys.Count); foreach (uint idTable in keys) { IEnumerable <ActionInfo> infos = from RowAction ra in tablesTrans[idTable] select BuildAction(idTable, ra.RowID, ra.ActionCode); int maxSize = 0; var lst = new List <IUpdateAction>(); foreach (ActionInfo ai in infos) { if (ai.DatumSize > maxSize) { maxSize = ai.DatumSize; } lst.Add(ai.Action); } var tableUpdate = new TableUpdate(idTable, lst, maxSize, AppContext.TableManager.GetTableGeneration(idTable)); updates.Add(tableUpdate); } return(updates); }
private int AddItemToGroup(GroupByKey key, int rowIndex, out bool notify) { notify = false; List <int> rowsInGroup; int groupedIndex; if (_groupedRows.TryGetValue(key, out rowsInGroup)) { groupedIndex = _keyPositions[key]; rowsInGroup.Add(rowIndex); } else { rowsInGroup = new List <int>(); groupedIndex = _groupedRows.AddWithIndex(key, rowsInGroup); _keyPositions.Add(key, groupedIndex); rowsInGroup.Add(rowIndex); foreach (var aggregateColumn in _aggregateColumns) { aggregateColumn.AddField(groupedIndex); } notify = true; // Make sure all the column values are sent too foreach (var keyColumn in _keyColumns) { _updates.OnNext(TableUpdate.NewColumnUpdate(groupedIndex, (IReactiveColumn)keyColumn)); } } return(groupedIndex); }
public override void ReplayRows(IObserver <TableUpdate> observer) { for (var i = 0; i < _groupedRows.Count; i++) { _updates.OnNext(TableUpdate.NewAddUpdate(i)); } }
public void OnNext(TableUpdate update) { if (update.Action == TableUpdateAction.Delete) { OnDelete(update); } }
private void OnNext(TableUpdate update) { var onCollectionChanged = CollectionChanged; var onPropertyChanged = PropertyChanged; if (update.Action == TableUpdateAction.Add) { if (onCollectionChanged != null) { var obj = _table.GetValue(update.Column.ColumnId, update.RowIndex); onCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, obj, update.RowIndex)); } } if (update.Action == TableUpdateAction.Update) { if (onPropertyChanged != null) { onPropertyChanged(this, new PropertyChangedEventArgs(update.Column.ColumnId)); // onCollectionChanged(this, new NotifyCollectionChangedEventArgs(Replace)); } } if (update.Action == TableUpdateAction.Delete) { if (onCollectionChanged != null) { var obj = _table.GetValue(update.Column.ColumnId, update.RowIndex); onCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, obj, update.RowIndex)); } } }
private void UpdateRowObserversAdd(IEnumerable <RowToUpdate> updatedRows, IReactiveColumn column, JoinSide side) { foreach (var updatedRow in updatedRows) { // Update that the new row exists if (updatedRow.Type == RowToUpdate.RowUpdateType.Add) { var rowUpdate = new TableUpdate(TableUpdateAction.Add, updatedRow.RowIndex); if (_updateObservers != null) { _updateObservers.OnNext(rowUpdate); } // Update all columns for newly added row on the sides that are present. var row = _rows[updatedRow.RowIndex]; if (row.HasValue && row.Value.LeftRowId.HasValue) { SendColumnUpdates(JoinSide.Left, updatedRow.RowIndex); } if (row.HasValue && row.Value.RightRowId.HasValue) { SendColumnUpdates(JoinSide.Right, updatedRow.RowIndex); } } else { // Update all rows on the side that has been added and also on the other side if also joined SendColumnUpdates(side, updatedRow.RowIndex); } } }
private bool PropagateColumnUpdates(TableUpdate update, int columnRowIndex, IReactiveTable table, Dictionary <int, HashSet <int> > columnRowsToJoinRows, JoinSide side) { HashSet <int> joinRows; IReactiveColumn updateColumn; if (table.GetColumnByName(update.Column.ColumnId, out updateColumn) && columnRowsToJoinRows.TryGetValue(columnRowIndex, out joinRows)) { foreach (var joinRow in joinRows) { var row = _rows[joinRow]; if (row.HasValue && row.Value.RowId.HasValue && !IsRowUnlinked(row.Value, side)) { var colUpdate = new TableUpdate(TableUpdateAction.Update, joinRow, update.Column); if (_updateObservers != null) { _updateObservers.OnNext(colUpdate); } return(true); } } } return(false); }
private void ProcessColumnUpdate(TableUpdate update, IReactiveColumn column) { JoinSide side; var columnRowIndex = update.RowIndex; if (column.Equals(_leftColumn)) { side = JoinSide.Left; } else if (column.Equals(_rightColumn)) { side = JoinSide.Right; } else { // Column upates after tables are joined - if this column is joined propagate the update, otherwise ignore var propagated = PropagateColumnUpdates(update, columnRowIndex, _leftTable, _leftColumnRowsToJoinRows, JoinSide.Left); propagated = propagated || PropagateColumnUpdates(update, columnRowIndex, _rightTable, _rightColumnRowsToJoinRows, JoinSide.Right); return; } // Processing a join column var updatedRows = OnColumnUpdate(columnRowIndex, side); if (updatedRows != null && updatedRows.Count > 0) { UpdateRowObserversAdd(updatedRows, column, side); } }
/// <summary> /// Keep the key dictionaries up to date when the key columns are updated. /// </summary> /// <param name="update"></param> private void OnNext(TableUpdate update, JoinSide side) { // Filter out add/deletes if (update.Action == TableUpdateAction.Delete) { return; } // If we have an add and which is a replay of the underlying tables then we need to // simulate column updates for all columns if (update.Action == TableUpdateAction.Add) { if (!_replaying) { return; } var columns = GetTableColumns(side); foreach (var column in columns) { update = new TableUpdate(TableUpdateAction.Update, update.RowIndex, column); ProcessColumnUpdate(update, column); } } else { // Key update ProcessColumnUpdate(update, update.Column); } }
private void DeleteAllRows() { for (var i = 0; i < _sorter.RowCount; i++) { var delete = new TableUpdate(TableUpdateAction.Delete, i); _subject.OnNext(delete); } }
public void OnColumnUpdate(TableUpdate update) { if (update.IsColumnUpdate()) { LastColumnsUpdated.Add(update.Column.ColumnId); LastRowsUpdated.Add(update.RowIndex); } }
/// <summary> /// 1. New row arrives /// - Need to propagate event at the righ row position /// - Update the positions of other rows (invalidate the view) /// 2. Row is updated /// - If the key column changes we need to re-sort and then do a BinarySearch to find the new position /// - If another column changes we need to find the row position using the key and BinarySearch to propagate /// - Update the positions of other rows (invalidate the view) /// 3. Row at position X scrolls into view /// - Go get the row id at the given position /// </summary> /// <param name="update"></param> /// <param name="needToResort"></param> /// <returns></returns> public int OnNext(TableUpdate update, out bool needToResort) { var sortColValue = _sourceTable.GetValue <T>(_sortColumnId, update.RowIndex); var keyValuePair = new KeyValuePair <T, int>(sortColValue, update.RowIndex); needToResort = false; var sortedRowId = -1; switch (update.Action) { case TableUpdateAction.Add: _keysToRows.Add(keyValuePair); _rowIdsToValues.Add(update.RowIndex, sortColValue); needToResort = true; break; case TableUpdateAction.Delete: sortedRowId = _keysToRows.BinarySearch(keyValuePair, _keyComparer); _keysToRows.RemoveAt(sortedRowId); _rowIdsToValues.Remove(update.RowIndex); needToResort = true; break; case TableUpdateAction.Update: { // Sort column updating if (update.Column.ColumnId == _sortColumnId) { var oldValue = _rowIdsToValues[update.RowIndex]; var oldSortColValue = new KeyValuePair <T, int>(oldValue, update.RowIndex); _keysToRows[_keysToRows.BinarySearch(oldSortColValue, _keyComparer)] = keyValuePair; _rowIdsToValues[update.RowIndex] = sortColValue; needToResort = true; } // Other column - row can't change position else { // In order to avoid this binary search and others should we rather keep build a list of rowIds to indeces at each re-sort? sortedRowId = _keysToRows.BinarySearch(keyValuePair, _keyComparer); } } break; } // Keep the table sorted if (needToResort) { _keysToRows.Sort((pair1, pair2) => _comparer.Compare(pair1.Key, pair2.Key)); sortedRowId = _keysToRows.BinarySearch(keyValuePair, _keyComparer); } // Find the now row id else if (sortedRowId < 0) { sortedRowId = _keysToRows.BinarySearch(keyValuePair, _keyComparer); } return(sortedRowId); }
public void DeleteRow(int rowIndex) { lock (_shared) { _rowManager.DeleteRow(rowIndex); var update = new TableUpdate(TableUpdateAction.Delete, rowIndex); _rowUpdatesDelete.Enqueue(update); } }
private void OnNext(TableUpdate update) { var onListChanged = ListChanged; if (onListChanged != null) { var listChangedEventArgs = GetListChangedEventArgs(update); onListChanged(this, listChangedEventArgs); } }
private void OnNext(TableUpdate update) { if (update.Action == TableUpdateAction.Add) { PersonAccounts.Add(new PersonAccountViewModel(_personAccounts, update.RowIndex)); } else if (update.Action == TableUpdateAction.Delete) { PersonAccounts.RemoveAt(PersonAccounts.GetIndexForKey(update.RowIndex)); } }
private void OnNext(TableUpdate tableUpdate) { // Row is being deleted var sourceRowIndex = tableUpdate.RowIndex; if (tableUpdate.Action == TableUpdateAction.Delete) { RemoveNotVisibleRow(sourceRowIndex); return; } var shouldCheck = tableUpdate.Action == TableUpdateAction.Add || _predicate.Columns.Contains(tableUpdate.Column.ColumnId); if (!shouldCheck) { // If the row exists but we're updating a different column then propagate the update. int filterRowIndex; if (_sourceRowToFilterRow.TryGetValue(sourceRowIndex, out filterRowIndex)) { OnUpdate(filterRowIndex, tableUpdate.Column); } return; } var rowIsVisible = _predicate.RowIsVisible(_sourceTable, sourceRowIndex); int filterRow; // We already have this row mapped var isMapped = _sourceRowToFilterRow.TryGetValue(sourceRowIndex, out filterRow); if (isMapped) { // Already exists but is no longer visible if (!rowIsVisible) { RemoveNotVisibleRow(sourceRowIndex); } // otherwise do we need to propagate the column update else { OnUpdate(filterRow, tableUpdate.Column); } } // No mapping yet else { // Has just appeared if (rowIsVisible) { AddVisibleRow(sourceRowIndex); } // otherwise do nothing } }
private void OnRowUpdate(TableUpdate u) { if (u.Action == TableUpdateAction.Add) { Items.Add(new SimpleGroupItem(_groupedTable, u.RowIndex)); } else if (u.Action == TableUpdateAction.Delete) { Items.RemoveAt(Items.IndexOf(item => item.RowIndex == u.RowIndex)); } }
private void SendColumnUpdates(JoinSide side, int rowIndex) { var table = GetTableForSide(side); foreach (var tableColumn in table.Columns) { var columnUpdate = new TableUpdate(TableUpdateAction.Update, rowIndex, tableColumn); if (_updateObservers != null) { _updateObservers.OnNext(columnUpdate); } } }
public int AddRow() { int rowIndex; lock (_shared) { rowIndex = _rowManager.AddRow(); var update = new TableUpdate(TableUpdateAction.Add, rowIndex); _rowUpdatesAdd.Enqueue(update); } //Debug.WriteLine("Added row {0} to batched passthrough", rowIndex); return(rowIndex); }
private void OnNext(TableUpdate update) { bool needToResort; var sortedRowId = _sorter.OnNext(update, out needToResort); // Propagate the update _subject.OnNext(new TableUpdate(update.Action, sortedRowId, update.Column)); if (needToResort) { _rowPosUpdatedSubject.OnNext(true); } }
private void OnDelete(TableUpdate update) { // If there is no mapping the joined row no longer exists and there's nothing to update. if (!_columnRowsToJoinRows.ContainsKey(update.RowIndex)) { return; } var joinRowIds = _columnRowsToJoinRows[update.RowIndex]; if (joinRowIds.Count < 0) { return; } var rowUpdates = new List <TableUpdate>(); // Get the key and row id to use from the first element var firstJoinRowId = joinRowIds.First(); var key = _rows[firstJoinRowId].Value.Key; var colRowMappings = _rowsByKey[key].ColRowMappings; // Make a copy as we'll modify the original inside the loop var joinRowIdsCopy = joinRowIds.ToList(); /* * 1. Blank our side * 2. If the other side has more than one entry for its row id then blank it * 3. For all rows where both sides are blank delete the row */ foreach (var joinRowId in joinRowIdsCopy) { var row = _rows[joinRowId]; if (!row.HasValue) { throw new NotImplementedException(); } DeleteRowMapping(row, joinRowId, colRowMappings, update); } // 3. For all rows where both sides are blank delete the row DeleteClearedRows(colRowMappings, rowUpdates, key, joinRowIdsCopy); if (rowUpdates.Count > 0) { UpdateObservers(rowUpdates); } }
private static ListChangedEventArgs GetListChangedEventArgs(TableUpdate update) { if (update.Action == TableUpdateAction.Add) { return(new ListChangedEventArgs(ListChangedType.ItemAdded, update.RowIndex)); } if (update.Action == TableUpdateAction.Delete) { return(new ListChangedEventArgs(ListChangedType.ItemDeleted, update.RowIndex)); } if (update.Action == TableUpdateAction.Update) { return(new ListChangedEventArgs(ListChangedType.ItemChanged, update.RowIndex)); } throw new NotImplementedException("Unknown update action " + update.Action); }
private void OnTableUpdate(TableUpdate tableUpdate, IReactiveTable table, SbeTableEncoderState encodeState) { var offset = 0; _header.Wrap(_buffer, offset, MessageTemplateVersion); _header.SchemaId = SbeTableUpdate.SchemaId; _header.TemplateId = SbeTableUpdate.TemplateId; // identifier for the table update object (SBE template ID) _header.Version = SbeTableUpdate.Schema_Version; // this can be overriden if we want to support different versions of the table update object (advanced functionality) offset += MessageHeader.Size; _update.WrapForEncode(_buffer, offset); _update.Type = MapType(tableUpdate.Action); _update.RowId = tableUpdate.RowIndex; offset += _update.Size; if (tableUpdate.Action == TableUpdateAction.Update) { int fieldId; if (!encodeState.ColumnsToFieldIds.TryGetValue(tableUpdate.Column.ColumnId, out fieldId)) { return; } _update.FieldId = fieldId; offset += WriteUpdateValue(table, tableUpdate, _buffer, offset); } _header.BlockLength = (ushort)offset; // size that a table update takes on the wire Debug.WriteLine("Writing block length of {0} for row {1}", _header.BlockLength, _update.RowId); _outputStream.Write(_byteArray, 0, offset); // Write all the columns after each add. if (tableUpdate.Action == TableUpdateAction.Add) { Debug.WriteLine("Sent new row {0}", _update.RowId); foreach (var columnId in encodeState.ColumnsToFieldIds.Keys) { OnTableUpdate(new TableUpdate(TableUpdateAction.Update, tableUpdate.RowIndex, table.GetColumnByName(columnId)), table, encodeState); } } }
//handlers: private void Tables_SelectedIndexChanged(object sender, EventArgs e) { int ndx = m_lbTables.SelectedIndex; m_lvActions.Items.Clear(); if (ndx < 0) { m_lblPostGenerationValue.Text = m_lblPreGenerationValue.Text = ""; } else { TableUpdate update = (m_lbTables.Items[ndx] as ListBoxData).Update; m_lblPostGenerationValue.Text = update.PostGeneration.ToString(); m_lblPreGenerationValue.Text = update.PreGeneration.ToString(); m_lvActions.Items.AddRange(update.Actions.Select(act => CreateItem(act)).ToArray()); } }
private void OnNext(TableUpdate tableUpdate) { if (tableUpdate.IsRowUpdate()) { Model.RowCount += tableUpdate.Action == TableUpdateAction.Add ? 1 : -1; } else { // Get the col position first as it's much cheaper than row position. var colIndex = ViewModel.GetColPosition(tableUpdate.Column.ColumnId) + Model.HeaderColumns; // TODO: handle updates to multiple columns (i.e. CellSpanInfo) if (IsColumnVisible(colIndex)) { var rowIndex = ViewModel.GetRowPosition(tableUpdate.RowIndex) + Model.HeaderRows; if (IsRowVisible(rowIndex)) { Model.InvalidateCell(new RowColumnIndex(rowIndex, colIndex)); } } } }
public void Navigate(ViewType viewType) { if (!ViewsDictionary.ContainsKey(viewType)) { InitializeView(viewType); } ContentOwner.Content = ViewsDictionary[viewType]; switch (viewType) { case ViewType.UsersTable: TableUpdate.Update(); break; case ViewType.UserEditing: TableUpdate.InitEdit(); break; default: break; } }
public ListBoxData(TableUpdate update) { Update = update; }
private void OnNext(TableUpdate tableUpdate) { _subject.OnNext(tableUpdate); }
private void OnNextLeft(TableUpdate update) { OnNext(update, JoinSide.Left); }
private void OnNextRight(TableUpdate update) { OnNext(update, JoinSide.Right); }