LCOV - code coverage report
Current view: top level - pebble/metamorphic - diagram.go (source / functions) Hit Total Coverage
Test: 2025-01-02 08:16Z f87b4ded - meta test only.lcov Lines: 0 67 0.0 %
Date: 2025-01-02 08:18:22 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2024 The LevelDB-Go and Pebble Authors. All rights reserved. Use
       2             : // of this source code is governed by a BSD-style license that can be found in
       3             : // the LICENSE file.
       4             : 
       5             : package metamorphic
       6             : 
       7             : import "strings"
       8             : 
       9             : // TryToGenerateDiagram attempts to generate a user-readable ASCII diagram of
      10             : // the keys involved in the operations.
      11             : //
      12             : // If the diagram would be too large to be practical, returns the empty string
      13             : // (with no error).
      14           0 : func TryToGenerateDiagram(keyFormat KeyFormat, opsData []byte) (string, error) {
      15           0 :         ops, err := parse(opsData, parserOpts{
      16           0 :                 parseFormattedUserKey:       keyFormat.ParseFormattedKey,
      17           0 :                 parseFormattedUserKeySuffix: keyFormat.ParseFormattedKeySuffix,
      18           0 :         })
      19           0 :         if err != nil {
      20           0 :                 return "", err
      21           0 :         }
      22           0 :         if len(ops) > 200 {
      23           0 :                 return "", nil
      24           0 :         }
      25           0 :         keySet := make(map[string]struct{})
      26           0 :         for _, o := range ops {
      27           0 :                 for _, r := range o.diagramKeyRanges() {
      28           0 :                         keySet[string(r.Start)] = struct{}{}
      29           0 :                         keySet[string(r.End)] = struct{}{}
      30           0 :                 }
      31             :         }
      32           0 :         if len(keySet) == 0 {
      33           0 :                 return "", nil
      34           0 :         }
      35           0 :         keys := sortedKeys(keyFormat.Comparer.Compare, keySet)
      36           0 :         axis1, axis2, pos := genAxis(keys)
      37           0 :         if len(axis1) > 200 {
      38           0 :                 return "", nil
      39           0 :         }
      40             : 
      41           0 :         var rows []string
      42           0 :         for _, o := range ops {
      43           0 :                 ranges := o.diagramKeyRanges()
      44           0 :                 var row strings.Builder
      45           0 :                 for _, r := range ranges {
      46           0 :                         s := pos[string(r.Start)]
      47           0 :                         e := pos[string(r.End)]
      48           0 :                         for row.Len() < s {
      49           0 :                                 row.WriteByte(' ')
      50           0 :                         }
      51           0 :                         row.WriteByte('|')
      52           0 :                         if e > s {
      53           0 :                                 for row.Len() < e {
      54           0 :                                         row.WriteByte('-')
      55           0 :                                 }
      56           0 :                                 row.WriteByte('|')
      57             :                         }
      58             :                 }
      59           0 :                 for row.Len() <= len(axis1) {
      60           0 :                         row.WriteByte(' ')
      61           0 :                 }
      62           0 :                 row.WriteString(o.formattedString(keyFormat))
      63           0 : 
      64           0 :                 rows = append(rows, row.String())
      65             :         }
      66           0 :         rows = append(rows, axis1, axis2)
      67           0 :         return strings.Join(rows, "\n"), nil
      68             : }
      69             : 
      70             : // genAxis generates the horizontal key axis and returns two rows (one for axis
      71             : // one for labels), along with a map from key to column.
      72             : 
      73             : // Example:
      74             : //
      75             : //      axisRow:    |----|----|----|
      76             : //      labelRow:   a    bar  foo  zed
      77             : //      pos:        a:0, bar:5, foo:10, zed:15
      78           0 : func genAxis(keys []string) (axisRow string, labelRow string, pos map[string]int) {
      79           0 :         const minSpaceBetweenKeys = 4
      80           0 :         const minSpaceBetweenKeyLabels = 2
      81           0 :         var a, b strings.Builder
      82           0 :         pos = make(map[string]int)
      83           0 :         for i, k := range keys {
      84           0 :                 if i > 0 {
      85           0 :                         b.WriteString(strings.Repeat(" ", minSpaceBetweenKeyLabels))
      86           0 :                         for b.Len() <= a.Len()+minSpaceBetweenKeys {
      87           0 :                                 b.WriteByte(' ')
      88           0 :                         }
      89           0 :                         for a.Len() < b.Len() {
      90           0 :                                 a.WriteByte('-')
      91           0 :                         }
      92             :                 }
      93           0 :                 pos[k] = a.Len()
      94           0 :                 a.WriteByte('|')
      95           0 :                 b.WriteString(k)
      96             :         }
      97           0 :         return a.String(), b.String(), pos
      98             : }

Generated by: LCOV version 1.14