@@ -2,9 +2,14 @@ package simpledb
22
33import (
44 "fmt"
5+ "os"
6+ "path/filepath"
7+ "testing"
8+
59 "github.com/stretchr/testify/assert"
10+ "github.com/thomasjungblut/go-sstables/memstore"
11+ "github.com/thomasjungblut/go-sstables/sstables"
612 "github.com/thomasjungblut/go-sstables/sstables/proto"
7- "testing"
813)
914
1015func TestExecCompactionLessFilesThanExpected (t * testing.T ) {
@@ -47,3 +52,93 @@ func TestExecCompactionSameContent(t *testing.T) {
4752 // for cleanups
4853 assert .Nil (t , db .sstableManager .currentReader .Close ())
4954}
55+
56+ func writeSSTableWithDataInDatabaseFolder (t * testing.T , db * DB , p string ) {
57+ fakeTablePath := filepath .Join (db .basePath , p )
58+ assert .Nil (t , os .MkdirAll (fakeTablePath , 0700 ))
59+ mStore := memstore .NewMemStore ()
60+ for i := 0 ; i < 1000 ; i ++ {
61+ assert .Nil (t , mStore .Add ([]byte (fmt .Sprintf ("%d" , i )), []byte (fmt .Sprintf ("%d" , i ))))
62+ }
63+ assert .Nil (t , mStore .Flush (
64+ sstables .WriteBasePath (fakeTablePath ),
65+ sstables .WithKeyComparator (db .cmp ),
66+ ))
67+ }
68+
69+ func writeSSTableWithTombstoneInDatabaseFolder (t * testing.T , db * DB , p string ) {
70+ fakeTablePath := filepath .Join (db .basePath , p )
71+ assert .Nil (t , os .MkdirAll (fakeTablePath , 0700 ))
72+ mStore := memstore .NewMemStore ()
73+
74+ // delete all key between 500 and 800
75+ for i := 500 ; i < 800 ; i ++ {
76+ assert .Nil (t , mStore .Tombstone ([]byte (fmt .Sprintf ("%d" , i ))))
77+ }
78+ assert .Nil (t , mStore .FlushWithTombstones (
79+ sstables .WriteBasePath (fakeTablePath ),
80+ sstables .WithKeyComparator (db .cmp ),
81+ ))
82+ }
83+
84+ func TestExecCompactionWithTombstone (t * testing.T ) {
85+ db := newOpenedSimpleDB (t , "simpledb_compactionSameContent" )
86+ defer cleanDatabaseFolder (t , db )
87+ // we'll close the database to mock some internals directly, yes it's very hacky
88+ closeDatabase (t , db )
89+ db .closed = false
90+ db .compactionThreshold = 0
91+
92+ writeSSTableWithDataInDatabaseFolder (t , db , fmt .Sprintf (SSTablePattern , 42 ))
93+ // only one SStable with holes should shrink
94+ writeSSTableWithTombstoneInDatabaseFolder (t , db , fmt .Sprintf (SSTablePattern , 43 ))
95+ assert .Nil (t , db .reconstructSSTables ())
96+ // 1000 initial + 300 Tombstone on second table
97+ assert .Equal (t , 1300 , int (db .sstableManager .currentSSTable ().MetaData ().GetNumRecords ()))
98+
99+ compactionMeta , err := executeCompaction (db )
100+ assert .Nil (t , err )
101+ assert .Equal (t , "sstable_000000000000042" , compactionMeta .ReplacementPath )
102+ assert .Equal (t , []string {"sstable_000000000000042" , "sstable_000000000000043" }, compactionMeta .SstablePaths )
103+ fmt .Print (compactionMeta )
104+ err = db .sstableManager .reflectCompactionResult (compactionMeta )
105+ assert .NoError (t , err )
106+ v , err := db .Get ("512" )
107+ assert .ErrorIs (t , err , ErrNotFound )
108+ assert .Equal (t , "" , v )
109+ // for cleanups
110+ assert .Nil (t , db .sstableManager .currentReader .Close ())
111+
112+ // check size of compacted sstable
113+ assert .Equal (t , 700 , int (db .sstableManager .currentSSTable ().MetaData ().NumRecords ))
114+ }
115+ func TestExecCompactionWithTombstoneRewriten (t * testing.T ) {
116+ db := newOpenedSimpleDB (t , "simpledb_compactionSameContent" )
117+ defer cleanDatabaseFolder (t , db )
118+ // we'll close the database to mock some internals directly, yes it's very hacky
119+ closeDatabase (t , db )
120+ db .closed = false
121+ db .compactionThreshold = 0
122+
123+ writeSSTableWithTombstoneInDatabaseFolder (t , db , fmt .Sprintf (SSTablePattern , 42 ))
124+ // the tombstone are overwrite
125+ writeSSTableWithDataInDatabaseFolder (t , db , fmt .Sprintf (SSTablePattern , 43 ))
126+ assert .Nil (t , db .reconstructSSTables ())
127+ assert .Equal (t , 1300 , int (db .sstableManager .currentSSTable ().MetaData ().GetNumRecords ()))
128+
129+ compactionMeta , err := executeCompaction (db )
130+ assert .Nil (t , err )
131+ assert .Equal (t , "sstable_000000000000042" , compactionMeta .ReplacementPath )
132+ assert .Equal (t , []string {"sstable_000000000000042" , "sstable_000000000000043" }, compactionMeta .SstablePaths )
133+ fmt .Print (compactionMeta )
134+ err = db .sstableManager .reflectCompactionResult (compactionMeta )
135+ assert .NoError (t , err )
136+ v , err := db .Get ("512" )
137+ assert .NoError (t , err )
138+ assert .Equal (t , "512" , v )
139+ // for cleanups
140+ assert .Nil (t , db .sstableManager .currentReader .Close ())
141+
142+ // check size of compacted sstable
143+ assert .Equal (t , 1000 , int (db .sstableManager .currentSSTable ().MetaData ().NumRecords ))
144+ }
0 commit comments