   using key_type = col0_type;
   using value_type = size_t;
 
-  std::multimap<key_type, value_type> the_map;
+
+  // Array of columns that will be inputs to the gdf_join function
+  std::vector<gdf_column*> left_columns;
+  std::vector<gdf_column*> right_columns;
 
   JoinTest()
   {
+    // Use constant seed so the psuedo-random order is the same each time
+    std::srand(0);
+  }
+
+  // TODO: Support more than 3 columns
+  void create_input(size_t col0_size, size_t col0_range=RAND_MAX,
+                    size_t col1_size=0, size_t col1_range=RAND_MAX,
+                    size_t col2_size=0, size_t col2_range=RAND_MAX)
+  {
+    left_columns.emplace_back(col0_size, col0_range);
+    right_columns.emplace_back(col0_size, col0_range);
+
+    if(col1_size > 0){ 
+      left_columns.emplace_back(col1_size, col1_range);
+      right_columns.emplace_back(col1_size, col1_range);
+    }
+    if(col2_size > 0){ 
+      left_columns.emplace_back(col2_size, col2_range);
+      right_columns.emplace_back(col2_size, col2_range);
+    }
+  }
+
+  void compute_reference_solution()
+  {
+    // Multimap used to compute the reference solution
+    std::multimap<key_type, value_type> the_map;
 
   }
-
+  
 };

  using col2_type = T2;
};

// A new instance of this class will be created for each *TEST(JoinTest, ...)
// Put all repeated setup and validation stuff here
template <class T>
struct JoinTest : public testing::Test
{

protected:

  // Extract the types for the input columns 

#include <iostream>
#include <vector>
#include <map>
#include <type_traits>

#include <thrust/device_vector.h>
#include <thrust/sort.h>
