1 using System.Collections.Generic;
4 namespace kinetica.Utils
11 internal sealed
class RecordKeyBuilder<T>
16 private enum ColumnType
44 private KineticaType ktype;
45 private IList<int> routing_column_indices;
46 private IList<ColumnType> column_types;
47 private int buffer_size;
49 public RecordKeyBuilder(
bool is_primary_key, KineticaType ktype)
54 routing_column_indices =
new List<int>();
55 column_types =
new List<ColumnType>();
60 bool has_timestamp =
false;
63 int track_id_column_idx = -1;
67 IList<KineticaType.Column> columns = ktype.getColumns();
68 for (
int i = 0; i < columns.Count; ++i)
71 KineticaType.Column column = columns[i];
74 switch (column.getName())
77 track_id_column_idx = i;
97 routing_column_indices.Add(i);
101 routing_column_indices.Add(i);
107 && has_timestamp && has_x && has_y && (track_id_column_idx != -1))
109 if (routing_column_indices.Count == 0)
111 routing_column_indices.Add(track_id_column_idx);
113 else if ((routing_column_indices.Count != 1)
114 || (routing_column_indices[0] != track_id_column_idx))
117 throw new KineticaException(
"Cannot have a shard key other than 'TRACKID' for track tables.");
124 foreach (
int i
in routing_column_indices)
127 KineticaType.Column column = columns[i];
129 switch (column.getType())
132 case KineticaType.Column.ColumnType.FLOAT:
134 column_types.Add(ColumnType.FLOAT);
135 this.buffer_size += 4;
138 case KineticaType.Column.ColumnType.DOUBLE:
140 column_types.Add(ColumnType.DOUBLE);
141 this.buffer_size += 8;
145 case KineticaType.Column.ColumnType.INT:
150 column_types.Add(ColumnType.INT8);
151 this.buffer_size += 1;
155 column_types.Add(ColumnType.INT16);
156 this.buffer_size += 2;
160 column_types.Add(ColumnType.INT);
161 this.buffer_size += 4;
166 case KineticaType.Column.ColumnType.LONG:
171 column_types.Add(ColumnType.TIMESTAMP);
175 column_types.Add(ColumnType.LONG);
177 this.buffer_size += 8;
181 case KineticaType.Column.ColumnType.STRING:
185 column_types.Add(ColumnType.CHAR1);
186 this.buffer_size += 1;
190 column_types.Add(ColumnType.CHAR2);
191 this.buffer_size += 2;
195 column_types.Add(ColumnType.CHAR4);
196 this.buffer_size += 4;
200 column_types.Add(ColumnType.CHAR8);
201 this.buffer_size += 8;
205 column_types.Add(ColumnType.CHAR16);
206 this.buffer_size += 16;
210 column_types.Add(ColumnType.CHAR32);
211 this.buffer_size += 32;
215 column_types.Add(ColumnType.CHAR64);
216 this.buffer_size += 64;
220 column_types.Add(ColumnType.CHAR128);
221 this.buffer_size += 128;
225 column_types.Add(ColumnType.CHAR256);
226 this.buffer_size += 256;
230 column_types.Add(ColumnType.DATE);
231 this.buffer_size += 4;
235 column_types.Add(ColumnType.DATETIME);
236 this.buffer_size += 8;
240 column_types.Add(ColumnType.DECIMAL);
241 this.buffer_size += 8;
245 column_types.Add(ColumnType.IPV4);
246 this.buffer_size += 4;
250 column_types.Add(ColumnType.TIME);
251 this.buffer_size += 4;
255 column_types.Add(ColumnType.STRING);
256 this.buffer_size += 8;
262 case KineticaType.Column.ColumnType.BYTES:
263 case KineticaType.Column.ColumnType.DEFAULT:
264 throw new KineticaException($
"Cannot use column '{column.getName()}' as a key.");
277 public RecordKey build(T record)
280 if (this.buffer_size == 0)
284 RecordKey key =
new RecordKey(this.buffer_size);
287 for (
int i = 0; i < this.routing_column_indices.Count; ++i)
290 KineticaType.Column column = this.ktype.getColumns()[this.routing_column_indices[i]];
293 var value = record.GetType().GetProperty(column.getName()).GetValue(record, null);
295 switch (this.column_types[i])
297 case ColumnType.CHAR1:
298 key.addCharN((string)value, 1);
301 case ColumnType.CHAR2:
302 key.addCharN((string)value, 2);
305 case ColumnType.CHAR4:
306 key.addCharN((string)value, 4);
309 case ColumnType.CHAR8:
310 key.addCharN((string)value, 8);
313 case ColumnType.CHAR16:
314 key.addCharN((string)value, 16);
317 case ColumnType.CHAR32:
318 key.addCharN((string)value, 32);
321 case ColumnType.CHAR64:
322 key.addCharN((string)value, 64);
325 case ColumnType.CHAR128:
326 key.addCharN((string)value, 128);
329 case ColumnType.CHAR256:
330 key.addCharN((string)value, 256);
333 case ColumnType.DATE:
334 key.addDate((string)value);
337 case ColumnType.DATETIME:
338 key.addDateTime((string)value);
341 case ColumnType.DECIMAL:
342 key.addDecimal((string)value);
345 case ColumnType.DOUBLE:
346 key.addDouble((
double?)value);
349 case ColumnType.FLOAT:
350 key.addFloat((
float?)value);
354 key.addInt((
int?)value);
357 case ColumnType.INT8:
358 key.addInt8((
int?)value);
361 case ColumnType.INT16:
362 key.addInt16((
int?)value);
365 case ColumnType.IPV4:
366 key.addIPv4((string)value);
369 case ColumnType.LONG:
370 key.addLong((
long?)value);
373 case ColumnType.STRING:
374 key.addString((string)value);
377 case ColumnType.TIME:
378 key.addTime((string)value);
381 case ColumnType.TIMESTAMP:
382 key.addTimeStamp((
long?)value);
403 public string buildExpression(T record)
406 if (this.buffer_size == 0)
410 System.Text.StringBuilder expression =
new System.Text.StringBuilder(
"(" );
413 for (
int i = 0; i < this.routing_column_indices.Count; ++i)
416 expression.Append(
" and " );
419 KineticaType.Column column = this.ktype.getColumns()[this.routing_column_indices[i]];
420 string column_name = column.getName();
423 var value = record.GetType().GetProperty( column_name ).GetValue( record, null );
428 expression.Append(
"is_null(" );
429 expression.Append( column_name );
430 expression.Append(
")" );
435 expression.Append(
"(" );
436 expression.Append( column_name );
437 expression.Append(
" = " );
440 switch ( this.column_types[i] )
443 case ColumnType.CHAR1:
444 case ColumnType.CHAR2:
445 case ColumnType.CHAR4:
446 case ColumnType.CHAR8:
447 case ColumnType.CHAR16:
448 case ColumnType.CHAR32:
449 case ColumnType.CHAR64:
450 case ColumnType.CHAR128:
451 case ColumnType.CHAR256:
452 case ColumnType.DATE:
453 case ColumnType.DATETIME:
454 case ColumnType.DECIMAL:
455 case ColumnType.IPV4:
456 case ColumnType.STRING:
457 case ColumnType.TIME:
458 expression.Append(
"\"" );
459 expression.Append( value );
460 expression.Append(
"\"" );
463 case ColumnType.DOUBLE:
464 case ColumnType.FLOAT:
466 case ColumnType.INT8:
467 case ColumnType.INT16:
468 case ColumnType.LONG:
469 expression.Append( value );
474 expression.Append(
")" );
478 expression.Append(
")" );
480 return expression.ToString();
493 return !(this.routing_column_indices.Count == 0);
502 public bool hasSameKey(RecordKeyBuilder<T> other)
504 return this.column_types.Equals(other.column_types);
const string CHAR1
This property provides optimized memory, disk and query performance for string columns.
const string DATETIME
Valid only for 'string' columns.
const string INT16
This property provides optimized memory and query performance for int columns.
const string PRIMARY_KEY
This property indicates that this column will be part of (or the entire) primary key.
const string CHAR128
This property provides optimized memory, disk and query performance for string columns.
const string TIMESTAMP
Valid only for 'long' columns.
const string CHAR16
This property provides optimized memory, disk and query performance for string columns.
const string CHAR64
This property provides optimized memory, disk and query performance for string columns.
const string CHAR4
This property provides optimized memory, disk and query performance for string columns.
const string CHAR2
This property provides optimized memory, disk and query performance for string columns.
const string DATE
Valid only for 'string' columns.
const string CHAR8
This property provides optimized memory, disk and query performance for string columns.
const string DECIMAL
Valid only for 'string' columns.
const string CHAR32
This property provides optimized memory, disk and query performance for string columns.
const string IPV4
This property provides optimized memory, disk and query performance for string columns representing I...
const string CHAR256
This property provides optimized memory, disk and query performance for string columns.
const string SHARD_KEY
This property indicates that this column will be part of (or the entire) shard key.
const string INT8
This property provides optimized memory and query performance for int columns.
const string TIME
Valid only for 'string' columns.