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 }