github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/sstable/writer_test.go (about) 1 // Copyright 2018 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 sstable 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "strings" 12 "testing" 13 14 "github.com/petermattis/pebble/internal/base" 15 "github.com/petermattis/pebble/internal/datadriven" 16 "github.com/petermattis/pebble/internal/rangedel" 17 "github.com/petermattis/pebble/vfs" 18 ) 19 20 func TestWriter(t *testing.T) { 21 var r *Reader 22 datadriven.RunTest(t, "testdata/writer", func(td *datadriven.TestData) string { 23 switch td.Cmd { 24 case "build": 25 if r != nil { 26 _ = r.Close() 27 r = nil 28 } 29 30 mem := vfs.NewMem() 31 f0, err := mem.Create("test") 32 if err != nil { 33 return err.Error() 34 } 35 36 w := NewWriter(f0, nil, TableOptions{}) 37 var tombstones []rangedel.Tombstone 38 f := rangedel.Fragmenter{ 39 Cmp: DefaultComparer.Compare, 40 Emit: func(fragmented []rangedel.Tombstone) { 41 tombstones = append(tombstones, fragmented...) 42 }, 43 } 44 for _, data := range strings.Split(td.Input, "\n") { 45 j := strings.Index(data, ":") 46 key := base.ParseInternalKey(data[:j]) 47 value := []byte(data[j+1:]) 48 switch key.Kind() { 49 case InternalKeyKindRangeDelete: 50 var err error 51 func() { 52 defer func() { 53 if r := recover(); r != nil { 54 err = errors.New(fmt.Sprint(r)) 55 } 56 }() 57 f.Add(key, value) 58 }() 59 if err != nil { 60 return err.Error() 61 } 62 default: 63 if err := w.Add(key, value); err != nil { 64 return err.Error() 65 } 66 } 67 } 68 f.Finish() 69 for _, v := range tombstones { 70 if err := w.Add(v.Start, v.End); err != nil { 71 return err.Error() 72 } 73 } 74 if err := w.Close(); err != nil { 75 return err.Error() 76 } 77 meta, err := w.Metadata() 78 if err != nil { 79 return err.Error() 80 } 81 82 f1, err := mem.Open("test") 83 if err != nil { 84 return err.Error() 85 } 86 r, err = NewReader(f1, 0, 0, nil) 87 if err != nil { 88 return err.Error() 89 } 90 return fmt.Sprintf("point: [%s,%s]\nrange: [%s,%s]\nseqnums: [%d,%d]\n", 91 meta.SmallestPoint, meta.LargestPoint, 92 meta.SmallestRange, meta.LargestRange, 93 meta.SmallestSeqNum, meta.LargestSeqNum) 94 95 case "build-raw": 96 if r != nil { 97 _ = r.Close() 98 r = nil 99 } 100 101 mem := vfs.NewMem() 102 f0, err := mem.Create("test") 103 if err != nil { 104 return err.Error() 105 } 106 107 w := NewWriter(f0, nil, TableOptions{}) 108 for i := range td.CmdArgs { 109 arg := &td.CmdArgs[i] 110 if arg.Key == "range-del-v1" { 111 w.rangeDelV1Format = true 112 break 113 } 114 } 115 116 for _, data := range strings.Split(td.Input, "\n") { 117 j := strings.Index(data, ":") 118 key := base.ParseInternalKey(data[:j]) 119 value := []byte(data[j+1:]) 120 if err := w.Add(key, value); err != nil { 121 return err.Error() 122 } 123 } 124 if err := w.Close(); err != nil { 125 return err.Error() 126 } 127 meta, err := w.Metadata() 128 if err != nil { 129 return err.Error() 130 } 131 132 f1, err := mem.Open("test") 133 if err != nil { 134 return err.Error() 135 } 136 r, err = NewReader(f1, 0, 0, nil) 137 if err != nil { 138 return err.Error() 139 } 140 return fmt.Sprintf("point: [%s,%s]\nrange: [%s,%s]\nseqnums: [%d,%d]\n", 141 meta.SmallestPoint, meta.LargestPoint, 142 meta.SmallestRange, meta.LargestRange, 143 meta.SmallestSeqNum, meta.LargestSeqNum) 144 145 case "scan": 146 iter := iterAdapter{r.NewIter(nil /* lower */, nil /* upper */)} 147 defer iter.Close() 148 149 var buf bytes.Buffer 150 for valid := iter.First(); valid; valid = iter.Next() { 151 fmt.Fprintf(&buf, "%s:%s\n", iter.Key(), iter.Value()) 152 } 153 return buf.String() 154 155 case "scan-range-del": 156 iter := r.NewRangeDelIter() 157 if iter == nil { 158 return "" 159 } 160 defer iter.Close() 161 162 var buf bytes.Buffer 163 for key, val := iter.First(); key != nil; key, val = iter.Next() { 164 fmt.Fprintf(&buf, "%s:%s\n", key, val) 165 } 166 return buf.String() 167 168 default: 169 return fmt.Sprintf("unknown command: %s", td.Cmd) 170 } 171 }) 172 }