internal ReadRowsStream(
     BigtableClientImpl client,
     ReadRowsRequest originalRequest,
     CallSettings callSettings,
     RetrySettings retrySettings)
 {
     _enumerator = new RowAsyncEnumerator(client, originalRequest, callSettings, retrySettings);
 }
            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);
                }
Beispiel #3
0
 /// <inheritdoc/>
 public IAsyncEnumerator <Row> GetAsyncEnumerator(CancellationToken cancellationToken)
 {
     lock (_lock)
     {
         if (_enumerator != null)
         {
             throw new InvalidOperationException($"The {nameof(ReadRowsStream)} can only be iterated once");
         }
         _enumerator = new RowAsyncEnumerator(_client, _originalRequest, _callSettings, _retrySettings, cancellationToken);
         return(_enumerator);
     }
 }
Beispiel #4
0
            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 abstract RowMergeState HandleChunk(RowAsyncEnumerator owner, CellChunk chunk);
Beispiel #8
0
            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);
                }