protected override void Expand() { // Build a selector of table values which were non-empty int[] indices = new int[_assignedIndices.Length]; byte[] metadata = this.Metadata; int count = 0; for (int i = 0; i < indices.Length; ++i) { if (metadata[i] != 0) { indices[count++] = i; } } // Save the old keys, ranks, and row indices in arrays XArray[] keyArrays = new XArray[_keys.Length]; for (int i = 0; i < _keys.Length; ++i) { keyArrays[i] = XArray.All(_keys[i].Values).Reselect(ArraySelector.Map(indices, count)); } XArray indicesArray = XArray.All(_assignedIndices).Reselect(ArraySelector.Map(indices, count)); // Expand the table Reset(HashCore.ResizeToSize(_assignedIndices.Length)); // Add items to the enlarged table FindOrAdd(keyArrays, indicesArray); }
public void Function_Coalesce_DifferingColumnTypesShouldFail() { string[] nameValues = { "Bob", "Sue", "Joseph", "Marty", "Samantha", "" }; int[] ageValues = { 50, 23, 42, 0, 0, 0 }; bool[] ageNullRows = { false, false, false, true, true, true }; bool[] birthdayNulls = { false, true, true, false, false, false }; DateTime[] birthdayValues = { new DateTime(2017, 12, 01, 0, 0, 0, DateTimeKind.Utc), new DateTime(2017, 12, 02, 0, 0, 0, DateTimeKind.Utc), new DateTime(2017, 12, 03, 0, 0, 0, DateTimeKind.Utc), new DateTime(2017, 12, 04, 0, 0, 0, DateTimeKind.Utc), new DateTime(2017, 12, 05, 0, 0, 0, DateTimeKind.Utc), new DateTime(2017, 12, 05, 0, 0, 0, DateTimeKind.Utc), }; XArray names = XArray.All(nameValues, nameValues.Length); XArray ages = XArray.All(ageValues, ageValues.Length, ageNullRows); XArray birthdays = XArray.All(birthdayValues, birthdayValues.Length, birthdayNulls); Action query = () => TableTestHarness.DatabaseContext.FromArrays(nameValues.Length) .WithColumn(new ColumnDetails("Name", typeof(string)), names) .WithColumn(new ColumnDetails("Age", typeof(int)), ages) .WithColumn(new ColumnDetails("Birthday", typeof(DateTime)), birthdays) .Query("select Coalesce([Age], [Name], [Birthday])", TableTestHarness.DatabaseContext); Assert.ThrowsException <UsageException>(query); }
private XArray Convert(XArray xarray1, XArray xarray2) { int count = xarray1.Count; if (count != xarray2.Count) { throw new InvalidOperationException("SimpleTwoArgumentFunction must get the same number of rows from each argument."); } // Allocate for results Allocator.AllocateToSize(ref _buffer, count); Allocator.AllocateToSize(ref _isNull, count); // Convert each non-null value bool areAnyNull = false; T[] array1 = (T[])xarray1.Array; U[] array2 = (U[])xarray2.Array; for (int i = 0; i < count; ++i) { int index1 = xarray1.Index(i); int index2 = xarray2.Index(i); bool rowIsNull = (xarray1.HasNulls && xarray1.NullRows[index1]) || (xarray2.HasNulls && xarray2.NullRows[index2]); areAnyNull |= rowIsNull; _isNull[i] = rowIsNull; _buffer[i] = (rowIsNull ? default(V) : _function(array1[index1], array2[index2])); } return(XArray.All(_buffer, count, (areAnyNull ? _isNull : null))); }
public XArray GetChosenRows(int startIndexInclusive, int endIndexExclusive, int startIndexInSet) { // Allocate a buffer to hold matching rows in the range Allocator.AllocateToSize(ref _rowBuffer, endIndexExclusive - startIndexInclusive); // If we haven't converted best rows to a vector, do so (one time) if (_bestRowVector == null) { ConvertChosenToVector(); } // Get rows matching the query and map them from global row IDs to XArray-relative indices // Likely better than BitVector.Page because we can't ask it to subtract or to stop by endIndex. int count = 0; for (int i = startIndexInclusive; i < endIndexExclusive; ++i) { if (_bestRowVector[i]) { _rowBuffer[count++] = i - startIndexInSet; } } // Return the matches return(XArray.All(_rowBuffer, count)); }
public void Function_Coalesce() { int[] ageValues = { 50, 23, 42, 0, -99, 0 }; int[] salaryValues = { 5, 0, 12, -3, 13, 0 }; int[] siblingValues = { -8, 0, 0, 1, 0, 2 }; bool[] ageNullRows = { false, false, false, true, true, true }; bool[] salaryNullRows = { false, true, false, true, false, true }; bool[] siblingNullRows = { true, true, true, false, true, false }; XArray ages = XArray.All(ageValues, ageValues.Length, ageNullRows); XArray salaries = XArray.All(salaryValues, salaryValues.Length, salaryNullRows); XArray siblings = XArray.All(siblingValues, siblingValues.Length, siblingNullRows); int[] expectedValues = { 50, 23, 42, 1, 13, 2 }; IXTable expected = TableTestHarness.DatabaseContext.FromArrays(ageValues.Length) .WithColumn("Coalesce", expectedValues); IXTable resultTable = TableTestHarness.DatabaseContext.FromArrays(ageValues.Length) .WithColumn(new ColumnDetails("Age", typeof(int)), ages) .WithColumn(new ColumnDetails("Salary", typeof(int)), salaries) .WithColumn(new ColumnDetails("Siblings", typeof(int)), siblings) .Query("select Coalesce([Age], [Salary], [Siblings])", TableTestHarness.DatabaseContext); TableTestHarness.AssertAreEqual(expected, resultTable, 2); }
public static void RunQueryAndVerify(Array values, string inputColumnName, Array expected, string outputColumnName, string queryText) { XArray inputxarray = XArray.All(values, values.Length); XArray expectedxarray = XArray.All(expected, expected.Length); RunQueryAndVerify(inputxarray, inputColumnName, expectedxarray, outputColumnName, queryText); }
public XArray Values() { bool[] nulls = null; if (_nullItemIndex != -1) { nulls = new bool[this.Metadata.Length]; nulls[_nullItemIndex] = true; } int[] indicesInOrder = new int[this.Count]; for (int i = 0; i < this.Metadata.Length; ++i) { if (this.Metadata[i] != 0) { indicesInOrder[_values[i]] = i; } } // Build an indexed XArray pointing to the keys in insertion order XArray keysInOrder = XArray.All(_keys, this.Count, nulls).Reselect(ArraySelector.Map(indicesInOrder, this.Count)); // Convert it to a contiguous, 0-based XArray T[] contiguousCopy = null; bool[] contiguousIsNull = null; return(keysInOrder.ToContiguous <T>(ref contiguousCopy, ref contiguousIsNull)); }
private static void RoundTrip(string columnName, int[] array, int batchSize = 128) { XDatabaseContext context = new XDatabaseContext(); string columnPath = Path.Combine("VariableIntegerReaderWriterTests", columnName); string columnPrefix = Path.Combine(columnPath, "Vl"); context.StreamProvider.Delete(columnPath); Directory.CreateDirectory(columnPath); XArray values = XArray.All(array, array.Length); using (IColumnWriter writer = new VariableIntegerWriter(context.StreamProvider, columnPrefix)) { ArraySelector page = ArraySelector.All(0).NextPage(array.Length, batchSize); while (page.Count > 0) { writer.Append(values.Reselect(page)); page = page.NextPage(array.Length, batchSize); } } XArray returned = default(XArray); using (IColumnReader reader = new VariableIntegerReader(context.StreamProvider, columnPrefix, CachingOption.AsConfigured)) { returned = reader.Read(ArraySelector.All(array.Length)); } TableTestHarness.AssertAreEqual(values, returned, array.Length); context.StreamProvider.Delete(columnPath); }
public void Append(XArray xarray) { // If we already had too many values, we're just writing them out normally if (_dictionary == null) { _valueWriter.Append(xarray); _rowCountWritten += xarray.Count; return; } // Otherwise, find the index of each value added if (_dictionary.Add(xarray, ref _currentArrayIndices)) { // If we're still under 256 values, write the indices _rowIndexWriter.Append(XArray.All(_currentArrayIndices, xarray.Count)); _rowCountWritten += xarray.Count; } else { // If we went over 256 values, convert to writing the values directly Convert(); _valueWriter.Append(xarray); _rowCountWritten += xarray.Count; return; } }
public XArray Read(ArraySelector selector) { if (selector.Indices != null) { throw new NotImplementedException(); } // Return the previous xarray if re-requested if (selector.Equals(_currentSelector)) { return(_currentArray); } // Allocate the result array Allocator.AllocateToSize(ref _array, selector.Count); // Read items in pages of 64k int byteStart = _bytesPerItem * selector.StartIndexInclusive; int byteEnd = _bytesPerItem * selector.EndIndexExclusive; int bytesRead = 0; for (int currentByteIndex = byteStart; currentByteIndex < byteEnd; currentByteIndex += ReadPageSize) { int currentByteEnd = Math.Min(byteEnd, currentByteIndex + ReadPageSize); XArray bytexarray = _byteReader.Read(ArraySelector.All(int.MaxValue).Slice(currentByteIndex, currentByteEnd)); Buffer.BlockCopy(bytexarray.Array, 0, _array, bytesRead, bytexarray.Count); bytesRead += currentByteEnd - currentByteIndex; } // Cache and return the current xarray _currentArray = XArray.All(_array, selector.Count); _currentSelector = selector; return(_currentArray); }
// Return an XArray with two empty array elements before and after the valid portion and indices pointing to the valid portion public static XArray Pad(XArray values) { Array modifiedArray = null; bool[] nulls = null; Allocator.AllocateToSize(ref modifiedArray, values.Array.Length + 4, values.Array.GetType().GetElementType()); if (values.HasNulls) { nulls = new bool[values.Array.Length + 4]; } int[] indices = new int[modifiedArray.Length]; // Copy values shifted over two (so, two default values at the beginning and two at the end) for (int i = 0; i < values.Array.Length; ++i) { indices[i] = i + 2; modifiedArray.SetValue(values.Array.GetValue(values.Index(i)), indices[i]); if (values.HasNulls) { nulls.SetValue(values.NullRows.GetValue(values.Index(i)), indices[i]); } } // Return an XArray with the padded array with the indices and shorter real length int[] remapArray = null; return(XArray.All(modifiedArray, values.Count, nulls).Select(ArraySelector.Map(indices, values.Count), ref remapArray)); }
private XArray ReadIndices(ArraySelector selector) { Allocator.AllocateToSize(ref _resultArray, selector.Count); // Read all string positions XArray positions = _positionsReader.Read(ArraySelector.All(_positionsReader.Count)); int[] positionArray = (int[])positions.Array; // Read all raw string bytes XArray bytes = _bytesReader.Read(ArraySelector.All(_bytesReader.Count)); byte[] textArray = (byte[])bytes.Array; // Update the String8 array to point to them for (int i = 0; i < selector.Count; ++i) { int rowIndex = selector.Index(i); int valueStart = (rowIndex == 0 ? 0 : positionArray[rowIndex - 1]); int valueEnd = positionArray[rowIndex]; _resultArray[i] = new String8(textArray, valueStart, valueEnd - valueStart); } // Cache the xarray and return it _currentArray = XArray.All(_resultArray, selector.Count); _currentSelector = selector; return(_currentArray); }
private void BuildChooseDictionary(CancellationToken cancellationToken) { XArray[] keyarrays = new XArray[_keyColumnGetters.Length]; int[] rowIndices = new int[XTableExtensions.DefaultBatchSize]; int totalSoFar = 0; int count; while ((count = _source.Next(XTableExtensions.DefaultBatchSize, cancellationToken)) != 0) { // Get the rank and key column arrays XArray rankArray = _rankColumnGetter(); for (int i = 0; i < keyarrays.Length; ++i) { keyarrays[i] = _keyColumnGetters[i](); } // Build a row index xarray for these global row IDs for (int i = 0; i < count; ++i) { rowIndices[i] = totalSoFar + i; } XArray rowIndexArray = XArray.All(rowIndices, count); totalSoFar += count; // Add these to the choose dictionary _dictionary.Add(keyarrays, rankArray, rowIndexArray); } }
private static void Comparer_VerifyWhereAll <T>(T[] left, T[] right, T value) where T : IComparable <T> { // Try operations between array and single value Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.Single(new T[1] { value }, left.Length), CompareOperator.Equal); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.Single(new T[1] { value }, left.Length), CompareOperator.NotEqual); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.Single(new T[1] { value }, left.Length), CompareOperator.GreaterThan); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.Single(new T[1] { value }, left.Length), CompareOperator.GreaterThanOrEqual); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.Single(new T[1] { value }, left.Length), CompareOperator.LessThan); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.Single(new T[1] { value }, left.Length), CompareOperator.LessThanOrEqual); // Try operations between two arrays Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.All(right, right.Length), CompareOperator.Equal); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.All(right, right.Length), CompareOperator.NotEqual); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.All(right, right.Length), CompareOperator.GreaterThan); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.All(right, right.Length), CompareOperator.GreaterThanOrEqual); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.All(right, right.Length), CompareOperator.LessThan); Comparer_VerifyWhere <T>(XArray.All(left, left.Length), XArray.All(right, right.Length), CompareOperator.LessThanOrEqual); }
public static void RunQueryAndVerify(Array left, Array right, Array expected, string queryText) { XArray leftXArray = XArray.All(left, left.Length); XArray rightXArray = XArray.All(right, right.Length); XArray expectedXArray = XArray.All(expected, expected.Length); RunQueryAndVerify(leftXArray, rightXArray, expectedXArray, queryText); }
public SchemaTransformer(IXTable source) : base(source) { _columns = new ArrayColumn[2]; _columns[0] = new ArrayColumn(XArray.All(_source.Columns.Select((col) => col.ColumnDetails.Name).ToArray()), new ColumnDetails("Name", typeof(string))); _columns[1] = new ArrayColumn(XArray.All(_source.Columns.Select((col) => col.ColumnDetails.Type.Name.ToString()).ToArray()), new ColumnDetails("Type", typeof(string))); _enumerateSelector = ArraySelector.All(0); }
public void Function_AsOfDate() { int[] values = Enumerable.Range(0, 5).ToArray(); DateTime[] expected = new DateTime[] { TestAsOfDateTime, TestAsOfDateTime, TestAsOfDateTime, TestAsOfDateTime, TestAsOfDateTime }; // Can't try other scenarios with AsOfDate because it doesn't care of the inputs are null or indirect RunAndCompare(XArray.All(values), "RowNumber", XArray.All(expected), "Result", "set [Result] AsOfDate()"); }
public void Function_IsNull() { int[] values = new int[] { 1, 2, 0, 3, 4 }; bool[] nulls = new bool[] { false, false, true, false, false }; XArray input = XArray.All(values, values.Length, nulls); XArray expected = XArray.All(nulls, nulls.Length); RunQueryAndVerify(input, "Name", expected, "Name", "set [Name] IsNull([Name])"); }
public void Append(XArray xarray) { // Write the values (without the null markers; we're writing those here) _valueWriter.Append(xarray.WithoutNulls()); // Track the row count written so we know how many null=false values to write when we first see a null _rowCountWritten += xarray.Count; // If there are no nulls in this set and none previously, no null markers need to be written if (!xarray.HasNulls && _nullWriter == null) { return; } if (_nullWriter == null) { // Check whether any rows in the set are actually null; the source may contain nulls but the filtered rows might not bool areAnyNulls = false; for (int i = 0; i < xarray.Count && !areAnyNulls; ++i) { areAnyNulls |= xarray.NullRows[xarray.Index(i)]; } // If there are not actually any null rows in this set, don't write null output yet if (!areAnyNulls) { return; } // Open a new file to write IsNull booleans string nullsPath = Path.Combine(_columnPath, "Vn.b8.bin"); _nullWriter = new PrimitiveArrayWriter <bool>(_streamProvider.OpenWrite(nullsPath)); // Write false for every value so far int previousCount = _rowCountWritten - xarray.Count; Allocator.AllocateToSize(ref _falseArray, 1024); for (int i = 0; i < previousCount; i += 1024) { int rowCount = Math.Min(1024, previousCount - i); _nullWriter.Append(XArray.All(_falseArray, rowCount)); } } if (!xarray.HasNulls) { // If this xarray doesn't have any nulls, write false for every value in this page Allocator.AllocateToSize(ref _falseArray, xarray.Count); _nullWriter.Append(XArray.All(_falseArray, xarray.Count)); } else { // Write the actual true/false values for this page _nullWriter.Append(XArray.All(xarray.NullRows).Reselect(xarray.Selector)); } }
private void PostSortAndFilter(XArray groups, XArray counts, int totalRowCount, bool wasAllRows) { int[] finalIndices = new int[groups.Count]; int[] finalCounts = new int[groups.Count]; int groupCount = 0; // Filter to counts over the minimum percentage threshold int[] countsArray = (int[])counts.Array; if (countsArray != null) { int threshold = (int)(totalRowCount * MinimumPercentageToReport); for (int i = 0; i < groups.Count; ++i) { int count = countsArray[counts.Index(i)]; if (count >= threshold) { finalIndices[groupCount] = i; finalCounts[groupCount] = count; groupCount++; } } } // Sort the values by count descending Array.Sort <int, int>(finalCounts, finalIndices, 0, groupCount, new ReverseComparer()); // Limit to the top N if needed if (groupCount > MaximumCountToReturn) { groupCount = MaximumCountToReturn; } // Set the distinct count (now that it's known) _distinctCount = groupCount; // Set the output values int[] groupsRemap = null; XArray finalCountsX = XArray.All(finalCounts, groupCount); _columns[0].SetValues(groups.Select(ArraySelector.Map(finalIndices, groupCount), ref groupsRemap)); _columns[1].SetValues(finalCountsX); if (wasAllRows) { _columns[2].SetValues(PercentageAggregator.ToPercentageStrings(finalCountsX, totalRowCount, PercentageAggregator.TwoSigFigs)); } else { _columns[2].SetValues(PercentageAggregator.ToPercentageStrings(finalCountsX, totalRowCount, PercentageAggregator.WholePercentage)); } }
public XArray Concatenate(IList <XArray> columns) { _block.Clear(); int count = columns.First().Count; Allocator.AllocateToSize(ref _buffer, count); Allocator.AllocateToSize(ref _isNull, count); bool couldBeNulls = columns.Any((col) => col.HasNulls); bool areAnyNulls = false; String8[][] arrays = columns.Select((xarray) => (String8[])xarray.Array).ToArray(); if (!couldBeNulls) { for (int i = 0; i < count; ++i) { String8 result = String8.Empty; for (int columnIndex = 0; columnIndex < columns.Count; ++columnIndex) { int rowIndex = columns[columnIndex].Index(i); result = _block.Concatenate(result, String8.Empty, arrays[columnIndex][rowIndex]); } _buffer[i] = result; } } else { for (int i = 0; i < count; ++i) { String8 result = String8.Empty; bool isNull = false; for (int columnIndex = 0; columnIndex < columns.Count; ++columnIndex) { int rowIndex = columns[columnIndex].Index(i); isNull |= columns[columnIndex].HasNulls && columns[columnIndex].NullRows[rowIndex]; result = _block.Concatenate(result, String8.Empty, arrays[columnIndex][rowIndex]); } _buffer[i] = result; _isNull[i] = isNull; areAnyNulls |= isNull; } } return(XArray.All(_buffer, count, (areAnyNulls ? _isNull : null))); }
public XArray Read(ArraySelector selector) { if (selector.Indices != null) { throw new NotImplementedException(); } Allocator.AllocateToSize(ref _array, selector.Count); _stream.Seek(selector.StartIndexInclusive, SeekOrigin.Begin); _stream.Read(_array, 0, selector.Count); return(XArray.All(_array, selector.Count)); }
public void Append(XArray xarray) { Allocator.AllocateToSize(ref _positionsBuffer, xarray.Count); String8[] array = (String8[])xarray.Array; for (int i = 0; i < xarray.Count; ++i) { String8 value = array[xarray.Index(i)]; value.WriteTo(_bytesWriter); _position += value.Length; _positionsBuffer[i] = _position; } _positionsWriter.Append(XArray.All(_positionsBuffer, xarray.Count)); }
public static XArray ToPercentageStrings(XArray counts, int total, Func <int, int, string> formatter) { int[] countArray = (int[])counts.Array; String8Block block = new String8Block(); String8[] percentages = new String8[counts.Count]; for (int i = 0; i < counts.Count; ++i) { // Convert to a percentage, string, and then String8 percentages[i] = block.GetCopy(formatter(countArray[counts.Index(i)], total)); } return(XArray.All(percentages, counts.Count)); }
public static Func <XArray, XArray> NegatedTryConvertToConverter(NegatedTryConvert negatedTryConvert, string errorContextMessage, ValueKinds errorOn = ValueKindsDefaults.ErrorOn, ValueKinds changeToDefault = ValueKindsDefaults.ChangeToDefault) { if (negatedTryConvert == null) { return(null); } Array result; bool[] couldNotConvert; bool[] buffer = null; if (changeToDefault == ValueKinds.None) { // Invalid/Null/Empty -> Null, so couldNotConvert becomes IsNull return((values) => { couldNotConvert = negatedTryConvert(values, out result); ErrorWhenSpecified(errorOn, values, couldNotConvert, errorContextMessage); return XArray.All(result, values.Count, MergeNulls(values, couldNotConvert, ref buffer), values.Selector.IsSingleValue); }); } else if (changeToDefault == ValueKinds.Invalid) { // Invalid -> Default, so keep nulls from source return((values) => { couldNotConvert = negatedTryConvert(values, out result); ErrorWhenSpecified(errorOn, values, couldNotConvert, errorContextMessage); return XArray.All(result, values.Count, XArray.RemapNulls(values, ref couldNotConvert), values.Selector.IsSingleValue); }); } else if (changeToDefault == ValueKinds.InvalidOrNull) { // Invalid/Null/Empty -> Default, so negate all nulls return((values) => { couldNotConvert = negatedTryConvert(values, out result); ErrorWhenSpecified(errorOn, values, couldNotConvert, errorContextMessage); return XArray.All(result, values.Count, null, values.Selector.IsSingleValue); }); } else { throw new NotImplementedException(changeToDefault.ToString()); } }
// Return an XArray with nulls inserted for every other value public static XArray Nulls(XArray values) { Array modifiedArray = null; Allocator.AllocateToSize(ref modifiedArray, values.Array.Length * 2, values.Array.GetType().GetElementType()); bool[] nulls = new bool[modifiedArray.Length]; // Every other value is null for (int i = 0; i < modifiedArray.Length; ++i) { nulls[i] = (i % 2 == 0); modifiedArray.SetValue(values.Array.GetValue(values.Index(i / 2)), i); } // Return an XArray with the doubled length and alternating nulls return(XArray.All(modifiedArray, modifiedArray.Length, nulls)); }
public XArray Read(ArraySelector selector) { if (selector.Indices != null) { return(ReadIndices(selector)); } if (selector.Count == 0) { return(XArray.All(_resultArray, 0)); } // Return previous xarray if re-requested if (selector.Equals(_currentSelector)) { return(_currentArray); } Allocator.AllocateToSize(ref _resultArray, selector.Count); bool includesFirstString = (selector.StartIndexInclusive == 0); // Read the string positions and bytes ReadRaw(selector); // Update the String8 array to point to them byte[] textArray = (byte[])_currentRaw.Bytes.Array; int[] positionArray = (int[])_currentRaw.Positions.Array; int firstStringStart = (includesFirstString ? 0 : positionArray[_currentRaw.Positions.Index(0)]); int positionOffset = _currentRaw.Positions.Index((includesFirstString ? 0 : 1)); int textOffset = firstStringStart - _currentRaw.Bytes.Index(0); int previousStringEnd = firstStringStart - textOffset; for (int i = 0; i < selector.Count; ++i) { int valueEnd = positionArray[i + positionOffset] - textOffset; _resultArray[i] = new String8(textArray, previousStringEnd, valueEnd - previousStringEnd); previousStringEnd = valueEnd; } // Cache the xarray and return it _currentArray = XArray.All(_resultArray, selector.Count); _currentSelector = selector; return(_currentArray); }
public XArray Read(ArraySelector selector) { // Return the cached xarray if re-requested if (selector.Equals(_currentSelector)) { return(_currentArray); } // Read the values themselves XArray values = _valueReader.Read(selector); // Read the null markers XArray nulls = _nullReader.Read(selector); // Cache and return the values and null markers together _currentArray = XArray.All(values.Array, -1, (bool[])nulls.Array).Reselect(values.Selector); _currentSelector = selector; return(_currentArray); }
private static void RunJoinAndVerify(Array joinTo, Array joinFrom, Array expected) { Type t = joinTo.GetType().GetElementType(); // Build a table with padded nulls to join from (so we see nulls are also filtered out) XArray joinFromxarray = TableTestHarness.Nulls(XArray.All(joinFrom)); IXTable joinFromTable = TableTestHarness.DatabaseContext.FromArrays(joinFromxarray.Count) .WithColumn(new ColumnDetails("ServerID", t), joinFromxarray); // Build the table to join to IXTable joinToTable = TableTestHarness.DatabaseContext.FromArrays(joinTo.Length) .WithColumn(new ColumnDetails("ID", t), XArray.All(joinTo)); // Run the join - verify the expected values without padding are found IXTable result = new Join(joinFromTable, "ServerID", joinToTable, "ID", "Server."); Func <XArray> serverID = result.Columns.Find("Server.ID").CurrentGetter(); IXTable expectedTable = TableTestHarness.DatabaseContext.FromArrays(expected.Length).WithColumn("Server.ID", expected); TableTestHarness.AssertAreEqual(expectedTable, result, 2); }
public XArray[] DistinctKeys() { // Build a map from each assigned index to the hash bucket containing it int[] indicesInOrder = new int[Count]; byte[] metadata = this.Metadata; for (int i = 0; i < metadata.Length; ++i) { if (metadata[i] != 0) { indicesInOrder[_assignedIndices[i]] = i; } } // Get the array for each key and reselect into assigned order XArray[] keyArrays = new XArray[_keys.Length]; for (int i = 0; i < _keys.Length; ++i) { keyArrays[i] = XArray.All(_keys[i].Values).Reselect(ArraySelector.Map(indicesInOrder, Count)); } return(keyArrays); }