plain.go (2121B)
1 // Copyright 2013 TLH and dsp. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package mapfs 6 7 import ( 8 "bytes" 9 "fmt" 10 "io/ioutil" 11 "os" 12 ) 13 14 type PlainMap struct { 15 cache map[int]plainVal 16 } 17 18 type plainVal struct { 19 dirty bool 20 buf []byte // Actual raw data 21 siz int // Size of raw data 22 } 23 24 func NewPlainMap() *PlainMap { 25 return &PlainMap{ 26 cache: make(map[int]plainVal), 27 } 28 } 29 30 func (p *PlainMap) rawRead(path string) ([]byte, error) { 31 b, err := ioutil.ReadFile(path) 32 if err != nil { 33 return nil, err 34 } 35 return b, err 36 } 37 38 func (p *PlainMap) rawWrite(path string, buf []byte) error { 39 _, err := os.Stat(path) 40 if err == nil { 41 return fmt.Errorf("File %s already exists", path) 42 } 43 err = ioutil.WriteFile(path, buf, 0644) 44 if err != nil { 45 return err 46 } 47 return nil 48 } 49 50 func (p *PlainMap) get(key int) ([]byte, error) { 51 val, ok := p.cache[key] 52 if !ok { 53 return nil, fmt.Errorf("No entry with key: %d", key) 54 } 55 return val.buf, nil 56 } 57 58 func (p *PlainMap) put(key int, buf []byte) error { 59 _, ok := p.cache[key] 60 if ok { 61 return fmt.Errorf("Key %d already in use", key) 62 } 63 p.cache[key] = plainVal{true, buf, len(buf)} 64 return nil 65 } 66 67 func (p *PlainMap) add(buf []byte) (int, error) { 68 key := len(p.cache) 69 p.cache[key] = plainVal{true, buf, len(buf)} 70 return key, nil 71 } 72 73 func (p *PlainMap) countMatches(buf []byte) int { 74 i := 0 75 for _, v := range p.cache { 76 if bytes.Equal(v.buf, buf) { 77 i++ 78 } 79 } 80 return i 81 } 82 83 func (p *PlainMap) virtSync() error { 84 for k, v := range p.cache { 85 p.cache[k] = plainVal{false, v.buf, v.siz} 86 } 87 return nil 88 } 89 90 func (p *PlainMap) syncEntry(path string, key int) error { 91 val, ok := p.cache[key] 92 if !ok { 93 return fmt.Errorf("No entry with key: %d", key) 94 } 95 if val.dirty { 96 p.rawWrite(path, val.buf) 97 } 98 return nil 99 } 100 101 func (p *PlainMap) size() int { 102 return len(p.cache) 103 } 104 105 func (p *PlainMap) string() string { 106 s := "" 107 for k, v := range p.cache { 108 dirty := "" 109 if v.dirty { 110 dirty = "yes" 111 } else { 112 dirty = "no" 113 } 114 s += fmt.Sprintf("k: %d - dirty: %s\n", 115 k, dirty) 116 } 117 return s 118 }