Files
spark/src/DataStreamSuite/DataStream/Primitives/Project/ProjectHelper.cs
T

101 lines
3.7 KiB
C#

using Bts.ColumnMapExpressions;
using Spark.Core.Diagnostics;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace BCG
{
/// <summary>
/// Provides the place holder for the int array that maps aliased column indices to the original
/// ones (and the algorithms to compute them)
/// </summary>
internal class ProjectHelper
{
internal int[] colMap;
internal IBlueTableSchema schema;
internal string[] relevantOrigCols;
/// <summary>
/// </summary>
/// <param name="isch">original(unprojected) schema</param>
/// <param name="exp">expression defining the mapping</param>
/// <param name="tableName">table name of the new schema</param>
internal ProjectHelper (IBlueTableSchema isch, string exp, string? tableName)
: this (isch, myGetDictionary (isch, exp), tableName)
{}
/// <summary>
/// </summary>
/// <param name="isch">original (unprojected) schema</param>
/// <param name="origToAlias">dictionary mapping unprojected names to their projected names, dropped cols should not be there</param>
/// <param name="tableName">table name of the new schema</param>
internal ProjectHelper (
IBlueTableSchema isch, IDictionary<string, string> origToAlias, string? tableName)
{
ArrayList colMapAl = new ArrayList (),
colInfoAl = new ArrayList ();
relevantOrigCols = new string[origToAlias.Count-1];
int c = 0;
ArrayList iColNames = new ArrayList (isch.columnNames);
iColNames.Sort ();
foreach (string colName in iColNames)
{
if (origToAlias.TryGetValue(colName, out var colAlias))
{
ColumnInfo ci = isch[colName];
colInfoAl.Add (new ColumnInfo (colAlias,
colInfoAl.Count,
ci.colType)
);
colMapAl.Add (ci.colNo);
if (ci.colName != "id")
relevantOrigCols[c++] = ci.colName;
}
}
schema = new BlueTableSchema (tableName == null ? isch.tableName : tableName,
colInfoAl.ToArray (typeof(ColumnInfo)) as ColumnInfo[]);
colMap = (int[])colMapAl.ToArray(typeof(int));
}
/// <summary>
/// Gets an IDictionary mapping the original names to their aliased names. (The columns
/// dropped do not appear in the returned value)
/// </summary>
/// <param name="isch"></param>
/// <param name="exp"></param>
/// <returns></returns>
private static IDictionary<string, string> myGetDictionary (IBlueTableSchema isch, string exp)
{
IDictionary<string, string> origToAlias = new Dictionary<string, string>();
var e = ColumnMapExpression.Parse(exp)
?? throw new ArgumentException("Failed to parse ColumnMapExpression", nameof(exp));
if (e.IsInclusive) {
origToAlias = e.Columns.ToDictionary();
origToAlias["id"] = "id";
} else {
origToAlias = isch.columnInfo.ToDictionary(
ci => ci.colName, ci => e.Columns.GetValueOrDefault(ci.colName) ?? ci.colName);
}
return origToAlias;
}
/// <summary>
/// Returns a new dictionary with the keys and values interchanging positions
/// </summary>
/// <param name="dic"></param>
/// <returns></returns>
internal static IDictionary invertDic (IDictionary dic)
{
IDictionary retVal = new Hashtable (dic.Count);
foreach (DictionaryEntry de in dic)
retVal.Add(ExceptionAssert.NotNull(de.Value), de.Key);
return retVal;
}
}
}