github.com/scottcagno/storage@v1.8.0/pkg/_se/engine.go (about)

     1  package _se
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"path/filepath"
     8  )
     9  
    10  const (
    11  	pageSize = 64
    12  )
    13  
    14  func align(size, mask int) int {
    15  	return (size + mask) &^ (mask)
    16  }
    17  
    18  type span struct {
    19  	start int
    20  	end   int
    21  }
    22  
    23  type engine struct {
    24  	fp    *os.File
    25  	size  int64
    26  	index []int64
    27  }
    28  
    29  func openFile(path string) (*os.File, error) {
    30  	// sanitize base path
    31  	path, err := filepath.Abs(path)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	// sanitize any path separators
    36  	path = filepath.ToSlash(path)
    37  	// get dir
    38  	dir, _ := filepath.Split(path)
    39  	// create any directories if they are not there
    40  	err = os.MkdirAll(dir, os.ModeDir)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	// open file
    45  	f, err := os.OpenFile(path, os.O_CREATE, 0666)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	return f, err
    50  }
    51  
    52  func openEngine(path string) (*engine, error) {
    53  	// open file
    54  	f, err := openFile(path)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	// get file size
    59  	fi, err := f.Stat()
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  	// init engine
    64  	e := &engine{
    65  		fp:    f,
    66  		size:  fi.Size(),
    67  		index: make([]int64, 0, 64),
    68  	}
    69  	// setup engine
    70  	err = e.setup()
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  	// return engine
    75  	return e, nil
    76  }
    77  
    78  func (e *engine) setup() error {
    79  	if e.size < 1 {
    80  		return nil
    81  	}
    82  	var i int
    83  	for {
    84  		off, err := e.fp.Seek(0, io.SeekCurrent)
    85  		if err != nil {
    86  			return err
    87  		}
    88  		rec, err := e.read()
    89  		if err != nil {
    90  			if err == io.EOF || err == io.ErrUnexpectedEOF {
    91  				break
    92  			}
    93  			return err
    94  		}
    95  		fmt.Printf("%s\n\n", rec)
    96  		if rec.header.magic != magicIdent {
    97  			continue
    98  		}
    99  		e.index = append(e.index, off)
   100  		i++
   101  		fmt.Println(i)
   102  	}
   103  	return nil
   104  }
   105  
   106  func (e *engine) write(rec *record) (int, error) {
   107  	n, err := rec.write(e.fp)
   108  	if err != nil {
   109  		return n, err
   110  	}
   111  	return n, nil
   112  }
   113  
   114  func (e *engine) writeAt(rec *record, page int) (int, error) {
   115  	return 0, nil
   116  }
   117  
   118  func (e *engine) read() (*record, error) {
   119  	r := new(record)
   120  	_, err := r.read(e.fp)
   121  	if err != nil {
   122  		return nil, err
   123  	}
   124  	return r, nil
   125  }
   126  
   127  func (e *engine) readAt(data []byte, offset int64) (int, error) {
   128  
   129  	return 0, nil
   130  }
   131  
   132  func (e *engine) seek(off int64, whence int) (int64, error) {
   133  	return 0, nil
   134  }
   135  
   136  func (e *engine) flush() error {
   137  	err := e.fp.Sync()
   138  	if err != nil {
   139  		return err
   140  	}
   141  	return nil
   142  }
   143  
   144  func (e *engine) close() error {
   145  	err := e.fp.Sync()
   146  	if err != nil {
   147  		return err
   148  	}
   149  	err = e.fp.Close()
   150  	if err != nil {
   151  		return err
   152  	}
   153  	return nil
   154  }