mesh-rb 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/ext/mesh/extconf.rb +22 -4
  4. data/ext/mesh/mesh.tar.gz +0 -0
  5. data/lib/mesh/version.rb +1 -1
  6. data/mesh.gemspec +3 -2
  7. metadata +4 -120
  8. data/ext/mesh/mesh/.bazelrc +0 -20
  9. data/ext/mesh/mesh/.bazelversion +0 -1
  10. data/ext/mesh/mesh/.clang-format +0 -15
  11. data/ext/mesh/mesh/.dockerignore +0 -5
  12. data/ext/mesh/mesh/.editorconfig +0 -16
  13. data/ext/mesh/mesh/.gitattributes +0 -4
  14. data/ext/mesh/mesh/.github/workflows/main.yml +0 -144
  15. data/ext/mesh/mesh/.gitignore +0 -51
  16. data/ext/mesh/mesh/AUTHORS +0 -5
  17. data/ext/mesh/mesh/CMakeLists.txt +0 -270
  18. data/ext/mesh/mesh/CODE_OF_CONDUCT.md +0 -77
  19. data/ext/mesh/mesh/Dockerfile +0 -30
  20. data/ext/mesh/mesh/LICENSE +0 -201
  21. data/ext/mesh/mesh/Makefile +0 -81
  22. data/ext/mesh/mesh/README.md +0 -97
  23. data/ext/mesh/mesh/WORKSPACE +0 -50
  24. data/ext/mesh/mesh/bazel +0 -350
  25. data/ext/mesh/mesh/mesh-pldi19-powers.pdf +0 -0
  26. data/ext/mesh/mesh/src/BUILD +0 -222
  27. data/ext/mesh/mesh/src/CMakeLists.txt +0 -85
  28. data/ext/mesh/mesh/src/bitmap.h +0 -590
  29. data/ext/mesh/mesh/src/cheap_heap.h +0 -170
  30. data/ext/mesh/mesh/src/common.h +0 -377
  31. data/ext/mesh/mesh/src/copts.bzl +0 -31
  32. data/ext/mesh/mesh/src/d_assert.cc +0 -75
  33. data/ext/mesh/mesh/src/fixed_array.h +0 -124
  34. data/ext/mesh/mesh/src/global_heap.cc +0 -547
  35. data/ext/mesh/mesh/src/global_heap.h +0 -569
  36. data/ext/mesh/mesh/src/gnu_wrapper.cc +0 -75
  37. data/ext/mesh/mesh/src/internal.h +0 -356
  38. data/ext/mesh/mesh/src/libmesh.cc +0 -239
  39. data/ext/mesh/mesh/src/mac_wrapper.cc +0 -528
  40. data/ext/mesh/mesh/src/measure_rss.cc +0 -44
  41. data/ext/mesh/mesh/src/measure_rss.h +0 -20
  42. data/ext/mesh/mesh/src/meshable_arena.cc +0 -776
  43. data/ext/mesh/mesh/src/meshable_arena.h +0 -309
  44. data/ext/mesh/mesh/src/meshing.h +0 -60
  45. data/ext/mesh/mesh/src/mini_heap.h +0 -532
  46. data/ext/mesh/mesh/src/mmap_heap.h +0 -104
  47. data/ext/mesh/mesh/src/one_way_mmap_heap.h +0 -77
  48. data/ext/mesh/mesh/src/partitioned_heap.h +0 -111
  49. data/ext/mesh/mesh/src/plasma/mesh.h +0 -33
  50. data/ext/mesh/mesh/src/real.cc +0 -52
  51. data/ext/mesh/mesh/src/real.h +0 -36
  52. data/ext/mesh/mesh/src/rng/mwc.h +0 -296
  53. data/ext/mesh/mesh/src/rng/mwc64.h +0 -58
  54. data/ext/mesh/mesh/src/rpl_printf.c +0 -1991
  55. data/ext/mesh/mesh/src/runtime.cc +0 -393
  56. data/ext/mesh/mesh/src/runtime.h +0 -114
  57. data/ext/mesh/mesh/src/shuffle_vector.h +0 -287
  58. data/ext/mesh/mesh/src/size_classes.def +0 -251
  59. data/ext/mesh/mesh/src/static/if.h +0 -36
  60. data/ext/mesh/mesh/src/static/log.h +0 -43
  61. data/ext/mesh/mesh/src/testing/benchmark/local_refill.cc +0 -103
  62. data/ext/mesh/mesh/src/testing/big-alloc.c +0 -28
  63. data/ext/mesh/mesh/src/testing/fragmenter.cc +0 -128
  64. data/ext/mesh/mesh/src/testing/global-large-stress.cc +0 -25
  65. data/ext/mesh/mesh/src/testing/local-alloc.c +0 -16
  66. data/ext/mesh/mesh/src/testing/meshing_benchmark.cc +0 -189
  67. data/ext/mesh/mesh/src/testing/thread.cc +0 -35
  68. data/ext/mesh/mesh/src/testing/unit/alignment.cc +0 -56
  69. data/ext/mesh/mesh/src/testing/unit/bitmap_test.cc +0 -274
  70. data/ext/mesh/mesh/src/testing/unit/concurrent_mesh_test.cc +0 -185
  71. data/ext/mesh/mesh/src/testing/unit/mesh_test.cc +0 -143
  72. data/ext/mesh/mesh/src/testing/unit/rng_test.cc +0 -22
  73. data/ext/mesh/mesh/src/testing/unit/size_class_test.cc +0 -66
  74. data/ext/mesh/mesh/src/testing/unit/triple_mesh_test.cc +0 -285
  75. data/ext/mesh/mesh/src/testing/userfaultfd-kernel-copy.cc +0 -164
  76. data/ext/mesh/mesh/src/thread_local_heap.cc +0 -163
  77. data/ext/mesh/mesh/src/thread_local_heap.h +0 -268
  78. data/ext/mesh/mesh/src/wrapper.cc +0 -433
  79. data/ext/mesh/mesh/support/export_mesh.cmake +0 -28
  80. data/ext/mesh/mesh/support/gen-size-classes +0 -57
  81. data/ext/mesh/mesh/support/install_all_configs +0 -33
  82. data/ext/mesh/mesh/support/remove_export_mesh.cmake +0 -48
  83. data/ext/mesh/mesh/support/update-bazelisk +0 -8
  84. data/ext/mesh/mesh/theory/32m80.png +0 -0
  85. data/ext/mesh/mesh/theory/64m80ind.png +0 -0
  86. data/ext/mesh/mesh/theory/bound_comparison.py +0 -67
  87. data/ext/mesh/mesh/theory/bounds/impdeg+1 +0 -135
  88. data/ext/mesh/mesh/theory/choose.py +0 -43
  89. data/ext/mesh/mesh/theory/common.py +0 -42
  90. data/ext/mesh/mesh/theory/compute_exp_Y.py +0 -134
  91. data/ext/mesh/mesh/theory/createRandomString.py +0 -69
  92. data/ext/mesh/mesh/theory/deg_bound_check.py +0 -100
  93. data/ext/mesh/mesh/theory/degcheck.py +0 -47
  94. data/ext/mesh/mesh/theory/dumps/32,1,80,dumb.txt +0 -81
  95. data/ext/mesh/mesh/theory/dumps/32,2,80,dumb.txt +0 -81
  96. data/ext/mesh/mesh/theory/dumps/32,3,80,dumb.txt +0 -81
  97. data/ext/mesh/mesh/theory/dumps/32,4,80,dumb.txt +0 -81
  98. data/ext/mesh/mesh/theory/dumps/32,5,80,dumb.txt +0 -81
  99. data/ext/mesh/mesh/theory/dumps/32,6,80,dumb.txt +0 -81
  100. data/ext/mesh/mesh/theory/dumps/32,7,80,dumb.txt +0 -81
  101. data/ext/mesh/mesh/theory/dumps/32,8,80,dumb.txt +0 -81
  102. data/ext/mesh/mesh/theory/dumps/32,9,80,dumb.txt +0 -81
  103. data/ext/mesh/mesh/theory/experiment.py +0 -303
  104. data/ext/mesh/mesh/theory/experiment_raw_results/.gitignore +0 -0
  105. data/ext/mesh/mesh/theory/greedy_experiment.py +0 -66
  106. data/ext/mesh/mesh/theory/greedy_experiment_copy.py +0 -46
  107. data/ext/mesh/mesh/theory/greedy_experiment_q.py +0 -75
  108. data/ext/mesh/mesh/theory/makeGraph.py +0 -64
  109. data/ext/mesh/mesh/theory/manyreps.png +0 -0
  110. data/ext/mesh/mesh/theory/manystrings.png +0 -0
  111. data/ext/mesh/mesh/theory/match_vs_color_experiment.py +0 -94
  112. data/ext/mesh/mesh/theory/maxmatch_vs_E[Y].py +0 -162
  113. data/ext/mesh/mesh/theory/maxmatch_vs_greedymatch.py +0 -96
  114. data/ext/mesh/mesh/theory/maxvdeg+1imp++32,80.png +0 -0
  115. data/ext/mesh/mesh/theory/mesh_util.py +0 -322
  116. data/ext/mesh/mesh/theory/meshers.py +0 -452
  117. data/ext/mesh/mesh/theory/meshingBenchmark.py +0 -96
  118. data/ext/mesh/mesh/theory/occupancyComparison.py +0 -133
  119. data/ext/mesh/mesh/theory/randmatch_vs_greedymatch.py +0 -97
  120. data/ext/mesh/mesh/theory/randmatch_vs_greedymatch_q.py +0 -103
  121. data/ext/mesh/mesh/theory/randmatch_vs_greedymatch_time.py +0 -117
  122. data/ext/mesh/mesh/theory/read_mesh_dump.py +0 -82
  123. data/ext/mesh/mesh/theory/test.py +0 -70
  124. data/ext/mesh/mesh/tools/bazel +0 -1
@@ -1,36 +0,0 @@
1
- // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2
-
3
- /**
4
- * @file staticif.h
5
- * @brief Statically returns a VALUE based on a conditional.
6
- * @author Emery Berger <http://www.cs.umass.edu/~emery>
7
- * @note Copyright (C) 2005 by Emery Berger, University of Massachusetts Amherst.
8
- */
9
-
10
- #pragma once
11
- #ifndef MESH_STATIC__IF_H
12
- #define MESH_STATIC__IF_H
13
-
14
- template <class TYPE>
15
- TYPE constexpr staticif(bool v, TYPE a, TYPE b) {
16
- return (v ? a : b);
17
- }
18
-
19
- #else
20
-
21
- template <bool b, int a, int c>
22
- class StaticIf;
23
-
24
- template <int a, int b>
25
- class StaticIf<true, a, b> {
26
- public:
27
- enum { VALUE = a };
28
- };
29
-
30
- template <int a, int b>
31
- class StaticIf<false, a, b> {
32
- public:
33
- enum { VALUE = b };
34
- };
35
-
36
- #endif
@@ -1,43 +0,0 @@
1
- // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2
-
3
- /**
4
- * @file staticlog.h
5
- * @brief Statically returns the log (base 2) of a value.
6
- * @author Emery Berger <http://www.cs.umass.edu/~emery>
7
- * @note Copyright (C) 2005 by Emery Berger, University of Massachusetts Amherst.
8
- */
9
-
10
- #pragma once
11
- #ifndef MESH_STATIC__LOG_H
12
- #define MESH_STATIC__LOG_H
13
-
14
- #include "if.h"
15
-
16
- int constexpr staticlog(int v) {
17
- return ((v == 1) ? 0 : (v == 2) ? 1 : (v > 1) ? staticlog(v / 2) + 1 : 0);
18
- }
19
-
20
- #else
21
-
22
- template <int Number>
23
- class StaticLog;
24
-
25
- template <>
26
- class StaticLog<1> {
27
- public:
28
- enum { VALUE = 0 };
29
- };
30
-
31
- template <>
32
- class StaticLog<2> {
33
- public:
34
- enum { VALUE = 1 };
35
- };
36
-
37
- template <int Number>
38
- class StaticLog {
39
- public:
40
- enum { VALUE = StaticIf<(Number > 1), StaticLog<Number / 2>::VALUE + 1, 0>::VALUE };
41
- };
42
-
43
- #endif
@@ -1,103 +0,0 @@
1
- // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2
- // Copyright 2020 The Mesh Authors. All rights reserved.
3
- // Use of this source code is governed by the Apache License,
4
- // Version 2.0, that can be found in the LICENSE file.
5
-
6
- #include <atomic>
7
- #include <random>
8
-
9
- #include <benchmark/benchmark.h>
10
-
11
- #include "internal.h"
12
- #include "global_heap.h"
13
- #include "runtime.h"
14
- #include "shuffle_vector.h"
15
-
16
- using namespace mesh;
17
-
18
- static constexpr size_t kMiniHeapCount = 2 << 18;
19
- static constexpr uint32_t kObjSize = 16;
20
- static constexpr uint32_t kObjCount = 256;
21
-
22
- static void ATTRIBUTE_NEVER_INLINE initializeMiniHeaps(FixedArray<MiniHeap, kMiniHeapCount> &miniheaps) {
23
- // https://xkcd.com/221/ ; ensure results are repeatable (each benchmark sees the same bits set)
24
- static constexpr std::mt19937::result_type kSeed{3852235742};
25
- auto rng = std::bind(std::uniform_int_distribution<uint64_t>{}, std::mt19937{kSeed});
26
-
27
- for (size_t i = 0; i < kMiniHeapCount; i++) {
28
- MiniHeap *mh = miniheaps[i];
29
-
30
- // this is way way faster than setting each individual bit
31
- auto bits = mh->writableBitmap().mut_bits();
32
- for (size_t j = 0; j < 4; j++) {
33
- bits[j] = rng();
34
- }
35
- }
36
- }
37
-
38
- static void ATTRIBUTE_NEVER_INLINE initAndRefill(FixedArray<MiniHeap, kMiniHeapCount> &array, size_t &n,
39
- ShuffleVector &sv) {
40
- {
41
- FixedArray<MiniHeap, kMaxMiniheapsPerShuffleVector> &miniheaps = sv.miniheaps();
42
- miniheaps.clear();
43
- for (size_t i = 0; i < kMaxMiniheapsPerShuffleVector; i++) {
44
- miniheaps.append(array[n++]);
45
- hard_assert(n < kMiniHeapCount);
46
- }
47
- }
48
- sv.reinit();
49
-
50
- bool cont = true;
51
- // it may take a few iterations to pull the available offsets from our miniheaps
52
- while (likely(cont)) {
53
- while (likely(!sv.isExhausted())) {
54
- char *ptr = reinterpret_cast<char *>(sv.malloc());
55
- hard_assert(ptr != nullptr);
56
- ptr[0] = 'x';
57
- }
58
-
59
- cont = sv.localRefill();
60
- }
61
- }
62
-
63
- static void BM_LocalRefill1(benchmark::State &state) {
64
- mesh::debug("local refill test!\n");
65
- const auto tid = gettid();
66
- GlobalHeap &gheap = runtime().heap();
67
-
68
- // disable automatic meshing for this test
69
- gheap.setMeshPeriodMs(kZeroMs);
70
-
71
- static FixedArray<MiniHeap, kMiniHeapCount> array{};
72
- if (array.size() == 0) {
73
- const size_t initialAllocCount = gheap.getAllocatedMiniheapCount();
74
- hard_assert_msg(initialAllocCount == 0UL, "expected 0 initial MHs, not %zu", initialAllocCount);
75
-
76
- // allocate two miniheaps for the same object size from our global heap
77
- gheap.allocSmallMiniheaps(SizeMap::SizeClass(kObjSize), kObjSize, array, tid);
78
- mesh::debug("initializing the miniheaps\n");
79
- }
80
-
81
- // always reinitialize the bitmaps (will be same pattern each time)
82
- initializeMiniHeaps(array);
83
-
84
- ShuffleVector sv{};
85
- sv.initialInit(gheap.arenaBegin(), kObjSize);
86
-
87
- size_t n = 0;
88
-
89
- for (auto _ : state) {
90
- initAndRefill(array, n, sv);
91
- }
92
-
93
- // for (size_t i = 0; i < kMiniHeapCount; i++) {
94
- // MiniHeap *mh = array[i];
95
- // gheap.freeMiniheap(mh);
96
- // }
97
- // array.clear();
98
-
99
- sv.miniheaps().clear();
100
- }
101
- BENCHMARK(BM_LocalRefill1);
102
-
103
- BENCHMARK_MAIN();
@@ -1,28 +0,0 @@
1
- #include <stdio.h>
2
- #include <stdlib.h>
3
- #include <string.h>
4
-
5
- #define SZ 32816
6
- #define NOBJS 40
7
-
8
- volatile char *volatile var;
9
-
10
- int main() {
11
- char *objects[NOBJS];
12
- memset(objects, 0, sizeof(*objects) * NOBJS);
13
-
14
- for (size_t i = 0; i < 1000000; i++) {
15
- var = malloc(SZ);
16
- memset((char *)var, 0x55, SZ);
17
- size_t off = i % NOBJS;
18
- if (objects[off] != NULL)
19
- free(objects[off]);
20
- objects[off] = (char *)var;
21
- var = NULL;
22
- }
23
-
24
- for (size_t i = 0; i < NOBJS; i++) {
25
- if (objects[i] != NULL)
26
- free(objects[i]);
27
- }
28
- }
@@ -1,128 +0,0 @@
1
- // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2
- // Copyright 2019 The Mesh Authors. All rights reserved.
3
- // Use of this source code is governed by the Apache License,
4
- // Version 2.0, that can be found in the LICENSE file.
5
-
6
- #include <unistd.h>
7
- #include <cstdio>
8
- #include <cstring>
9
- #include <memory>
10
- #include <sstream>
11
- #include <string>
12
- #include <vector>
13
-
14
- #include "measure_rss.h"
15
-
16
- void print_rss() {
17
- printf("\trss:\t%10.3f MB\n", get_rss_kb() / 1024.0);
18
- }
19
-
20
- extern "C" {
21
- int mesh_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
22
- }
23
-
24
- using std::string;
25
-
26
- // use as (voidptr)ptr -- disgusting, but useful to minimize the clutter
27
- // around using volatile.
28
- #define voidptr void *)(intptr_t
29
- #define NOINLINE __attribute__((noinline))
30
- #define MESH_MARKER (7305126540297948313)
31
- #define MB (1024 * 1024)
32
- #define GB (1024 * 1024 * 1024)
33
-
34
- void *NOINLINE bench_alloc(size_t n) {
35
- volatile void *ptr = malloc(n);
36
- for (size_t i = 0; i < n; i++) {
37
- ((char *)ptr)[i] = lrand48() & 0xff;
38
- }
39
-
40
- return (voidptr)ptr;
41
- }
42
-
43
- void NOINLINE bench_free(void *ptr) {
44
- free(ptr);
45
- }
46
-
47
- // Fig 4. "A Basic Strategy" from http://www.ece.iastate.edu/~morris/papers/10/ieeetc10.pdf
48
- void NOINLINE basic_fragment(int64_t n, size_t m_total) {
49
- int64_t ci = 1;
50
- int64_t m_avail = m_total;
51
- size_t m_usage = 0; // S_t in the paper
52
- size_t retained_off = 0;
53
-
54
- const size_t ptr_table_len = 2 * m_total / (ci * n);
55
- // fprintf(stdout, "ptr_table_len: %zu\n", ptr_table_len);
56
- volatile char *volatile *ptr_table =
57
- reinterpret_cast<volatile char *volatile *>(bench_alloc(ptr_table_len * sizeof(char *)));
58
- volatile char *volatile *retained_table =
59
- reinterpret_cast<volatile char *volatile *>(bench_alloc(ptr_table_len * sizeof(char *)));
60
- memset((voidptr)retained_table, 0, ptr_table_len * sizeof(char *));
61
-
62
- // show how much RSS we just burned through for the table of
63
- // pointers we just allocated
64
- print_rss();
65
-
66
- for (int64_t i = 1; m_avail >= 2 * ci * n; i++) {
67
- ci *= 2;
68
- // number of allocation pairs in this iteration
69
- const size_t pi = m_avail / (2 * ci * n);
70
-
71
- fprintf(stderr, "i:%4lld, ci:%5lld, n:%5lld, pi:%7zu (osize:%5lld)\n", (long long int)i, (long long int)ci,
72
- (long long int)n, pi, (long long int)(ci * n));
73
-
74
- // allocate two objects
75
- for (size_t k = 0; k < pi; k++) {
76
- ptr_table[2 * k + 0] = reinterpret_cast<volatile char *>(bench_alloc(ci * n));
77
- ptr_table[2 * k + 1] = reinterpret_cast<volatile char *>(bench_alloc(ci * n));
78
- }
79
-
80
- m_usage += ci * n * pi;
81
-
82
- // now free every other object
83
- for (size_t k = 0; k < pi; k++) {
84
- retained_table[retained_off++] = ptr_table[2 * k + 0];
85
- bench_free((voidptr)ptr_table[2 * k + 1]);
86
- }
87
-
88
- m_avail -= ci * n * pi;
89
- }
90
-
91
- fprintf(stderr, "allocated (and not freed) %f MB\n", ((double)m_usage) / MB);
92
-
93
- print_rss();
94
-
95
- // mesh_mallctl("mesh.scavenge", nullptr, nullptr, nullptr, 0);
96
-
97
- print_rss();
98
-
99
- for (size_t i = 0; i < ptr_table_len; i++) {
100
- bench_free((voidptr)retained_table[i]);
101
- }
102
-
103
- print_rss();
104
-
105
- bench_free((voidptr)ptr_table);
106
- bench_free((voidptr)retained_table);
107
-
108
- // mesh_mallctl("mesh.scavenge", nullptr, nullptr, nullptr, 0);
109
- }
110
-
111
- int main(int argc, char *argv[]) {
112
- print_rss();
113
-
114
- basic_fragment(512, 128 * MB);
115
-
116
- print_rss();
117
- // char *env = getenv("LD_PRELOAD");
118
- // if (env && strstr(env, "libmesh.so") != NULL) {
119
- // fprintf(stderr, "meshing stuff\n");
120
- // free((void *)MESH_MARKER);
121
- // }
122
-
123
- // print_rss();
124
-
125
- // sleep(700);
126
-
127
- return 0;
128
- }
@@ -1,25 +0,0 @@
1
- #include <cstdio>
2
- #include <cstdlib>
3
- #include <vector>
4
-
5
- static constexpr size_t kMinAllocSz = 800000;
6
- static constexpr size_t kMaxAllocSz = 900000;
7
- static constexpr unsigned kMaxLiveAlloc = 128; // keep no more than 128 * kMaxAllocSz memory allocated.
8
-
9
- int main(void) {
10
- std::vector<void *> alloc(kMaxLiveAlloc, nullptr);
11
- for (size_t i = 0; i < kMaxLiveAlloc; i++) {
12
- if (alloc[i] != nullptr) {
13
- fprintf(stderr, "alloc not zero initialized!\n");
14
- }
15
- }
16
-
17
- while (1) {
18
- const size_t ix = rand() % kMaxLiveAlloc;
19
- const size_t sz = (rand() % (kMaxAllocSz - kMinAllocSz)) + kMinAllocSz;
20
-
21
- free(alloc[ix]);
22
- alloc[ix] = malloc(sz);
23
- }
24
- return 0;
25
- }
@@ -1,16 +0,0 @@
1
- #include <stdio.h>
2
- #include <stdlib.h>
3
- #include <string.h>
4
-
5
- #define SZ 61
6
-
7
- volatile char *volatile var;
8
-
9
- int main() {
10
- for (size_t i = 0; i < 200000000; i++) {
11
- var = malloc(SZ);
12
- /* memset((char *)var, 0, SZ); */
13
- free((void *)var);
14
- var = NULL;
15
- }
16
- }
@@ -1,189 +0,0 @@
1
- // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*-
2
- // Copyright 2019 The Mesh Authors. All rights reserved.
3
- // Use of this source code is governed by the Apache License,
4
- // Version 2.0, that can be found in the LICENSE file.
5
-
6
- #include <cstdio>
7
- #include <cstring>
8
- #include <memory>
9
- #include <sstream>
10
- #include <string>
11
- #include <vector>
12
-
13
- #if defined(__APPLE__)
14
- #include <libgen.h>
15
- #endif
16
-
17
- #include "internal.h"
18
-
19
- #include "bitmap.h"
20
- #include "meshing.h"
21
-
22
- using mesh::internal::Bitmap;
23
- using std::make_unique;
24
- using std::stoi;
25
- using std::string;
26
- using std::unique_ptr;
27
- using std::vector;
28
-
29
- // https://stackoverflow.com/questions/236129/split-a-string-in-c
30
- template <typename Out>
31
- void split(const std::string &s, char delim, Out result) {
32
- std::stringstream ss;
33
- ss.str(s);
34
- std::string item;
35
- while (std::getline(ss, item, delim)) {
36
- *(result++) = item;
37
- }
38
- }
39
-
40
- // https://stackoverflow.com/questions/236129/split-a-string-in-c
41
- std::vector<std::string> split(const std::string &s, char delim) {
42
- std::vector<std::string> elems;
43
- split(s, delim, std::back_inserter(elems));
44
- return elems;
45
- }
46
-
47
- class MeshTestcase {
48
- public:
49
- explicit MeshTestcase(int length, int occupancy, int nStrings, string method)
50
- : length(static_cast<size_t>(length)),
51
- occupancy(static_cast<size_t>(occupancy)),
52
- nStrings(static_cast<size_t>(nStrings)),
53
- method(method) {
54
- d_assert(length > 0);
55
- d_assert(occupancy > 0);
56
- d_assert(nStrings > 0);
57
- }
58
- vector<Bitmap> bitmaps{};
59
- vector<mesh::internal::string> strings{};
60
-
61
- size_t length; // string length
62
- size_t occupancy;
63
- size_t nStrings;
64
- string method;
65
-
66
- ssize_t expectedResult{-1};
67
- };
68
-
69
- unique_ptr<MeshTestcase> openTestcase(const char *path) {
70
- FILE *f = fopen(path, "r");
71
- if (f == nullptr) {
72
- fprintf(stderr, "ERROR: couldn't open testcase %s: %s\n", path, strerror(errno));
73
- exit(1);
74
- }
75
-
76
- auto *bname = basename((char *)path);
77
- auto *fname = strdup(bname);
78
- auto *dotPos = strrchr(fname, '.');
79
- // remove the extension if it exists
80
- if (dotPos) {
81
- *dotPos = 0;
82
- }
83
-
84
- vector<string> parts = split(fname, ',');
85
- if (parts.size() != 4) {
86
- fprintf(stderr, "ERROR: expected filename to have 4 parts before extension: %s\n", path);
87
- exit(1);
88
- }
89
- free(fname);
90
-
91
- auto testcase = make_unique<MeshTestcase>(stoi(parts[0]), stoi(parts[1]), stoi(parts[2]), parts[3]);
92
-
93
- bool loop = true;
94
- while (loop) {
95
- char *line = nullptr;
96
- size_t n = 0;
97
- ssize_t len = getline(&line, &n, f);
98
- if ((len < 0 && !errno) || len == 0) {
99
- if (line)
100
- free(line);
101
- fprintf(stderr, "ERROR: unexpected end of testcase\n");
102
- exit(1);
103
- } else if (len < 0) {
104
- fprintf(stderr, "ERROR: getline: %s\n", strerror(errno));
105
- exit(1);
106
- }
107
- d_assert(line != nullptr);
108
-
109
- d_assert(len > 0);
110
- if (line[len - 1] == '\n') {
111
- line[len - 1] = 0;
112
- len--;
113
- }
114
-
115
- d_assert(len > 0);
116
- if (line[len - 1] == '\r') {
117
- line[len - 1] = 0;
118
- len--;
119
- }
120
-
121
- d_assert(len > 0);
122
- if (line[0] == '-') {
123
- testcase->expectedResult = stoi(&line[1]);
124
- loop = false;
125
- } else {
126
- mesh::internal::string sline{line};
127
- d_assert(sline.length() == testcase->length);
128
-
129
- testcase->bitmaps.emplace_back(sline);
130
- testcase->strings.emplace_back(sline);
131
-
132
- d_assert_msg(sline == testcase->bitmaps.back().to_string(sline.length()), "expected roundtrip '%s' == '%s'", line,
133
- testcase->bitmaps.back().to_string().c_str());
134
- }
135
- free(line);
136
- }
137
- fclose(f);
138
-
139
- d_assert_msg(testcase->strings.size() == testcase->nStrings, "%zu == %zu", testcase->strings.size(),
140
- testcase->nStrings);
141
- d_assert(testcase->expectedResult >= 0);
142
-
143
- return testcase;
144
- }
145
-
146
- bool validate(const unique_ptr<MeshTestcase> &testcase) {
147
- ssize_t result = 0;
148
- if (testcase->method == "dumb") {
149
- // result = mesh::method::simple(testcase->bitmaps);
150
- printf("TODO: implement new shifted splitting method here\n");
151
- if (result == testcase->expectedResult)
152
- return true;
153
- } else {
154
- printf("ERROR: unimplemented method '%s'\n", testcase->method.c_str());
155
- return false;
156
- }
157
-
158
- if (result != testcase->expectedResult) {
159
- printf("ERROR: unexpected result %zu (expected %zu) for %s method\n", result, testcase->expectedResult,
160
- testcase->method.c_str());
161
- }
162
- return false;
163
- }
164
-
165
- int main(int argc, char *argv[]) {
166
- if (argc > 1 && ((strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-h") == 0))) {
167
- fprintf(stderr, "Reads in string dumps and attempts to mesh.\n\n");
168
- fprintf(stderr, "USAGE: %s DUMP_FILE\n", basename(argv[0]));
169
- exit(0);
170
- }
171
-
172
- if (argc <= 1) {
173
- fprintf(stderr, "ERROR: expected at least one filename pointing to a dump.\n");
174
- exit(1);
175
- }
176
-
177
- for (auto i = 1; i < argc; ++i) {
178
- printf("meshing strings from %s\n", argv[i]);
179
-
180
- auto testcase = openTestcase(argv[i]);
181
-
182
- if (!validate(testcase)) {
183
- printf("%s: failed to validate.\n", argv[i]);
184
- exit(1);
185
- }
186
- }
187
-
188
- return 0;
189
- }