1 using System.Collections.Generic;
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;
95 if (is_primary_key && column.getProperties().Contains(ColumnProperty.PRIMARY_KEY))
97 routing_column_indices.Add(i);
99 else if (!is_primary_key && column.getProperties().Contains(ColumnProperty.SHARD_KEY))
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:
148 if (column.getProperties().Contains(ColumnProperty.INT8))
150 column_types.Add(ColumnType.INT8);
151 this.buffer_size += 1;
153 else if (column.getProperties().Contains(ColumnProperty.INT16))
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:
169 if (column.getProperties().Contains(ColumnProperty.TIMESTAMP))
171 column_types.Add(ColumnType.TIMESTAMP);
175 column_types.Add(ColumnType.LONG);
177 this.buffer_size += 8;
181 case KineticaType.Column.ColumnType.STRING:
183 if (column.getProperties().Contains(ColumnProperty.CHAR1))
185 column_types.Add(ColumnType.CHAR1);
186 this.buffer_size += 1;
188 else if (column.getProperties().Contains(ColumnProperty.CHAR2))
190 column_types.Add(ColumnType.CHAR2);
191 this.buffer_size += 2;
193 else if (column.getProperties().Contains(ColumnProperty.CHAR4))
195 column_types.Add(ColumnType.CHAR4);
196 this.buffer_size += 4;
198 else if (column.getProperties().Contains(ColumnProperty.CHAR8))
200 column_types.Add(ColumnType.CHAR8);
201 this.buffer_size += 8;
203 else if (column.getProperties().Contains(ColumnProperty.CHAR16))
205 column_types.Add(ColumnType.CHAR16);
206 this.buffer_size += 16;
208 else if (column.getProperties().Contains(ColumnProperty.CHAR32))
210 column_types.Add(ColumnType.CHAR32);
211 this.buffer_size += 32;
213 else if (column.getProperties().Contains(ColumnProperty.CHAR64))
215 column_types.Add(ColumnType.CHAR64);
216 this.buffer_size += 64;
218 else if (column.getProperties().Contains(ColumnProperty.CHAR128))
220 column_types.Add(ColumnType.CHAR128);
221 this.buffer_size += 128;
223 else if (column.getProperties().Contains(ColumnProperty.CHAR256))
225 column_types.Add(ColumnType.CHAR256);
226 this.buffer_size += 256;
228 else if (column.getProperties().Contains(ColumnProperty.DATE))
230 column_types.Add(ColumnType.DATE);
231 this.buffer_size += 4;
233 else if (column.getProperties().Contains(ColumnProperty.DATETIME))
235 column_types.Add(ColumnType.DATETIME);
236 this.buffer_size += 8;
238 else if (column.getProperties().Contains(ColumnProperty.DECIMAL))
240 column_types.Add(ColumnType.DECIMAL);
241 this.buffer_size += 8;
243 else if (column.getProperties().Contains(ColumnProperty.IPV4))
245 column_types.Add(ColumnType.IPV4);
246 this.buffer_size += 4;
248 else if (column.getProperties().Contains(ColumnProperty.TIME))
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);