public override RowMergeState HandleChunk(RowAsyncEnumerator owner, CellChunk chunk) { owner.Assert( chunk.RowKey.IsEmpty || chunk.RowKey == owner._currentCell.Row.Key, "NewCell must have the same key as the current row"); if (chunk.FamilyName != null) { if (chunk.FamilyName != owner._currentCell.Family?.Name) { owner._currentCell.Family = new Family { Name = chunk.FamilyName }; Debug.Assert(!owner._currentFamilies.ContainsKey(chunk.FamilyName)); owner._currentFamilies[chunk.FamilyName] = owner._currentCell.Family; } owner.Assert(chunk.Qualifier != null, "NewCell has a familyName, but no qualifier"); } if (chunk.Qualifier != null && chunk.Qualifier != owner._currentCell.Column?.Qualifier) { owner._currentCell.Column = new Column { Qualifier = chunk.Qualifier }; owner.Assert( owner._currentCell.Family != null, "NewCell has a qualifier, but no familyName"); owner._currentCell.Family.Columns.Add(owner._currentCell.Column); } owner._currentCell.Timestamp = chunk.TimestampMicros; owner._currentCell.Labels = chunk.Labels; owner.Assert(chunk.Value != null, "NewCell must have a value"); // calculate cell size owner._currentCell.ValueSizeExpected = chunk.ValueSize > 0 ? chunk.ValueSize : chunk.Value.Length; owner._currentCell.ValueSizeRemaining = owner._currentCell.ValueSizeExpected - chunk.Value.Length; if (owner._currentCell.ValueSizeRemaining != 0) { ref var accumulator = ref owner._currentCell.ValueAccumulator; if (accumulator == null) { accumulator = new List <byte>(owner._currentCell.ValueSizeExpected); } else { Debug.Assert(accumulator.Count == 0); accumulator.Capacity = Math.Max(owner._currentCell.ValueSizeExpected, accumulator.Capacity); } owner._currentCell.ValueAccumulator.AddRange(chunk.Value); return(CellInProgress.Instance); }
public override RowMergeState HandleChunk(RowAsyncEnumerator owner, CellChunk chunk) { owner.Assert(chunk.RowKey != null && !chunk.RowKey.IsEmpty, "NewRow must have a rowKey"); owner.Assert(chunk.FamilyName != null, "NewRow must have a family"); owner.Assert(chunk.Qualifier != null, "NewRow must have a qualifier"); owner.Assert( owner._currentCell.Row == null || BigtableByteString.Compare(owner._currentCell.Row.Key, chunk.RowKey) < 0, "NewRow key must be greater than the previous row's"); // WARNING: owner._currentCell is a struct value. Do not extract as a local (which will make a copy). owner._currentCell.Row = new Row { Key = chunk.RowKey }; owner._currentCell.Family = null; owner._currentCell.Column = null; owner._currentCell.Timestamp = 0; owner._currentCell.Labels = null; // auto transition return(NewCell.Instance.HandleChunk(owner, chunk)); }
public override RowMergeState HandleChunk(RowAsyncEnumerator owner, CellChunk chunk) { if (chunk.ResetRow) { return(owner.ResetRow(chunk)); } owner.Assert( chunk.RowKey.IsEmpty || chunk.RowKey == owner._currentCell.Row.Key, "Cell row keys must not change"); bool isSplit = chunk.ValueSize > 0; if (isSplit) { owner.Assert( !chunk.CommitRow, "NewCell can't commit when valueSize indicates more data"); owner.Assert( !chunk.Value.IsEmpty, "NewCell must have data when valueSize promises more data in the next chunk"); } owner.Assert(chunk.ValueSize >= 0, "NewCell valueSize can't be negative"); if (chunk.FamilyName != null) { if (chunk.FamilyName != owner._currentCell.Family?.Name) { owner._currentCell.Family = new Family { Name = chunk.FamilyName }; Debug.Assert(!owner._currentFamilies.ContainsKey(chunk.FamilyName)); owner._currentFamilies[chunk.FamilyName] = owner._currentCell.Family; } owner.Assert(chunk.Qualifier != null, "NewCell has a familyName, but no qualifier"); } if (chunk.Qualifier != null && chunk.Qualifier != owner._currentCell.Column?.Qualifier) { owner._currentCell.Column = new Column { Qualifier = chunk.Qualifier }; owner.Assert( owner._currentCell.Family != null, "NewCell has a qualifier, but no familyName"); owner._currentCell.Family.Columns.Add(owner._currentCell.Column); } owner._currentCell.Timestamp = chunk.TimestampMicros; owner._currentCell.Labels = chunk.Labels; // calculate cell size owner._currentCell.ValueSizeExpected = isSplit ? chunk.ValueSize : chunk.Value.Length; owner._currentCell.ValueSizeRemaining = owner._currentCell.ValueSizeExpected - chunk.Value.Length; if (owner._currentCell.ValueSizeRemaining != 0) { ref var accumulator = ref owner._currentCell.ValueAccumulator; if (accumulator == null) { accumulator = new List <byte>(owner._currentCell.ValueSizeExpected); } else { Debug.Assert(accumulator.Count == 0); accumulator.Capacity = Math.Max(owner._currentCell.ValueSizeExpected, accumulator.Capacity); } owner._currentCell.ValueAccumulator.AddRange(chunk.Value); return(CellInProgress.Instance); }
public virtual RowMergeState CommitRow(RowAsyncEnumerator owner) { owner.Assert(false, $"Cannot commit a row from {GetType().Name}"); return(this); }
public override RowMergeState HandleChunk(RowAsyncEnumerator owner, CellChunk chunk) { // update name & make sure it changed bool idChanged = false; if (chunk.FamilyName != null) { if (chunk.FamilyName != owner._currentCell.Family?.Name) { idChanged = true; owner._currentCell.Family = new Family { Name = chunk.FamilyName }; owner._currentCell.Row.Families.Add(owner._currentCell.Family); } owner.Assert(chunk.Qualifier != null, "NewCell has a familyName, but no qualifier"); } if (chunk.Qualifier != null && chunk.Qualifier != owner._currentCell.Column?.Qualifier) { idChanged = true; owner._currentCell.Column = new Column { Qualifier = chunk.Qualifier }; owner.Assert( owner._currentCell.Family != null, "NewCell has a qualifier, but no familyName"); owner._currentCell.Family.Columns.Add(owner._currentCell.Column); } idChanged = idChanged || owner._currentCell.Timestamp != chunk.TimestampMicros; owner._currentCell.Timestamp = chunk.TimestampMicros; idChanged = idChanged || !chunk.Labels.SequenceEqual(owner._currentCell.Labels ?? Enumerable.Empty <string>()); owner._currentCell.Labels = chunk.Labels; owner.Assert(idChanged, "NewCell must have a new identifier"); owner.Assert(chunk.Value != null, "NewCell must have a value"); // calculate cell size owner._currentCell.ValueSizeExpected = chunk.ValueSize > 0 ? chunk.ValueSize : chunk.Value.Length; owner._currentCell.ValueSizeRemaining = owner._currentCell.ValueSizeExpected - chunk.Value.Length; if (owner._currentCell.ValueSizeRemaining != 0) { ref var accumulator = ref owner._currentCell.ValueAccumulator; if (accumulator == null) { accumulator = new List <byte>(owner._currentCell.ValueSizeExpected); } else { Debug.Assert(accumulator.Count == 0); accumulator.Capacity = Math.Max(owner._currentCell.ValueSizeExpected, accumulator.Capacity); } owner._currentCell.ValueAccumulator.AddRange(chunk.Value); return(CellInProgress.Instance); }