@@ -1175,9 +1175,6 @@ class CCPPDSUtils {
1175
1175
}
1176
1176
1177
1177
std::string get_dict_type (ASR::Dict_t* dict_type) {
1178
- if (!ASR::is_a<ASR::Integer_t>(*dict_type->m_key_type )) {
1179
- throw CodeGenError (" Only Integer keys supported for now in C-dictionary" );
1180
- }
1181
1178
std::string dict_type_code = ASRUtils::get_type_code ((ASR::ttype_t *)dict_type, true );
1182
1179
if (typecodeToDStype.find (dict_type_code) != typecodeToDStype.end ()) {
1183
1180
return typecodeToDStype[dict_type_code];
@@ -1196,14 +1193,27 @@ class CCPPDSUtils {
1196
1193
tmp_gen += indent + tab + " bool *present;\n " ;
1197
1194
tmp_gen += indent + " };\n\n " ;
1198
1195
func_decls += tmp_gen;
1199
- dict_init (dict_type, dict_struct_type, dict_type_code);
1200
- dict_resize (dict_type, dict_struct_type, dict_type_code);
1201
- dict_insert (dict_type, dict_struct_type, dict_type_code);
1202
- dict_get_item (dict_type, dict_struct_type, dict_type_code);
1203
- dict_get_item_with_fallback (dict_type, dict_struct_type, dict_type_code);
1204
- dict_len (dict_type, dict_struct_type, dict_type_code);
1205
- dict_pop (dict_type, dict_struct_type, dict_type_code);
1206
- dict_deepcopy (dict_type, dict_struct_type, dict_type_code);
1196
+ generate_compare_funcs (dict_type->m_key_type );
1197
+ generate_compare_funcs (dict_type->m_value_type );
1198
+ if (ASR::is_a<ASR::Integer_t>(*dict_type->m_key_type )) {
1199
+ dict_init (dict_type, dict_struct_type, dict_type_code);
1200
+ dict_resize_probing (dict_type, dict_struct_type, dict_type_code);
1201
+ dict_insert_probing (dict_type, dict_struct_type, dict_type_code);
1202
+ dict_get_item_probing (dict_type, dict_struct_type, dict_type_code);
1203
+ dict_get_item_with_fallback_probing (dict_type, dict_struct_type, dict_type_code);
1204
+ dict_len (dict_type, dict_struct_type, dict_type_code);
1205
+ dict_pop_probing (dict_type, dict_struct_type, dict_type_code);
1206
+ dict_deepcopy (dict_type, dict_struct_type, dict_type_code);
1207
+ } else {
1208
+ dict_init (dict_type, dict_struct_type, dict_type_code);
1209
+ dict_resize_naive (dict_type, dict_struct_type, dict_type_code);
1210
+ dict_insert_naive (dict_type, dict_struct_type, dict_type_code);
1211
+ dict_get_item_naive (dict_type, dict_struct_type, dict_type_code);
1212
+ dict_get_item_with_fallback_naive (dict_type, dict_struct_type, dict_type_code);
1213
+ dict_len (dict_type, dict_struct_type, dict_type_code);
1214
+ dict_pop_naive (dict_type, dict_struct_type, dict_type_code);
1215
+ dict_deepcopy (dict_type, dict_struct_type, dict_type_code);
1216
+ }
1207
1217
return dict_struct_type;
1208
1218
}
1209
1219
@@ -1231,7 +1241,7 @@ class CCPPDSUtils {
1231
1241
generated_code += indent + " }\n\n " ;
1232
1242
}
1233
1243
1234
- void dict_resize (ASR::Dict_t *dict_type, std::string dict_struct_type,
1244
+ void dict_resize_probing (ASR::Dict_t *dict_type, std::string dict_struct_type,
1235
1245
std::string dict_type_code) {
1236
1246
std::string indent (indentation_level * indentation_spaces, ' ' );
1237
1247
std::string tab (indentation_spaces, ' ' );
@@ -1268,6 +1278,7 @@ class CCPPDSUtils {
1268
1278
generated_code += indent + tab + " for(size_t i=0; i<x->capacity/2; i++) {\n " ;
1269
1279
generated_code += indent + tab + tab + " if(tmp_p[i]) {\n " ;
1270
1280
generated_code += indent + tab + tab + tab + " int j=tmp_key[i]\%x->capacity;\n " ;
1281
+ generated_code += indent + tab + tab + tab + " j=(j+x->capacity)\%x->capacity;\n " ;
1271
1282
generated_code += indent + tab + tab + tab + " while(x->present[j]) j=(j+1)\%x->capacity;\n " ;
1272
1283
generated_code += indent + tab + tab + tab + \
1273
1284
" x->key[j] = tmp_key[i]; x->value[j] = tmp_val[i]; x->present[j] = true;\n " ;
@@ -1276,7 +1287,29 @@ class CCPPDSUtils {
1276
1287
generated_code += indent + " }\n\n " ;
1277
1288
}
1278
1289
1279
- void dict_insert (ASR::Dict_t *dict_type, std::string dict_struct_type,
1290
+ void dict_resize_naive (ASR::Dict_t *dict_type, std::string dict_struct_type,
1291
+ std::string dict_type_code) {
1292
+ std::string indent (indentation_level * indentation_spaces, ' ' );
1293
+ std::string tab (indentation_spaces, ' ' );
1294
+ std::string dict_rez_func = global_scope->get_unique_name (" dict_resize_" + dict_type_code);
1295
+ typecodeToDSfuncs[dict_type_code][" dict_resize" ] = dict_rez_func;
1296
+ std::string signature = " void " + dict_rez_func + " (" + dict_struct_type + " * x)" ;
1297
+ func_decls += indent + " inline " + signature + " ;\n " ;
1298
+ signature = indent + signature;
1299
+ std::string key = CUtils::get_c_type_from_ttype_t (dict_type->m_key_type );
1300
+ std::string val = CUtils::get_c_type_from_ttype_t (dict_type->m_value_type );
1301
+ generated_code += indent + signature + " {\n " ;
1302
+ generated_code += indent + tab + " x->capacity = 2*x->capacity + 1;\n " ;
1303
+ generated_code += indent + tab + " x->key = (" + key + " *) " +
1304
+ " realloc(x->key, x->capacity * sizeof(" + key + " ));\n " ;
1305
+ generated_code += indent + tab + " x->value = (" + val + " *) " +
1306
+ " realloc(x->value, x->capacity * sizeof(" + val + " ));\n " ;
1307
+ generated_code += indent + tab + " x->present = (bool*) " +
1308
+ " realloc(x->present, x->capacity * sizeof(bool));\n " ;
1309
+ generated_code += indent + " }\n\n " ;
1310
+ }
1311
+
1312
+ void dict_insert_probing (ASR::Dict_t *dict_type, std::string dict_struct_type,
1280
1313
std::string dict_type_code) {
1281
1314
std::string indent (indentation_level * indentation_spaces, ' ' );
1282
1315
std::string tab (indentation_spaces, ' ' );
@@ -1291,18 +1324,48 @@ class CCPPDSUtils {
1291
1324
signature = indent + signature;
1292
1325
generated_code += indent + signature + " {\n " ;
1293
1326
generated_code += indent + tab + " int j=k\%x->capacity; int c = 0;\n " ;
1327
+ generated_code += indent + tab + " j=(j+x->capacity)\%x->capacity;\n " ;
1294
1328
generated_code += indent + tab + " while(c < x->capacity && x->present[j] && x->key[j]!=k) j=(j+1)\%x->capacity, c++;\n " ;
1295
1329
generated_code += indent + tab + " if (c == x->capacity) {\n " ;
1296
1330
generated_code += indent + tab + tab + dict_rz + " (x);\n " ;
1297
- generated_code += indent + tab + tab + " j=k\%x->capacity;\n " ;
1331
+ generated_code += indent + tab + tab + " j=k\%x->capacity; j=(j+x->capacity)\%x->capacity; \n " ;
1298
1332
generated_code += indent + tab + tab + " while(x->present[j]) j=(j+1)\%x->capacity;\n " ;
1299
1333
generated_code += indent + tab + " }\n " ;
1300
1334
generated_code += indent + tab + \
1301
1335
" x->key[j] = k; x->value[j] = v; x->present[j] = true;\n " ;
1302
1336
generated_code += indent + " }\n\n " ;
1303
1337
}
1304
1338
1305
- void dict_get_item (ASR::Dict_t *dict_type, std::string dict_struct_type,
1339
+ void dict_insert_naive (ASR::Dict_t *dict_type, std::string dict_struct_type,
1340
+ std::string dict_type_code) {
1341
+ std::string indent (indentation_level * indentation_spaces, ' ' );
1342
+ std::string tab (indentation_spaces, ' ' );
1343
+ std::string dict_in_func = global_scope->get_unique_name (" dict_insert_" + dict_type_code);
1344
+ typecodeToDSfuncs[dict_type_code][" dict_insert" ] = dict_in_func;
1345
+ std::string dict_rz = typecodeToDSfuncs[dict_type_code][" dict_resize" ];
1346
+ std::string key = CUtils::get_c_type_from_ttype_t (dict_type->m_key_type );
1347
+ std::string val = CUtils::get_c_type_from_ttype_t (dict_type->m_value_type );
1348
+ std::string signature = " void " + dict_in_func + " (" + dict_struct_type + " * x, " +\
1349
+ key + " k," + val + " v)" ;
1350
+ func_decls += indent + " inline " + signature + " ;\n " ;
1351
+ signature = indent + signature;
1352
+ generated_code += indent + signature + " {\n " ;
1353
+ std::string key_cmp_func = get_compare_func (dict_type->m_key_type );
1354
+ std::string key_cmp = key_cmp_func + " (x->key[c], k)" ;
1355
+ generated_code += indent + tab + " int c = 0;\n " ;
1356
+ generated_code += indent + tab + " while(c < x->capacity && x->present[c] && !" + key_cmp + " ) c++;\n " ;
1357
+ generated_code += indent + tab + " if (c == x->capacity) {\n " ;
1358
+ generated_code += indent + tab + tab + dict_rz + " (x);\n " ;
1359
+ generated_code += indent + tab + " }\n " ;
1360
+ std::string key_deep_copy = get_deepcopy (dict_type->m_key_type , " k" , " x->key[c]" );
1361
+ std::string val_deep_copy = get_deepcopy (dict_type->m_value_type , " v" , " x->value[c]" );
1362
+ generated_code += indent + tab + key_deep_copy + " \n " ;
1363
+ generated_code += indent + tab + val_deep_copy + " \n " ;
1364
+ generated_code += indent + tab + " x->present[c] = true;\n " ;
1365
+ generated_code += indent + " }\n\n " ;
1366
+ }
1367
+
1368
+ void dict_get_item_probing (ASR::Dict_t *dict_type, std::string dict_struct_type,
1306
1369
std::string dict_type_code) {
1307
1370
std::string indent (indentation_level * indentation_spaces, ' ' );
1308
1371
std::string tab (indentation_spaces, ' ' );
@@ -1316,14 +1379,38 @@ class CCPPDSUtils {
1316
1379
signature = indent + signature;
1317
1380
generated_code += indent + signature + " {\n " ;
1318
1381
generated_code += indent + tab + " int j=k\%x->capacity, c = 0;\n " ;
1382
+ generated_code += indent + tab + " j=(j+x->capacity)\%x->capacity;\n " ;
1319
1383
generated_code += indent + tab + " while(c<x->capacity && x->present[j] && !(x->key[j] == k)) j=(j+1)\%x->capacity, c++;\n " ;
1320
1384
generated_code += indent + tab + " if (x->present[j] && x->key[j] == k) return x->value[j];\n " ;
1321
1385
generated_code += indent + tab + " printf(\" Key not found\\ n\" );\n " ;
1322
1386
generated_code += indent + tab + " exit(1);\n " ;
1323
1387
generated_code += indent + " }\n\n " ;
1324
1388
}
1325
1389
1326
- void dict_get_item_with_fallback (ASR::Dict_t *dict_type, std::string dict_struct_type,
1390
+ void dict_get_item_naive (ASR::Dict_t *dict_type, std::string dict_struct_type,
1391
+ std::string dict_type_code) {
1392
+ std::string indent (indentation_level * indentation_spaces, ' ' );
1393
+ std::string tab (indentation_spaces, ' ' );
1394
+ std::string dict_get_func = global_scope->get_unique_name (" dict_get_item_" + dict_type_code);
1395
+ typecodeToDSfuncs[dict_type_code][" dict_get" ] = dict_get_func;
1396
+ std::string key = CUtils::get_c_type_from_ttype_t (dict_type->m_key_type );
1397
+ std::string val = CUtils::get_c_type_from_ttype_t (dict_type->m_value_type );
1398
+ std::string signature = val + " " + dict_get_func + " (" + dict_struct_type + " * x, " +\
1399
+ key + " k)" ;
1400
+ func_decls += indent + " inline " + signature + " ;\n " ;
1401
+ signature = indent + signature;
1402
+ generated_code += indent + signature + " {\n " ;
1403
+ std::string key_cmp_func = get_compare_func (dict_type->m_key_type );
1404
+ std::string key_cmp = key_cmp_func + " (x->key[i], k)" ;
1405
+ generated_code += indent + tab + " for (int i=0; i<x->capacity; i++) {\n " ;
1406
+ generated_code += indent + tab + tab + " if (x->present[i] && " + key_cmp + " ) return x->value[i];\n " ;
1407
+ generated_code += indent + tab + " }\n " ;
1408
+ generated_code += indent + tab + " printf(\" Key not found\\ n\" );\n " ;
1409
+ generated_code += indent + tab + " exit(1);\n " ;
1410
+ generated_code += indent + " }\n\n " ;
1411
+ }
1412
+
1413
+ void dict_get_item_with_fallback_probing (ASR::Dict_t *dict_type, std::string dict_struct_type,
1327
1414
std::string dict_type_code) {
1328
1415
std::string indent (indentation_level * indentation_spaces, ' ' );
1329
1416
std::string tab (indentation_spaces, ' ' );
@@ -1337,12 +1424,35 @@ class CCPPDSUtils {
1337
1424
signature = indent + signature;
1338
1425
generated_code += indent + signature + " {\n " ;
1339
1426
generated_code += indent + tab + " int j=k\%x->capacity, c = 0;\n " ;
1427
+ generated_code += indent + tab + " j=(j+x->capacity)\%x->capacity;\n " ;
1340
1428
generated_code += indent + tab + " while(c<x->capacity && x->present[j] && !(x->key[j] == k)) j=(j+1)\%x->capacity, c++;\n " ;
1341
1429
generated_code += indent + tab + " if (x->present[j] && x->key[j] == k) return x->value[j];\n " ;
1342
1430
generated_code += indent + tab + " return dv;\n " ;
1343
1431
generated_code += indent + " }\n\n " ;
1344
1432
}
1345
1433
1434
+ void dict_get_item_with_fallback_naive (ASR::Dict_t *dict_type, std::string dict_struct_type,
1435
+ std::string dict_type_code) {
1436
+ std::string indent (indentation_level * indentation_spaces, ' ' );
1437
+ std::string tab (indentation_spaces, ' ' );
1438
+ std::string dict_get_func = global_scope->get_unique_name (" dict_get_item_fb_" + dict_type_code);
1439
+ typecodeToDSfuncs[dict_type_code][" dict_get_fb" ] = dict_get_func;
1440
+ std::string key = CUtils::get_c_type_from_ttype_t (dict_type->m_key_type );
1441
+ std::string val = CUtils::get_c_type_from_ttype_t (dict_type->m_value_type );
1442
+ std::string signature = val + " " + dict_get_func + " (" + dict_struct_type + " * x, " +\
1443
+ key + " k, " + val + " dv)" ;
1444
+ func_decls += indent + " inline " + signature + " ;\n " ;
1445
+ signature = indent + signature;
1446
+ generated_code += indent + signature + " {\n " ;
1447
+ std::string key_cmp_func = get_compare_func (dict_type->m_key_type );
1448
+ std::string key_cmp = key_cmp_func + " (x->key[i], k)" ;
1449
+ generated_code += indent + tab + " for (int i=0; i<x->capacity; i++) {\n " ;
1450
+ generated_code += indent + tab + tab + " if (x->present[i] && " + key_cmp + " ) return x->value[i];\n " ;
1451
+ generated_code += indent + tab + " }\n " ;
1452
+ generated_code += indent + tab + " return dv;\n " ;
1453
+ generated_code += indent + " }\n\n " ;
1454
+ }
1455
+
1346
1456
void dict_len (ASR::Dict_t *dict_type, std::string dict_struct_type,
1347
1457
std::string dict_type_code) {
1348
1458
std::string indent (indentation_level * indentation_spaces, ' ' );
@@ -1361,7 +1471,7 @@ class CCPPDSUtils {
1361
1471
generated_code += indent + " }\n\n " ;
1362
1472
}
1363
1473
1364
- void dict_pop (ASR::Dict_t *dict_type, std::string dict_struct_type,
1474
+ void dict_pop_probing (ASR::Dict_t *dict_type, std::string dict_struct_type,
1365
1475
std::string dict_type_code) {
1366
1476
std::string indent (indentation_level * indentation_spaces, ' ' );
1367
1477
std::string tab (indentation_spaces, ' ' );
@@ -1374,6 +1484,7 @@ class CCPPDSUtils {
1374
1484
signature = indent + signature;
1375
1485
generated_code += indent + signature + " {\n " ;
1376
1486
generated_code += indent + tab + " int j = k\%x->capacity;\n " ;
1487
+ generated_code += indent + tab + " j=(j+x->capacity)\%x->capacity;\n " ;
1377
1488
generated_code += indent + tab + " for(int i=0; i < x->capacity; i++) {\n " ;
1378
1489
generated_code += indent + tab + tab + " if (x->present[j] && x->key[j] == k) {\n " ;
1379
1490
generated_code += indent + tab + tab + tab + " x->present[j] = false;\n " ;
@@ -1385,6 +1496,30 @@ class CCPPDSUtils {
1385
1496
generated_code += indent + " }\n\n " ;
1386
1497
}
1387
1498
1499
+ void dict_pop_naive (ASR::Dict_t *dict_type, std::string dict_struct_type,
1500
+ std::string dict_type_code) {
1501
+ std::string indent (indentation_level * indentation_spaces, ' ' );
1502
+ std::string tab (indentation_spaces, ' ' );
1503
+ std::string dict_pop_func = global_scope->get_unique_name (" dict_pop_" + dict_type_code);
1504
+ typecodeToDSfuncs[dict_type_code][" dict_pop" ] = dict_pop_func;
1505
+ std::string key = CUtils::get_c_type_from_ttype_t (dict_type->m_key_type );
1506
+ std::string val = CUtils::get_c_type_from_ttype_t (dict_type->m_value_type );
1507
+ std::string signature = val + " " + dict_pop_func + " (" + dict_struct_type + " * x, " + key + " k)" ;
1508
+ func_decls += indent + " inline " + signature + " ;\n " ;
1509
+ signature = indent + signature;
1510
+ generated_code += indent + signature + " {\n " ;
1511
+ std::string key_cmp_func = get_compare_func (dict_type->m_key_type );
1512
+ std::string key_cmp = key_cmp_func + " (x->key[i], k)" ;
1513
+ generated_code += indent + tab + " for(int i=0; i < x->capacity; i++) {\n " ;
1514
+ generated_code += indent + tab + tab + " if (x->present[i] && " + key_cmp + " ) {\n " ;
1515
+ generated_code += indent + tab + tab + tab + " x->present[i] = false;\n " ;
1516
+ generated_code += indent + tab + tab + tab + " return x->value[i];\n " ;
1517
+ generated_code += indent + tab + tab + " }\n " ;
1518
+ generated_code += indent + tab + " }\n " ;
1519
+ generated_code += indent + tab + " printf(\" Key not found\\ n\" ); exit(1);\n " ;
1520
+ generated_code += indent + " }\n\n " ;
1521
+ }
1522
+
1388
1523
void dict_deepcopy (ASR::Dict_t *dict_type, std::string dict_struct_type,
1389
1524
std::string dict_type_code) {
1390
1525
std::string indent (indentation_level * indentation_spaces, ' ' );
0 commit comments