public void NumberListColumn_NullableCases() { // StringColumns are extremely common in object models, // so having very compact representations for common cases // is really important to file size for small databases. GenericNumberListColumn <int> column = new GenericNumberListColumn <int>(Nullability.DefaultToNull); TreeDiagnostics diagnostics; // Empty: { } diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(diagnostics.Length <= 2); // All null: { IsNull: { Count: 100, Capacity: 100 } } for (int i = 0; i < 100; ++i) { column[i] = null; } CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false)); diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(1 == diagnostics.Children.Count); Assert.True(diagnostics.Length <= 13); // All empty: Only nulls false written List <int> empty = new List <int>(); for (int i = 0; i < 100; ++i) { column[i] = empty; } CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false)); diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(1 == diagnostics.Children.Count); Assert.True(diagnostics.Length <= 13); // No nulls, No Empty: 4b + 2.125b / value (613b) + 4 pages x 4b (16b) + overhead (~10b) List <int> single = new List <int>(); single.Add(1); for (int i = 0; i < 100; ++i) { column[i] = single; } CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false)); diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(1 == diagnostics.Children.Count); Assert.True(diagnostics.Length <= 640); // Nulls and Non-Nulls; both parts must be written column[50] = null; CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false)); diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(2 == diagnostics.Children.Count); Assert.True(diagnostics.Length <= 670); }
public void NumberListColumn_Basics() { NumberListColumn <int> column = new NumberListColumn <int>(); column[0].SetTo(new ArraySlice <int>(new int[] { 0, 1, 2 })); TreeDiagnostics diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); int tinyColumnLength = (int)diagnostics.Length; Column.Basics(() => new NumberListColumn <int>(), NumberList <int> .Empty, column[0], (index) => { column[index].SetTo(new ArraySlice <int>(new int[] { index, index + 1, index + 2 })); return(column[index]); }); // NumberList Equals, GetHashCode int[] asArray = new int[] { 0, 1, 3 }; column[1].SetTo(new ArraySlice <int>(asArray)); Assert.False(column[0] == column[1]); Assert.True(column[0] != column[1]); Assert.NotEqual(column[0].GetHashCode(), column[1].GetHashCode()); // Compare to array Assert.True(column[1].Equals(asArray)); }
public void StringColumn_EmptyCases() { // StringColumns are extremely common in object models, // so having very compact representations for common cases // is really important to file size for small databases. StringColumn column = new StringColumn(); TreeDiagnostics diagnostics; // Empty: { } diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(diagnostics.Length <= 2); // All null: { IsNull: { Count: 100, Capacity: 100 } } for (int i = 0; i < 100; ++i) { column[i] = null; } CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false)); diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(1 == diagnostics.Children.Count); Assert.True(diagnostics.Length <= 13); // All empty: Only nulls false written for (int i = 0; i < 100; ++i) { column[i] = ""; } CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false)); diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(1 == diagnostics.Children.Count); Assert.True(diagnostics.Length <= 13); // No nulls, No Empty: 3b / value (2b end + 1b text) + 4 pages x 4b + 20b overhead for (int i = 0; i < 100; ++i) { column[i] = "-"; } CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false)); diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(1 == diagnostics.Children.Count); Assert.True(diagnostics.Length <= 336); // Nulls and Non-Nulls; both parts must be written column[50] = null; CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false)); diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); Assert.True(2 == diagnostics.Children.Count); Assert.True(diagnostics.Length <= 336 + 40); }
public void Database_Basics() { V1.Community community = new V1.Community(); community.People = new List <V1.Person>(); community.People.Add(new V1.Person() { Age = 39, Name = "Scott" }); community.People.Add(new V1.Person() { Age = 36, Name = "Adam" }); // Use ReadOnlyList.VerifySame to check count, enumerators, and indexer community.DB.Save("V1.Community.bsoa", TreeFormat.Binary); V1.Community roundTripped = new V1.Community(); roundTripped.DB.Load("V1.Community.bsoa", TreeFormat.Binary); CollectionReadVerifier.VerifySame(community.People, roundTripped.People); // Try loading database with size diagnostics TreeDiagnostics diagnostics = TreeSerializer.Diagnostics(community.DB, () => new V1.Community().DB, TreeFormat.Binary); // Verify table and column names in diagnostics string text = diagnostics.ToString(); Assert.Contains("Person", text); Assert.Contains("Age", text); Assert.Contains("Name", text); // Verify Person has two columns, Write doesn't throw Assert.Equal("Person", diagnostics.Children[0].Name); Assert.Equal(Names.Columns, diagnostics.Children[0].Children[0].Name); Assert.Equal(2, diagnostics.Children[0].Children[0].Children.Count); diagnostics.Write(Console.Out, 3); // Verify Trim doesn't throw (results not visible) community.DB.Trim(); CollectionReadVerifier.VerifySame(community.People, roundTripped.People); // Verify Copy constructor recursively copies (List.SetTo -> LocalIndex -> CopyFrom construction) V1.Community copy = new V1.Community(community); CollectionReadVerifier.VerifySame(community.People, copy.People); community.People[0].Age += 10; Assert.NotEqual(community.People[0].Age, copy.People[0].Age); // Verify Database.Clear works community.DB.Clear(); var people = community.People; Assert.True(people == null || people.Count == 0); }
public void BooleanColumn_AllDefault() { BooleanColumn c = new BooleanColumn(true); // Set a large number of values all to the default for (int i = 0; i < 8192; ++i) { c[i] = true; } // Verify the column serializes small (not to one bit per row) TreeDiagnostics diagnostics = TreeSerializer.Diagnostics(c, () => new BooleanColumn(true), TreeFormat.Binary); Assert.True(diagnostics.Length < 100); }
public void NumberListColumn_Basics() { NumberListColumn <int> column = new NumberListColumn <int>(); column[0].SetTo(new ArraySlice <int>(new int[] { 0, 1, 2 })); TreeDiagnostics diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); int tinyColumnLength = (int)diagnostics.Length; Column.Basics(() => new NumberListColumn <int>(), NumberList <int> .Empty, column[0], (index) => { column[index].SetTo(new ArraySlice <int>(new int[] { index, index + 1, index + 2 })); return(column[index]); }); // NumberList Equals, GetHashCode int[] asArray = new int[] { 0, 1, 3 }; column[1].SetTo(new ArraySlice <int>(asArray)); Assert.False(column[0] == column[1]); Assert.True(column[0] != column[1]); Assert.NotEqual(column[0].GetHashCode(), column[1].GetHashCode()); // Compare to array Assert.True(column[1].Equals(asArray)); // ForEach column.Clear(); column[0].SetTo(new ArraySlice <int>(new int[] { 0, 1, 2 })); int sum = 0; column.ForEach((slice) => { int[] array = slice.Array; int end = slice.Index + slice.Count; for (int i = slice.Index; i < end; ++i) { sum += array[i]; } }); Assert.Equal(3, sum); }
public void GenericNumberListColumn_Basics() { List <int> empty = new List <int>(); GenericNumberListColumn <int> column = new GenericNumberListColumn <int>(); column[0] = new int[] { 0, 1, 2 }; TreeDiagnostics diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary); int tinyColumnLength = (int)diagnostics.Length; Column.Basics(() => new GenericNumberListColumn <int>(), null, column[0], (index) => { IList <int> values = column[index]; if (values == null || values.Count == 0) { column[index] = new int[] { index, index + 1, index + 2 }; values = column[index]; } return(values); }); // ForEach column.Clear(); column[0] = new int[] { 0, 1, 2 }; int sum = 0; column.ForEach((slice) => { int[] array = slice.Array; int end = slice.Index + slice.Count; for (int i = slice.Index; i < end; ++i) { sum += array[i]; } }); Assert.Equal(3, sum); }