Files
spark/src/DataStreamSuite/DataStream/Primitives/Join/ParallelJoinTest.cs
T
John Colvin 7d6e4efa4f cleanup: Fix numerous build warnings in DataStreamSuite
Nearly all warnings were due to nullability issues, since the concept of
nullable reference types did not exist when the DataStream code was
originally written.

* Compression related files
  - BZip2InputStream  (disable nullability warnings)
  - BZip2OutputStream (disable nullability warnings)
  - DeflaterHuffman   (disable nullability warnings)
  - Inflater          (disable nullability warnings)
  - InflaterDynHeader (disable nullability warnings)
  - ParallelJoinTest  (disable nullability warnings)
  - TarHeader
  - TarInputStream    (disable nullability warnings)
  - ZipEntry
  - ZipFile
  - ZipInputStream

* AsyncTCPConnection_APM
* AsyncTCPConnection_APM
* InflaterHuffmanTree
* ManagedSubscriber
* ManagedTCPMessageHub
* MapStream
* PubSubClientMessage
  - Normalize indentation/whitespace
  - Fix some typos
  - Address nullability issues to fix build warnings
  - Modernize code
* PubSubMessageReactor
* PubSubServerManagedTCPConnection
* PubSubSingleTagStateEvent
* PubSubState
* PublisherCore
* PubsubDeserializationController
* RemoteMessage
  - make 'message' nullable to resolve warnings elsewhere (in calling code)
* SharedStreamConfig
* SingleTagData
* SubscriberCore
* SuperMapStream
* SystemHeartbeatPublisher
* SystemStatsPublisher
* SystemSubscriptionMapPublisher
* ThreadSafeQueue
* TradeBarsStream

Only use Registry on windows.
2025-12-30 11:38:20 -05:00

370 lines
12 KiB
C#

#nullable disable
using System;
using System.Collections;
using System.Collections.Generic;
namespace BCG
{
/// <summary>
/// This class is used to effect a mapping between values in a join column and entries in three different tables:
/// the left and right tables of a join, as well as the output table (the join table).
/// </summary>
class ParallelJoinTestTablePointer
{
int myLeftTableId = -1;
public int LeftTableId
{
get { return myLeftTableId; }
set { myLeftTableId = value; }
}
int myRightTableId = -1;
public int RightTableId
{
get { return myRightTableId; }
set { myRightTableId = value; }
}
int myJoinTableId = -1;
public int JoinTableId
{
get { return myJoinTableId; }
set { myJoinTableId = value; }
}
public ParallelJoinTestTablePointer(int leftId, int rightId, int joinId)
{
myLeftTableId = leftId;
myRightTableId = rightId;
myJoinTableId = joinId;
}
public ParallelJoinTestTablePointer() : this(-1,-1,-1)
{
}
}
#region IBlueRow implementation for join and leftJoin
public class ParallelJoinTestRow : IBlueRow
{
private JoinProjectHelper myHelper;
private IBlueRow myLeftRow, myRightRow;
int myID;
public ParallelJoinTestRow(int id, IBlueRow leftRow, IBlueRow rightRow, JoinProjectHelper joinProjectHelper)
{
myID = id;
myLeftRow = leftRow;
myRightRow = rightRow;
myHelper = joinProjectHelper;
}
public int leftID { get { return (int)myLeftRow["id"]; } }
public int rightID { get { return (int)myRightRow["id"]; } }
public IBlueRow leftRow { get { return myLeftRow; } }
public IBlueRow rightRow { get { return myRightRow; } }
#region IBlueRow Members
public IBlueTableSchema schema { get { return myHelper.schema; } }
public object this[int index] { get { return this[schema[index].colName]; } }
public object this[string colName]
{
get
{
if (colName == "id")
return myID;
else
{
bool isLeft;
string col = myHelper.getOriginalCol(colName, out isLeft);
return isLeft ? myLeftRow[col] : (myRightRow == null ? (object)DBNull.Value : myRightRow[col]);
}
}
}
#endregion
#region IDictionary Members
public void Add(object key, object value) { { throw new NotSupportedException("IBlueRow is readonly"); } }
public void Clear() { throw new NotSupportedException("IBlueRow is readonly"); }
public bool Contains(object key) { throw new Exception("The method or operation is not implemented."); }
public System.Collections.IDictionaryEnumerator GetEnumerator() { return new BlueRowDictionaryEnumerator(this); }
public bool IsFixedSize { get { return true; } }
public bool IsReadOnly {get { return true; }}
public System.Collections.ICollection Keys { get { return schema.columnNames; } }
public void Remove(object key) { throw new NotSupportedException("IBlueRow is readonly"); }
public System.Collections.ICollection Values
{
get
{
List<object> rv = new List<object> ();
foreach (string col in Keys)
rv.Add(this[col]);
return rv;
}
}
public object this[object key]
{
get { return key is string ? this[key.ToString()] : this[(int)key]; }
set { throw new NotSupportedException("IBlueRow is readonly"); }
}
#endregion
#region ICollection Members
public void CopyTo(Array array, int index) { Values.CopyTo(array, index); }
public int Count { get { return schema.columnNames.Length; } }
public bool IsSynchronized { get { return false; } }
public object SyncRoot { get { return this; } }
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return new BlueRowEnumerator(this); }
#endregion
}
#endregion
/// <summary>
/// This class represents a join on two streams. It works by storing a table with the result of the join.
/// </summary>
public class ParallelJoinTestStream : ViewStream
{
BlueTable myJoinedTable;
BlueTable myLeftTable;
BlueTable myRightTable;
Hashtable myKeyToTablePointerMap;
ViewStream myVLeft, myVRight;
int myIdToUse;
string myLeftKey, myRightKey, myLeftProj, myRightProj;
public ParallelJoinTestStream(ViewStream leftStream, string leftKey, ViewStream rightStream, string rightKey)
: this(leftStream, leftKey, "!", rightStream, rightKey, "!") { }
public ParallelJoinTestStream(ViewStream leftStream, string leftKey, string leftProj, ViewStream rightStream, string rightKey, string rightProj)
{
myVLeft = leftStream;
myVRight = rightStream;
myLeftProj = leftProj;
myRightProj = rightProj;
myLeftKey = leftKey;
myRightKey = rightKey;
myKeyToTablePointerMap = new Hashtable();
myIdToUse = 0;
}
protected override void myOnFirstSubscriber()
{
myVLeft.onChange += new ChangeDelegate(myVLeft_onChange);
myVRight.onChange += new ChangeDelegate(myVRight_onChange);
}
void myVRight_onChange(object newValue)
{
myHandleChange(newValue as DataPacket, false);
}
void myVLeft_onChange(object newValue)
{
myHandleChange(newValue as DataPacket, true);
}
void myHandleChange(DataPacket dp, bool isLeft)
{
int i = 0; // for going throuhg loops and such
BlueTable addedRows = null, droppedRows = null;
if (myJoinedTable == null)
{
if (isLeft && myLeftTable == null)
{
myLeftTable = new BlueTable(dp.addedRows);
//go through the list of added rows and get the id of each row, storing this in the TablePointer map
foreach (IBlueRow row in myLeftTable)
{
if (myKeyToTablePointerMap.ContainsKey(row[myLeftKey]))
{
((ParallelJoinTestTablePointer)myKeyToTablePointerMap[row[myLeftKey]]).LeftTableId = (int)row["id"];
}
else
{
myKeyToTablePointerMap[row[myLeftKey]] = new ParallelJoinTestTablePointer((int)row["id"],-1,-1);
}
}
}
else if (!isLeft && myRightTable == null)
{
myRightTable = new BlueTable(dp.addedRows);
//go through the list of added rows and get the id of each row, storing this in the TablePointer map
foreach (IBlueRow row in myRightTable)
{
if (myKeyToTablePointerMap.ContainsKey(row[myRightKey]))
{
((ParallelJoinTestTablePointer)myKeyToTablePointerMap[row[myRightKey]]).RightTableId = (int)row["id"];
}
else
{
myKeyToTablePointerMap[row[myRightKey]] = new ParallelJoinTestTablePointer(-1,(int)row["id"],-1);
}
}
}
if (myLeftTable != null && myRightTable != null)
{
//construct the schema for the table based upon the schemas of the two tables that are going to be joined together
int numColumns = myLeftTable.schema.columnInfo.Length;
ColumnInfo[] newColumnInfoArray = new ColumnInfo[numColumns * 2 + 1];
for (i = 0; i < numColumns; i++)
{
newColumnInfoArray[i] = new ColumnInfo("L." + myLeftTable.schema.columnNames[i], i, myLeftTable.schema.columnInfo[i].colType);
newColumnInfoArray[numColumns + i] = new ColumnInfo("R." + myRightTable.schema.columnNames[i], i + numColumns, myRightTable.schema.columnInfo[i].colType);
}
newColumnInfoArray[numColumns + i] = new ColumnInfo("id", numColumns + i, (typeof(System.Int64)));
IBlueTableSchema newSchema = new BlueTableSchema("Joined Table", newColumnInfoArray);
myJoinedTable = new BlueTable(newSchema);
addedRows = new BlueTable(newSchema);
droppedRows = new BlueTable(newSchema);
//now that we've created the table, we should have some leftover stuff from the side tables
//that we were storing until now. Add that stuff to the table.
BlueTable rowsToAdd = isLeft ? myRightTable : myLeftTable;
foreach (BlueRow row in rowsToAdd)
{
Object[] newRowObjects = new Object[newSchema.columnInfo.Length];
if (isLeft)
{
for (i = 0; i < numColumns; i++)
{
newRowObjects[i] = row[i];
newRowObjects[numColumns + i] = null;
}
newRowObjects[numColumns + i] = myIdToUse;
//store the fact that the row with this key value went to this id
((ParallelJoinTestTablePointer)myKeyToTablePointerMap[row[myLeftKey]]).JoinTableId = myIdToUse;
myIdToUse++;
}
else
{
for (i = 0; i < numColumns; i++)
{
newRowObjects[i] = null;
newRowObjects[numColumns + i] = row[i];
}
newRowObjects[numColumns + i] = myIdToUse;
//store the fact that the row with this key value went to this id
((ParallelJoinTestTablePointer)myKeyToTablePointerMap[row[myRightKey]]).JoinTableId = myIdToUse;
myIdToUse++;
}
BlueRow newRow = new BlueRow(newSchema, newRowObjects);
addedRows.addRow(newRow);
myJoinedTable.addRow(newRow);
}
}
}
else
{
addedRows = new BlueTable(myJoinedTable.schema);
droppedRows = new BlueTable(myJoinedTable.schema);
}
//setup is complete. At this point, we have to delete all the rows that were deleted, then add in the rows that were added in.
foreach (BlueRow row in dp.addedRows)
{
//check to see if this row has a match in the table already.
//If it does, get rid of that row in the table because it's OUT OF DATE
string joinColumn = isLeft ? myLeftKey : myRightKey;
if (myKeyToTablePointerMap.ContainsKey(row[joinColumn]))
{
//the value is already in the hashtable.
ParallelJoinTestTablePointer tp = (ParallelJoinTestTablePointer) myKeyToTablePointerMap[row[joinColumn]];
int rowOfExistingGuy = tp.JoinTableId;
if (rowOfExistingGuy != -1)
{
//remove this guy from the table
IBlueRow rowToDelete = myJoinedTable[rowOfExistingGuy];
myJoinedTable.deleteRow(rowToDelete);
droppedRows.addRow(rowToDelete);
tp.JoinTableId = -1;
}
}
}
//finally, fire off a packet, but only if you have enough information about the table to do so.
if (myJoinedTable != null)
{
DataPacket outPacket = new DataPacket(myJoinedTable,addedRows, new BlueTable(myJoinedTable.schema));
myFireEvent(outPacket);
}
}
}
}