Unverified Commit 2f7f6701 authored by Jan Tattermusch's avatar Jan Tattermusch Committed by GitHub

Merge pull request #6530 from prat0088/csharp-ensuresize

c# feature(RepeatedField): Capacity property to resize the internal array
parents 77646a45 da574008
......@@ -33,6 +33,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
......@@ -756,5 +757,52 @@ namespace Google.Protobuf.Collections
Assert.True(list1.Contains(SampleNaNs.SignallingFlipped));
Assert.False(list2.Contains(SampleNaNs.SignallingFlipped));
}
[Test]
public void Capacity_Increase()
{
// Unfortunately this case tests implementation details of RepeatedField. This is necessary
var list = new RepeatedField<int>() { 1, 2, 3 };
Assert.AreEqual(8, list.Capacity);
Assert.AreEqual(3, list.Count);
list.Capacity = 10; // Set capacity to a larger value to trigger growth
Assert.AreEqual(10, list.Capacity, "Capacity increased");
Assert.AreEqual(3, list.Count);
CollectionAssert.AreEqual(new int[] {1, 2, 3}, list.ToArray(), "We didn't lose our data in the resize");
}
[Test]
public void Capacity_Decrease()
{
var list = new RepeatedField<int>() { 1, 2, 3 };
Assert.AreEqual(8, list.Capacity);
Assert.DoesNotThrow(() => list.Capacity = 5, "Can decrease capacity if new capacity is greater than list.Count");
Assert.AreEqual(5, list.Capacity);
Assert.DoesNotThrow(() => list.Capacity = 3, "Can set capacity exactly to list.Count" );
Assert.Throws<ArgumentOutOfRangeException>(() => list.Capacity = 2, "Can't set the capacity smaller than list.Count" );
Assert.Throws<ArgumentOutOfRangeException>(() => list.Capacity = 0, "Can't set the capacity to zero" );
Assert.Throws<ArgumentOutOfRangeException>(() => list.Capacity = -1, "Can't set the capacity to negative" );
}
[Test]
public void Capacity_Zero()
{
var list = new RepeatedField<int>() { 1 };
list.RemoveAt(0);
Assert.AreEqual(0, list.Count);
Assert.AreEqual(8, list.Capacity);
Assert.DoesNotThrow(() => list.Capacity = 0, "Can set Capacity to 0");
Assert.AreEqual(0, list.Capacity);
}
}
}
......@@ -220,14 +220,46 @@ namespace Google.Protobuf.Collections
}
}
/// <summary>
/// Gets and sets the capacity of the RepeatedField's internal array. WHen set, the internal array is reallocated to the given capacity.
/// <exception cref="ArgumentOutOfRangeException">The new value is less than Count -or- when Count is less than 0.</exception>
/// </summary>
public int Capacity
{
get { return array.Length; }
set
{
if (value < count)
{
throw new ArgumentOutOfRangeException("Capacity", value,
$"Cannot set Capacity to a value smaller than the current item count, {count}");
}
if (value >= 0 && value != array.Length)
{
SetSize(value);
}
}
}
// May increase the size of the internal array, but will never shrink it.
private void EnsureSize(int size)
{
if (array.Length < size)
{
size = Math.Max(size, MinArraySize);
int newSize = Math.Max(array.Length * 2, size);
var tmp = new T[newSize];
Array.Copy(array, 0, tmp, 0, array.Length);
SetSize(newSize);
}
}
// Sets the internal array to an exact size.
private void SetSize(int size)
{
if (size != array.Length)
{
var tmp = new T[size];
Array.Copy(array, 0, tmp, 0, count);
array = tmp;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment