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  }