serialbench 0.8.1 → 0.9.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55b58686ee445c84cbbf69588022d932a56c7014255567c19d3bc44c2ddbad53
4
- data.tar.gz: 0353b87e4e5d5690a706e2ef3b2e3d96f85166092b098893c13b9024b56acf4e
3
+ metadata.gz: 814cb0f6d767b00d0b936a40e6d9cdc45ddb185fafd8c6149e67a78454f5cbdd
4
+ data.tar.gz: cf269293728af5a4eb3f479af7ed3e41204307e6953c04f8fc08298b4e45473f
5
5
  SHA512:
6
- metadata.gz: fdf9e8086fa5e7960151717340df5f131679af2389bf4126801f9a2ab777fed04f3eba511d108e2a4fe2d3f9e47c723970a22911b20880a162d93fdf85f7ace5
7
- data.tar.gz: 665f581b8491ce518a0602f76dfc7227ae51c14f343bbf650c6ee5e4b735b3d64676d4af3fd2b6e10d9eb16209ca9ec412763072183d1101cf6e63c40088a83d
6
+ metadata.gz: 55385f1d7ad647b3e6e11d066276a6f8369f8d218571ecf19c01e8d71af9b8c62c126a980b65cb54c67bf989e22bb278d1c4b659dde046373f95dced12007b09
7
+ data.tar.gz: 8e9e38c807063136a6c97fcae14c24575849d044c61660edc85bb9ccdc7dc1ba1f19081cd9a43cd968934731d3c98aa40b28f633f1b84aedb128738fac7ca370
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+ # Exit 0 if this leg's format results are already in the data repo, 1 if not.
3
+ # The data repo is the checkpoint ledger: a present file means the format was
4
+ # measured and pushed; reruns skip it and only fill what is missing.
5
+ set -euo pipefail
6
+
7
+ FMT="$1"
8
+ RUBY_VERSION="$2"
9
+ PLATFORM="$3"
10
+ DATA_TOKEN="${DATA_REPO_TOKEN:-}"
11
+ DATE="${DATA_RUN_DATE:-$(date -u +%Y-%m-%d)}"
12
+
13
+ [ -n "$DATA_TOKEN" ] || exit 1
14
+
15
+ TARGET="runs/${DATE}/${PLATFORM}-ruby-${RUBY_VERSION}.${FMT}.yaml"
16
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
17
+ -H "Authorization: Bearer ${DATA_TOKEN}" \
18
+ "https://api.github.com/repos/serialbench/data/contents/${TARGET}")
19
+
20
+ [ "$HTTP_CODE" = "200" ] && exit 0
21
+ exit 1
@@ -21,7 +21,9 @@ if [ ! -f "$RESULTS_FILE" ]; then
21
21
  exit 0
22
22
  fi
23
23
 
24
- DATE=$(date -u +%Y-%m-%d)
24
+ # The matrix start date (setup job output), so every push and rerun of one
25
+ # matrix lands in one dated directory; wall clock is only a fallback.
26
+ DATE="${DATA_RUN_DATE:-$(date -u +%Y-%m-%d)}"
25
27
  TARGET_PATH="runs/${DATE}/${PLATFORM}-ruby-${RUBY_VERSION}.${FMT}.yaml"
26
28
  CONTENT=$(base64 < "$RESULTS_FILE" | tr -d '\r\n')
27
29
 
@@ -37,19 +39,31 @@ HTTP_CODE=$(curl -s -o /tmp/data-push-resp.json -w "%{http_code}" -X PUT \
37
39
  if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
38
40
  echo "Pushed ${TARGET_PATH}"
39
41
  elif [ "$HTTP_CODE" = "422" ]; then
40
- SHA=$(curl -sf \
41
- -H "Authorization: Bearer ${DATA_TOKEN}" \
42
- "https://api.github.com/repos/serialbench/data/contents/${TARGET_PATH}" \
43
- | grep -oE '"sha":\s*"[a-f0-9]+"' | head -1 | grep -oE '[a-f0-9]{40}')
44
- if [ -n "$SHA" ]; then
45
- curl -sf -X PUT \
42
+ # File exists: fetch its sha and update. 409 (sha race when the branch
43
+ # moves between fetch and put) is retried with a fresh sha.
44
+ UPDATE_CODE=409
45
+ for TRY in 1 2 3; do
46
+ SHA=$(curl -sf \
47
+ -H "Authorization: Bearer ${DATA_TOKEN}" \
48
+ "https://api.github.com/repos/serialbench/data/contents/${TARGET_PATH}" \
49
+ | grep -oE '"sha":\s*"[a-f0-9]+"' | head -1 | grep -oE '[a-f0-9]{40}')
50
+ if [ -z "$SHA" ]; then
51
+ echo "::warning::422 but couldn't get sha for ${TARGET_PATH}"
52
+ break
53
+ fi
54
+ UPDATE_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X PUT \
46
55
  -H "Authorization: Bearer ${DATA_TOKEN}" \
47
56
  -H "Accept: application/vnd.github+json" \
48
57
  "https://api.github.com/repos/serialbench/data/contents/${TARGET_PATH}" \
49
- -d "{\"message\": \"${PLATFORM} ruby-${RUBY_VERSION} ${FMT} (update)\", \"content\": \"${CONTENT}\", \"sha\": \"${SHA}\", \"branch\": \"main\"}" > /dev/null
58
+ -d "{\"message\": \"${PLATFORM} ruby-${RUBY_VERSION} ${FMT} (update)\", \"content\": \"${CONTENT}\", \"sha\": \"${SHA}\", \"branch\": \"main\"}")
59
+ [ "$UPDATE_CODE" = "200" ] && break
60
+ echo "update attempt $TRY got $UPDATE_CODE — refetching sha"
61
+ sleep 2
62
+ done
63
+ if [ "$UPDATE_CODE" = "200" ]; then
50
64
  echo "Updated existing ${TARGET_PATH}"
51
- else
52
- echo "::warning::422 but couldn't get sha for ${TARGET_PATH}"
65
+ elif [ -n "$SHA" ]; then
66
+ echo "::warning::could not update ${TARGET_PATH} ($UPDATE_CODE)"
53
67
  fi
54
68
  else
55
69
  echo "::warning::Push failed (${HTTP_CODE}): $(cat /tmp/data-push-resp.json | head -c 200)"
@@ -0,0 +1,59 @@
1
+ name: benchmark-autoheal
2
+
3
+ # Reruns failed legs (runner evictions, OOM blips) of the latest benchmark
4
+ # matrix without human intervention. Capped: a run gets at most 5 attempts,
5
+ # and deliberately cancelled runs are never resurrected.
6
+ on:
7
+ # Heal immediately when a matrix completes (reliable event seam); the
8
+ # hourly cron below is only a backstop — GitHub drops cron ticks freely.
9
+ workflow_run:
10
+ workflows: [benchmark-weekly]
11
+ types: [completed]
12
+ schedule:
13
+ # hourly at :23 — off the busy top of the hour
14
+ - cron: '23 * * * *'
15
+ workflow_dispatch:
16
+
17
+ permissions:
18
+ actions: write
19
+
20
+ concurrency:
21
+ group: benchmark-autoheal
22
+ cancel-in-progress: false
23
+
24
+ jobs:
25
+ rerun-failed:
26
+ runs-on: ubuntu-latest
27
+ timeout-minutes: 5
28
+ steps:
29
+ - name: Rerun failed benchmark legs (capped)
30
+ env:
31
+ GH_TOKEN: ${{ github.token }}
32
+ run: |
33
+ set -euo pipefail
34
+ RUN_ID=$(gh run list -R "$GITHUB_REPOSITORY" --workflow=benchmark.yml --limit 1 --json databaseId --jq '.[0].databaseId')
35
+ [ -n "$RUN_ID" ] || { echo "no benchmark run found"; exit 0; }
36
+
37
+ STATUS=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$RUN_ID" --jq '.status')
38
+ if [ "$STATUS" != "completed" ]; then
39
+ echo "latest run $RUN_ID still $STATUS — nothing to do"
40
+ exit 0
41
+ fi
42
+
43
+ CONCLUSION=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$RUN_ID" --jq '.conclusion // ""')
44
+ if [ "$CONCLUSION" != "failure" ]; then
45
+ echo "latest run concluded $CONCLUSION — nothing to rerun (cancelled runs are deliberate)"
46
+ exit 0
47
+ fi
48
+
49
+ ATTEMPT=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$RUN_ID" --jq '.run_attempt')
50
+ if [ "$ATTEMPT" -ge 5 ]; then
51
+ echo "attempt cap reached ($ATTEMPT) — leaving for humans"
52
+ exit 1
53
+ fi
54
+
55
+ FAILED=$(gh run view "$RUN_ID" -R "$GITHUB_REPOSITORY" --json jobs --jq '[.jobs[] | select(.conclusion == "failure")] | length')
56
+ [ "$FAILED" -gt 0 ] || { echo "no failed legs"; exit 0; }
57
+
58
+ echo "rerunning $FAILED failed legs (attempt $ATTEMPT -> $((ATTEMPT + 1)))"
59
+ gh run rerun "$RUN_ID" -R "$GITHUB_REPOSITORY" --failed
@@ -3,7 +3,12 @@ name: benchmark-weekly
3
3
  on:
4
4
  push:
5
5
  branches: [main]
6
- pull_request:
6
+ paths-ignore:
7
+ - 'README.md'
8
+ - 'CONTEXT.md'
9
+ - 'docs/**'
10
+ - 'lib/serialbench/version.rb'
11
+ - '**.md'
7
12
  schedule:
8
13
  # Run benchmarks weekly on Sundays at 2 AM UTC
9
14
  - cron: '0 2 * * 0'
@@ -20,20 +25,24 @@ concurrency:
20
25
  jobs:
21
26
  setup:
22
27
  runs-on: ubuntu-latest
28
+ timeout-minutes: 5
23
29
  outputs:
24
30
  ruby-versions: ${{ steps.set-matrix.outputs.ruby-versions }}
25
31
  platforms: ${{ steps.set-matrix.outputs.platforms }}
32
+ run-date: ${{ steps.set-matrix.outputs.run-date }}
26
33
  steps:
27
34
  - name: Set matrix configurations
28
35
  id: set-matrix
29
36
  run: |
30
37
  echo 'ruby-versions=["3.2", "3.3", "3.4", "4.0"]' >> $GITHUB_OUTPUT
31
38
  echo 'platforms=["ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-14", "macos-15", "macos-15-intel", "macos-26", "macos-26-intel", "windows-2022", "windows-2025", "windows-11-arm"]' >> $GITHUB_OUTPUT
39
+ echo "run-date=$(date -u +%Y-%m-%d)" >> $GITHUB_OUTPUT
32
40
 
33
41
  # Cross-platform native benchmarks
34
42
  benchmark:
35
43
  runs-on: ${{ matrix.platform }}
36
44
  needs: setup
45
+ timeout-minutes: 120
37
46
  strategy:
38
47
  fail-fast: false
39
48
  matrix:
@@ -125,7 +134,13 @@ jobs:
125
134
  shell: bash
126
135
  env:
127
136
  GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
137
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
138
+ DATA_RUN_DATE: ${{ needs.setup.outputs.run-date }}
128
139
  run: |
140
+ if [ "${{ github.run_attempt }}" -gt 1 ] && .github/scripts/format-status.sh json ${{ matrix.ruby-version }} ${{ matrix.platform }}; then
141
+ echo "json already in the data repo — skipping (gap-filling rerun)"
142
+ exit 0
143
+ fi
129
144
  bundle exec serialbench environment execute \
130
145
  config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
131
146
  config/benchmarks/full-json.yml \
@@ -145,6 +160,7 @@ jobs:
145
160
  continue-on-error: true
146
161
  env:
147
162
  DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
163
+ DATA_RUN_DATE: ${{ needs.setup.outputs.run-date }}
148
164
  run: .github/scripts/push-to-data.sh json ${{ matrix.ruby-version }} ${{ matrix.platform }}
149
165
  shell: bash
150
166
 
@@ -153,7 +169,13 @@ jobs:
153
169
  shell: bash
154
170
  env:
155
171
  GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
172
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
173
+ DATA_RUN_DATE: ${{ needs.setup.outputs.run-date }}
156
174
  run: |
175
+ if [ "${{ github.run_attempt }}" -gt 1 ] && .github/scripts/format-status.sh yaml ${{ matrix.ruby-version }} ${{ matrix.platform }}; then
176
+ echo "yaml already in the data repo — skipping (gap-filling rerun)"
177
+ exit 0
178
+ fi
157
179
  bundle exec serialbench environment execute \
158
180
  config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
159
181
  config/benchmarks/full-yaml.yml \
@@ -173,6 +195,7 @@ jobs:
173
195
  continue-on-error: true
174
196
  env:
175
197
  DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
198
+ DATA_RUN_DATE: ${{ needs.setup.outputs.run-date }}
176
199
  run: .github/scripts/push-to-data.sh yaml ${{ matrix.ruby-version }} ${{ matrix.platform }}
177
200
  shell: bash
178
201
 
@@ -181,7 +204,13 @@ jobs:
181
204
  shell: bash
182
205
  env:
183
206
  GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
207
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
208
+ DATA_RUN_DATE: ${{ needs.setup.outputs.run-date }}
184
209
  run: |
210
+ if [ "${{ github.run_attempt }}" -gt 1 ] && .github/scripts/format-status.sh toml ${{ matrix.ruby-version }} ${{ matrix.platform }}; then
211
+ echo "toml already in the data repo — skipping (gap-filling rerun)"
212
+ exit 0
213
+ fi
185
214
  bundle exec serialbench environment execute \
186
215
  config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
187
216
  config/benchmarks/full-toml.yml \
@@ -201,6 +230,7 @@ jobs:
201
230
  continue-on-error: true
202
231
  env:
203
232
  DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
233
+ DATA_RUN_DATE: ${{ needs.setup.outputs.run-date }}
204
234
  run: .github/scripts/push-to-data.sh toml ${{ matrix.ruby-version }} ${{ matrix.platform }}
205
235
  shell: bash
206
236
 
@@ -211,7 +241,13 @@ jobs:
211
241
  shell: bash
212
242
  env:
213
243
  GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
244
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
245
+ DATA_RUN_DATE: ${{ needs.setup.outputs.run-date }}
214
246
  run: |
247
+ if [ "${{ github.run_attempt }}" -gt 1 ] && .github/scripts/format-status.sh xml ${{ matrix.ruby-version }} ${{ matrix.platform }}; then
248
+ echo "xml already in the data repo — skipping (gap-filling rerun)"
249
+ exit 0
250
+ fi
215
251
  bundle exec serialbench environment execute \
216
252
  config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
217
253
  config/benchmarks/full-xml.yml \
@@ -231,13 +267,37 @@ jobs:
231
267
  continue-on-error: true
232
268
  env:
233
269
  DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
270
+ DATA_RUN_DATE: ${{ needs.setup.outputs.run-date }}
234
271
  run: .github/scripts/push-to-data.sh xml ${{ matrix.ruby-version }} ${{ matrix.platform }}
235
272
  shell: bash
236
273
 
237
274
 
275
+
276
+ - name: Verify leg completeness
277
+ if: ${{ !cancelled() }}
278
+ shell: bash
279
+ env:
280
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
281
+ DATA_RUN_DATE: ${{ needs.setup.outputs.run-date }}
282
+ run: |
283
+ MISSING=""
284
+ for FMT in json yaml toml xml; do
285
+ if .github/scripts/format-status.sh "$FMT" "${{ matrix.ruby-version }}" "${{ matrix.platform }}"; then
286
+ echo "$FMT: in data repo"
287
+ else
288
+ echo "$FMT: MISSING from data repo"
289
+ MISSING="$MISSING $FMT"
290
+ fi
291
+ done
292
+ if [ -n "$MISSING" ]; then
293
+ echo "::error::formats never pushed:${MISSING} — failing the leg so autoheal fills the gap"
294
+ exit 1
295
+ fi
296
+
238
297
  # Summary job
239
298
  summary:
240
299
  runs-on: ubuntu-latest
300
+ timeout-minutes: 5
241
301
  needs: [setup, benchmark]
242
302
  if: always()
243
303
  steps:
@@ -64,6 +64,9 @@ jobs:
64
64
  git tag "v${VERSION}" 2>/dev/null || true
65
65
  git push origin "v${VERSION}" 2>/dev/null || true
66
66
 
67
+ - name: Validate the bumped tree
68
+ run: bundle exec rspec --format progress
69
+
67
70
  - name: Build gem
68
71
  run: gem build serialbench.gemspec
69
72
 
data/CONTEXT.md CHANGED
@@ -8,4 +8,5 @@
8
8
  - **Environment**: where a leg executes — `local`, `docker`, or `asdf` (`kind` in the environment config). Dispatched through `Runners.for`.
9
9
  - **Environment key**: `{platform}-ruby-{version}` (e.g. `macos-26-ruby-3.4`) — the site's identity for a platform×ruby pair.
10
10
  - **Capability**: a symbol in an adapter's capability set (`:xpath`, `:sax`, `:stax`, `:generate`, `:namespaces`…). Benchmarks filter adapters by capability; the site renders them as the capability strip.
11
+ - **Data push**: one Result Leg's results.yaml written to the data repo via the Contents API (atomic, per-format).
11
12
  - **Fixture**: the generated test document for a format × size (`small`/`medium`/`large`), built by `Serialbench::TestData`. `test_data/{size}.{format}` files override the generated one.
data/Gemfile CHANGED
@@ -12,7 +12,9 @@ unless Gem.win_platform? && RUBY_PLATFORM.include?('aarch64')
12
12
  gem 'libxml-ruby'
13
13
  end
14
14
 
15
- gem 'leptris', '1.9.35' # precompiled platform gems bundle libleptris (darwin/linux/mingw)
15
+ gem 'leptris', '1.9.152.1' # precompiled platform gems bundle libleptris (darwin/linux/mingw)
16
+ gem 'yeptris', '0.2.0.1' # precompiled darwin/linux; no windows or darwin-intel gems yet
17
+ gem 'teptris', '0.1.0' # precompiled all platforms
16
18
  gem 'benchmark' # Removed from stdlib in Ruby 4.0
17
19
  gem 'base64' # Required for Ruby 3.4+
18
20
  gem 'lutaml-model', '~> 0.7'
@@ -0,0 +1,14 @@
1
+ # ADR-0007: The data repo is the checkpoint ledger
2
+
3
+ Date: 2026-09-02
4
+
5
+ ## Context
6
+ A leg's format steps are continue-on-error, so a Benchmark step failing inside a green job was invisible: autoheal (job-level) never saw it, and the missing format file surfaced only as a coverage gap (19 of 184 missing on 2026-09-01). Rerunning whole green jobs to recover one format costs ~45 minutes of re-measurement per leg — deliberate duplicate work.
7
+
8
+ ## Decision
9
+ The data repo is the source of truth for what a leg has delivered:
10
+ 1. Every leg ends with a completeness check that queries the data repo for all four of its format files; any miss fails the leg, making gaps visible to autoheal.
11
+ 2. Benchmark steps skip a format whose file already exists — but only on rerun attempts (`github.run_attempt > 1`), so first attempts always measure fresh code.
12
+ 3. Consequently autoheal's reruns are surgical: pushed formats skip in seconds and only the missing format is measured — eviction windows shrink from ~45 minutes to a single format's runtime.
13
+
14
+ Gaps that survive the 5-attempt cap surface as red runs, never as silent holes.
@@ -65,9 +65,12 @@ module Serialbench
65
65
  return [] unless defined?(::MemoryProfiler)
66
66
 
67
67
  run_benchmark_iteration('memory') do |serializer, format, size, data|
68
- # Memory profiling for parsing
68
+ # Memory profiling for parsing. MemoryProfiler disables GC while
69
+ # reporting, so every profiled parse accumulates: ten large-document
70
+ # trees exhaust the 16GB windows runners. One parse fully captures
71
+ # a large document's allocation and retention profile.
69
72
  report = ::MemoryProfiler.report do
70
- 10.times { serializer.parse(data) }
73
+ profile_iterations(size).times { serializer.parse(data) }
71
74
  end
72
75
 
73
76
  result = Models::MemoryPerformance.new(
@@ -173,6 +176,10 @@ module Serialbench
173
176
  end
174
177
  end
175
178
 
179
+ def profile_iterations(size)
180
+ size.to_s == 'large' ? 1 : 10
181
+ end
182
+
176
183
  def validate_operations!
177
184
  unknown = (@benchmark_config.operations || []) - (OPERATIONS.keys + ['memory'])
178
185
  return if unknown.empty?
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_json_serializer'
4
+
5
+ module Serialbench
6
+ module Serializers
7
+ module Json
8
+ # Yeptris JSON side: parsing only — no dump in 0.2.x
9
+ class YeptrisSerializer < BaseJsonSerializer
10
+ def name
11
+ 'yeptris-json'
12
+ end
13
+
14
+ def parse(json_string)
15
+ require 'yeptris'
16
+ Yeptris::JSON.load(json_string)
17
+ end
18
+
19
+ def capabilities
20
+ Set.new(%i[dom parse])
21
+ end
22
+
23
+ def available?
24
+ return @available if defined?(@available)
25
+
26
+ @available = begin
27
+ require 'yeptris'
28
+ Yeptris::JSON.load('{"probe":true}')
29
+ true
30
+ rescue StandardError, LoadError
31
+ false
32
+ end
33
+ end
34
+
35
+ def version
36
+ return 'unknown' unless available?
37
+
38
+ require 'yeptris'
39
+ Yeptris::VERSION
40
+ end
41
+
42
+ def library_require_name
43
+ 'yeptris'
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_toml_serializer'
4
+
5
+ module Serialbench
6
+ module Serializers
7
+ module Toml
8
+ class TeptrisSerializer < BaseTomlSerializer
9
+ def name
10
+ 'teptris'
11
+ end
12
+
13
+ def parse(toml_string)
14
+ require 'teptris'
15
+ Teptris::TOML.load(toml_string)
16
+ end
17
+
18
+ def generate(object, _options = {})
19
+ require 'teptris'
20
+ Teptris::TOML.dump(object)
21
+ end
22
+
23
+ def available?
24
+ return @available if defined?(@available)
25
+
26
+ @available = begin
27
+ require 'teptris'
28
+ Teptris::TOML.load("probe = true\n")
29
+ true
30
+ rescue StandardError, LoadError
31
+ false
32
+ end
33
+ end
34
+
35
+ def version
36
+ return 'unknown' unless available?
37
+
38
+ require 'teptris'
39
+ Teptris::VERSION
40
+ end
41
+
42
+ def library_require_name
43
+ 'teptris'
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_yaml_serializer'
4
+
5
+ module Serialbench
6
+ module Serializers
7
+ module Yaml
8
+ class YeptrisSerializer < BaseYamlSerializer
9
+ def name
10
+ 'yeptris-yaml'
11
+ end
12
+
13
+ def parse(yaml_string)
14
+ require 'yeptris'
15
+ Yeptris::YAML.load(yaml_string)
16
+ end
17
+
18
+ def generate(object, _options = {})
19
+ require 'yeptris'
20
+ Yeptris::YAML.dump(object)
21
+ end
22
+
23
+ def stream_parse(yaml_string, &block)
24
+ require 'yeptris'
25
+ Yeptris::YAML.load_stream(yaml_string).each { |doc| block.call(:document, doc) }
26
+ end
27
+
28
+ def capabilities
29
+ super | Set.new(%i[streaming])
30
+ end
31
+
32
+ def available?
33
+ return @available if defined?(@available)
34
+
35
+ @available = begin
36
+ require 'yeptris'
37
+ Yeptris::YAML.load('probe: true')
38
+ true
39
+ rescue StandardError, LoadError
40
+ false
41
+ end
42
+ end
43
+
44
+ def version
45
+ return 'unknown' unless available?
46
+
47
+ require 'yeptris'
48
+ Yeptris::VERSION
49
+ end
50
+
51
+ def library_require_name
52
+ 'yeptris'
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -18,17 +18,20 @@ require_relative 'serializers/json/json_serializer'
18
18
  require_relative 'serializers/json/oj_serializer'
19
19
  require_relative 'serializers/json/yajl_serializer'
20
20
  require_relative 'serializers/json/rapidjson_serializer'
21
+ require_relative 'serializers/json/yeptris_serializer'
21
22
 
22
23
  # YAML Serializers
23
24
  require_relative 'serializers/yaml/base_yaml_serializer'
24
25
  require_relative 'serializers/yaml/psych_serializer'
25
26
  require_relative 'serializers/yaml/syck_serializer'
27
+ require_relative 'serializers/yaml/yeptris_serializer'
26
28
 
27
29
  # TOML Serializers
28
30
  require_relative 'serializers/toml/base_toml_serializer'
29
31
  require_relative 'serializers/toml/toml_rb_serializer'
30
32
  require_relative 'serializers/toml/tomlib_serializer'
31
33
  require_relative 'serializers/toml/tomlrb_serializer'
34
+ require_relative 'serializers/toml/teptris_serializer'
32
35
 
33
36
  module Serialbench
34
37
  module Serializers
@@ -46,16 +49,19 @@ module Serialbench
46
49
  Json::JsonSerializer,
47
50
  Json::OjSerializer,
48
51
  Json::RapidjsonSerializer,
49
- Json::YajlSerializer
52
+ Json::YajlSerializer,
53
+ Json::YeptrisSerializer
50
54
  ],
51
55
  yaml: [
52
56
  Yaml::PsychSerializer,
53
- Yaml::SyckSerializer
57
+ Yaml::SyckSerializer,
58
+ Yaml::YeptrisSerializer
54
59
  ],
55
60
  toml: [
56
61
  Toml::TomlRbSerializer,
57
62
  Toml::TomlibSerializer,
58
- Toml::TomlrbSerializer
63
+ Toml::TomlrbSerializer,
64
+ Toml::TeptrisSerializer
59
65
  ]
60
66
  }.freeze
61
67
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Serialbench
4
- VERSION = '0.8.1'
4
+ VERSION = '0.9.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serialbench
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
@@ -256,7 +256,9 @@ executables:
256
256
  extensions: []
257
257
  extra_rdoc_files: []
258
258
  files:
259
+ - ".github/scripts/format-status.sh"
259
260
  - ".github/scripts/push-to-data.sh"
261
+ - ".github/workflows/benchmark-autoheal.yml"
260
262
  - ".github/workflows/benchmark.yml"
261
263
  - ".github/workflows/rake.yml"
262
264
  - ".github/workflows/release.yml"
@@ -296,6 +298,7 @@ files:
296
298
  - docs/adr/0004-explicit-workflow-steps.md
297
299
  - docs/adr/0005-site-loader-stays-flat.md
298
300
  - docs/adr/0006-operations-vocabulary.md
301
+ - docs/adr/0007-data-repo-checkpoint-ledger.md
299
302
  - exe/serialbench
300
303
  - lib/serialbench.rb
301
304
  - lib/serialbench/benchmark_runner.rb
@@ -325,7 +328,9 @@ files:
325
328
  - lib/serialbench/serializers/json/oj_serializer.rb
326
329
  - lib/serialbench/serializers/json/rapidjson_serializer.rb
327
330
  - lib/serialbench/serializers/json/yajl_serializer.rb
331
+ - lib/serialbench/serializers/json/yeptris_serializer.rb
328
332
  - lib/serialbench/serializers/toml/base_toml_serializer.rb
333
+ - lib/serialbench/serializers/toml/teptris_serializer.rb
329
334
  - lib/serialbench/serializers/toml/toml_rb_serializer.rb
330
335
  - lib/serialbench/serializers/toml/tomlib_serializer.rb
331
336
  - lib/serialbench/serializers/toml/tomlrb_serializer.rb
@@ -339,6 +344,7 @@ files:
339
344
  - lib/serialbench/serializers/yaml/base_yaml_serializer.rb
340
345
  - lib/serialbench/serializers/yaml/psych_serializer.rb
341
346
  - lib/serialbench/serializers/yaml/syck_serializer.rb
347
+ - lib/serialbench/serializers/yaml/yeptris_serializer.rb
342
348
  - lib/serialbench/test_data.rb
343
349
  - lib/serialbench/version.rb
344
350
  - lib/serialbench/yaml_validator.rb