LotSizingDataModel.Instance 2.0.1
Lot-sizing instance representation, descriptors and problem characterization.
Loading...
Searching...
No Matches
BenchmarkDatasetLayout.cs
Go to the documentation of this file.
2
3/// <summary>
4/// Canonical repository layout for benchmark artifacts.
5/// </summary>
6public static class BenchmarkDatasetLayout
7{
8 public const string RootDirectory =
9 "benchmarks";
10
11 public const string RawDirectory =
12 "raw";
13
14 public const string AnnotatedDirectory =
15 "annotated";
16
17 public const string SolutionsDirectory =
18 "solutions";
19
20 public const string CampaignsDirectory =
21 "campaigns";
22
23 public static string GetDirectory(
25 {
26 return kind switch
27 {
29 $"{RootDirectory}/{RawDirectory}",
30
32 $"{RootDirectory}/{AnnotatedDirectory}",
33
35 $"{RootDirectory}/{SolutionsDirectory}",
36
38 $"{RootDirectory}/{CampaignsDirectory}",
39
40 _ =>
41 throw new ArgumentOutOfRangeException(
42 nameof(kind),
43 kind,
44 "Unknown benchmark artifact kind.")
45 };
46 }
47
48 public static string CreateRelativePath(
50 string family,
51 string fileName)
52 {
53 string normalizedFamily =
54 NormalizeSegment(
55 family,
56 nameof(family));
57
58 string normalizedFile =
59 NormalizeSegment(
60 fileName,
61 nameof(fileName));
62
63 return
64 $"{GetDirectory(kind)}/{normalizedFamily}/{normalizedFile}";
65 }
66
67 public static void EnsureCanonicalRelativePath(
68 string relativePath)
69 {
70 if (string.IsNullOrWhiteSpace(
71 relativePath))
72 {
73 throw new ArgumentException(
74 "A benchmark relative path is required.",
75 nameof(relativePath));
76 }
77
78 string normalized =
79 relativePath
80 .Replace('\\', '/')
81 .Trim();
82
83 if (normalized.StartsWith(
84 "/",
85 StringComparison.Ordinal) ||
86 normalized.Contains(
87 "../",
88 StringComparison.Ordinal) ||
89 normalized.Contains(
90 "/..",
91 StringComparison.Ordinal))
92 {
93 throw new InvalidOperationException(
94 "Benchmark artifact paths must remain relative and cannot traverse directories.");
95 }
96
97 string[] allowedPrefixes =
98 [
99 $"{RootDirectory}/{RawDirectory}/",
100 $"{RootDirectory}/{AnnotatedDirectory}/",
101 $"{RootDirectory}/{SolutionsDirectory}/",
102 $"{RootDirectory}/{CampaignsDirectory}/"
103 ];
104
105 if (!allowedPrefixes.Any(
106 prefix =>
107 normalized.StartsWith(
108 prefix,
109 StringComparison.Ordinal)))
110 {
111 throw new InvalidOperationException(
112 $"Benchmark path '{normalized}' is outside the canonical raw/annotated/solutions/campaigns layout.");
113 }
114 }
115
116 private static string NormalizeSegment(
117 string value,
118 string parameterName)
119 {
120 if (string.IsNullOrWhiteSpace(
121 value))
122 {
123 throw new ArgumentException(
124 "A non-empty benchmark path segment is required.",
125 parameterName);
126 }
127
128 string normalized =
129 value.Trim();
130
131 if (normalized.Contains('/') ||
132 normalized.Contains('\\') ||
133 normalized is "." or "..")
134 {
135 throw new ArgumentException(
136 "Benchmark path segments cannot contain directory separators or traversal tokens.",
137 parameterName);
138 }
139
140 return normalized;
141 }
142}
Canonical repository layout for benchmark artifacts.
static string GetDirectory(BenchmarkDatasetArtifactKind kind)
static string CreateRelativePath(BenchmarkDatasetArtifactKind kind, string family, string fileName)