github.com/scottcagno/storage@v1.8.0/pkg/lsmtree/channelsearch.go (about)

     1  package lsmtree
     2  
     3  //wasnt' really sure where you wanted me to put this, I hope here is ok
     4  //I just copy/pasted from playground, I'll be cleaning this up then
     5  
     6  import (
     7  	"fmt"
     8  	"sync"
     9  )
    10  
    11  //this is a placeholder for an actual directory
    12  type myDir struct {
    13  	files []*myFile
    14  }
    15  
    16  //placeholder for an actual file
    17  type myFile struct {
    18  	data []*myEntry
    19  }
    20  
    21  //just going to search int for now
    22  type myEntry struct {
    23  	value int
    24  }
    25  
    26  //This is just a quick search function I whipped up for an example, it would
    27  //be replaced by whatever search function you're currently using for the sstable.
    28  //Once I get this into my IDE I'll implement something that actually works with files.
    29  func search(f *myFile, i int, c chan *myEntry, wg *sync.WaitGroup) {
    30  	for _, v := range f.data {
    31  		if v.value == i {
    32  			c <- v
    33  			wg.Done()
    34  			return
    35  		}
    36  	}
    37  	wg.Done()
    38  	return
    39  }
    40  
    41  //I'm not sure what the input parameter will be, I'm assuming we'll be searching a
    42  //directory, but for now I'm just building very simply
    43  func channelSearch(d *myDir, i int) (*myEntry, error) {
    44  	//this is the channel we'll be receiving data on
    45  	c := make(chan *myEntry)
    46  	//the wait group will tell us when all the concurrent search functions are over
    47  	wg := &sync.WaitGroup{}
    48  
    49  	//I think this will make the search function faster by making the function
    50  	//call concurrent. Specifically, this should make a huge difference when
    51  	//the entry is found in one of the first few files
    52  	wg.Add(len(d.files))
    53  
    54  	//now we can make this part concurrent
    55  	go func() {
    56  		for _, f := range d.files {
    57  			go search(f, i, c, wg)
    58  		}
    59  	}()
    60  
    61  	//close c if all searches finish without returning a value
    62  	go func() {
    63  		wg.Wait()
    64  		close(c)
    65  		return
    66  	}()
    67  
    68  	//now this blocks the return until either the index is found
    69  	//or the channel is closed
    70  	for {
    71  		v, ok := <-c
    72  		if ok != true { //if we've closed the channel
    73  			break
    74  		}
    75  		return v, nil
    76  	}
    77  
    78  	//I should really put the wg blocking operation here, just gotta wrap my head around the logistics first
    79  
    80  	return &myEntry{}, fmt.Errorf("Not Found")
    81  
    82  }
    83  
    84  //linear search to benchmark beside
    85  func linearSearch(d *myDir, i int) (int, error) {
    86  	for _, f := range d.files {
    87  		for _, e := range f.data {
    88  			if e.value == i {
    89  				return i, nil
    90  			}
    91  		}
    92  	}
    93  	return -1, fmt.Errorf("Not found")
    94  }