private async Task <long> SetupTableForDiffScansAsync(KuduTable table, int numRows) { for (int i = 0; i < numRows / 2; i++) { var row = ClientTestUtil.CreateBasicSchemaInsert(table, i); await _session.EnqueueAsync(row); } await _session.FlushAsync(); // Grab the timestamp, then add more data so there's a diff. long timestamp = _client.LastPropagatedTimestamp; for (int i = numRows / 2; i < numRows; i++) { var row = ClientTestUtil.CreateBasicSchemaInsert(table, i); await _session.EnqueueAsync(row); } await _session.FlushAsync(); // Delete some data so the is_deleted column can be tested. for (int i = 0; i < numRows / 4; i++) { var row = table.NewDelete(); row.SetInt32(0, i); await _session.EnqueueAsync(row); } await _session.FlushAsync(); return(timestamp); }
/// <summary> /// Generates a list of random mutation operations. Any unique row, identified by /// it's key, could have a random number of operations/mutations. However, the /// target count of numInserts, numUpdates and numDeletes will always be achieved /// if the entire list of operations is processed. /// </summary> /// <param name="table">The table to generate operations for.</param> /// <param name="numInserts">The number of row mutations to end with an insert.</param> /// <param name="numUpdates">The number of row mutations to end with an update.</param> /// <param name="numDeletes">The number of row mutations to end with an delete.</param> private List <KuduOperation> GenerateMutationOperations( KuduTable table, int numInserts, int numUpdates, int numDeletes) { var results = new List <KuduOperation>(); var unfinished = new List <MutationState>(); int minMutationsBound = 5; // Generate Operations to initialize all of the row with inserts. var changeCounts = new List <(RowOperation type, int count)> { (RowOperation.Insert, numInserts), (RowOperation.Update, numUpdates), (RowOperation.Delete, numDeletes) }; foreach (var(type, count) in changeCounts) { for (int i = 0; i < count; i++) { // Generate a random insert. var insert = table.NewInsert(); _generator.RandomizeRow(insert); var key = insert.GetInt32(0); // Add the insert to the results. results.Add(insert); // Initialize the unfinished MutationState. unfinished.Add(new MutationState(key, type, _random.Next(minMutationsBound))); } } // Randomly pull from the unfinished list, mutate it and add that operation to // the results. If it has been mutated at least the minimum number of times, // remove it from the unfinished list. while (unfinished.Count > 0) { // Get a random row to mutate. int index = _random.Next(unfinished.Count); MutationState state = unfinished[index]; // If the row is done, remove it from unfinished and continue. if (state.NumMutations >= state.MinMutations && state.CurrentType == state.EndType) { unfinished.RemoveAt(index); continue; } // Otherwise, generate an operation to mutate the row based on its current ChangeType. // insert -> update|delete // update -> update|delete // delete -> insert KuduOperation op; if (state.CurrentType == RowOperation.Insert || state.CurrentType == RowOperation.Update) { op = _random.NextBool() ? table.NewUpdate() : table.NewDelete(); } else { // Must be a delete, so we need an insert next. op = table.NewInsert(); } op.SetInt32(0, state.Key); if (op.Operation != RowOperation.Delete) { _generator.RandomizeRow(op, randomizeKeys: false); } results.Add(op); state.CurrentType = op.Operation; state.NumMutations++; } return(results); }