--- BsonArray.cs.orig 2011-06-16 23:53:20.000000000 +0400 +++ BsonArray.cs 2011-06-25 01:46:38.419161300 +0400 @@ -29,7 +29,7 @@ [Serializable] public class BsonArray : BsonValue, IComparable, IEquatable, IList { #region private fields - private List values = new List(); + private List values; #endregion #region constructors @@ -38,6 +38,16 @@ /// public BsonArray() : base(BsonType.Array) { + values = new List(); + } + + /// + /// Initializes a new instance of the BsonArray class. + /// + /// Initial array capacity. + public BsonArray(int capacity) + : base(BsonType.Array) { + values = new List(capacity); } /// @@ -377,11 +387,7 @@ public BsonArray AddRange( IEnumerable values ) { - if (values != null) { - foreach (var value in values) { - this.values.Add(BsonBoolean.Create(value)); - } - } + AddRange(values, BsonBoolean.Create); return this; } @@ -393,6 +399,7 @@ public BsonArray AddRange( IEnumerable values ) { + Grow(0); if (values != null) { this.values.AddRange(values); } @@ -407,11 +414,7 @@ public BsonArray AddRange( IEnumerable values ) { - if (values != null) { - foreach (var value in values) { - this.values.Add(BsonDateTime.Create(value)); - } - } + AddRange(values, BsonDateTime.Create); return this; } @@ -423,11 +426,7 @@ public BsonArray AddRange( IEnumerable values ) { - if (values != null) { - foreach (var value in values) { - this.values.Add(BsonDouble.Create(value)); - } - } + AddRange(values, BsonDouble.Create); return this; } @@ -439,11 +438,7 @@ public BsonArray AddRange( IEnumerable values ) { - if (values != null) { - foreach (var value in values) { - this.values.Add(BsonInt32.Create(value)); - } - } + AddRange(values, BsonInt32.Create); return this; } @@ -455,11 +450,7 @@ public BsonArray AddRange( IEnumerable values ) { - if (values != null) { - foreach (var value in values) { - this.values.Add(BsonInt64.Create(value)); - } - } + AddRange(values, BsonInt64.Create); return this; } @@ -471,11 +462,7 @@ public BsonArray AddRange( IEnumerable values ) { - if (values != null) { - foreach (var value in values) { - this.values.Add(BsonValue.Create(value)); - } - } + AddRange(values, BsonValue.Create); return this; } @@ -487,11 +474,7 @@ public BsonArray AddRange( IEnumerable values ) { - if (values != null) { - foreach (var value in values) { - this.values.Add(BsonObjectId.Create(value)); - } - } + AddRange(values, BsonObjectId.Create); return this; } @@ -503,11 +486,7 @@ public BsonArray AddRange( IEnumerable values ) { - if (values != null) { - foreach (var value in values) { - this.values.Add(BsonString.Create(value)); - } - } + AddRange(values, BsonString.Create); return this; } @@ -516,9 +495,10 @@ /// /// A shallow clone of the array. public override BsonValue Clone() { - BsonArray clone = new BsonArray(); - foreach (var value in values) { - clone.Add(value.Clone()); + int count = values.Count; + BsonArray clone = new BsonArray(count); + for (int i = 0; i < count; i++) { + clone.Add(values[i].Clone()); } return clone; } @@ -606,9 +586,10 @@ /// /// A deep clone of the array. public override BsonValue DeepClone() { - BsonArray clone = new BsonArray(); - foreach (var value in values) { - clone.Add(value.DeepClone()); + int count = values.Count; + BsonArray clone = new BsonArray(count); + for (int i = 0; i < count; i++) { + clone.Add(values[i].DeepClone()); } return clone; } @@ -780,6 +761,48 @@ IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + + void Grow(int count) { + if (this.values != null) { + int capacity = this.values.Count + count; + if (this.values.Capacity < capacity) + this.values.Capacity = capacity; + } + else + this.values = new List(count); + } + + void AddRange(IEnumerable values, Func transform) { + if (values == null) { + Grow(0); + return; + } + var valuesArray = values as T[]; + if (valuesArray != null) { + int count = valuesArray.Length; + Grow(count); + for (int i = 0; i < count; i++) + this.values.Add(transform(valuesArray[i])); + } + else { + var valuesList = values as IList; + if (valuesList != null) { + int count = valuesList.Count; + Grow(count); + for (int i = 0; i < count; i++) + this.values.Add(transform(valuesList[i])); + } + else { + var vc = values as ICollection; + if (vc != null) + Grow(vc.Count); + else + Grow(0); + foreach (var value in values) + this.values.Add(transform(value)); + } + } + } #endregion #region explicit interface implementations