commit 80f5a620c451f25842d994ba2b0a474c7728b5b1
parent a01240a6834260d743ad092573590de66d375fd6
Author: sin <sin@2f30.org>
Date: Sat, 27 Apr 2013 17:45:26 +0100
rename fsdb to mapfs
Diffstat:
4 files changed, 228 insertions(+), 228 deletions(-)
diff --git a/src/fsdb/fsdb.go b/src/fsdb/fsdb.go
@@ -1,223 +0,0 @@
-// Simple filesystem DB
-package fsdb
-
-import (
- "errors"
- "fmt"
- "io/ioutil"
- "math/rand"
- "os"
- "path"
- "path/filepath"
- "strconv"
- "sync"
-)
-
-type Fsdb struct {
- name string
- path string
- prefix string
- dbMap map[int]fsdbVal
- lock sync.Mutex
-}
-
-type fsdbVal struct {
- dirty bool // Do we need to sync this entry to the disk?
- data []byte // Actual raw data
-}
-
-func NewFsdb(name string, path string, prefix string) *Fsdb {
- return &Fsdb{
- name: name,
- path: path,
- prefix: prefix,
- dbMap: make(map[int]fsdbVal),
- }
-}
-
-func (d *Fsdb) fsRead(key int) ([]byte, error) {
- path := fmt.Sprintf("%s/%s%d.txt", d.path, d.prefix, key)
- b, err := ioutil.ReadFile(path)
- if err != nil {
- return nil, err
- }
- return b, err
-}
-
-func (d *Fsdb) fsWrite(key int, buf []byte) error {
- path := fmt.Sprintf("%s/%s%d.txt", d.path, d.prefix, key)
- _, err := os.Stat(path)
- if err == nil {
- return fmt.Errorf("Entry %s already exists in %s db",
- path, d.name)
- }
- err = ioutil.WriteFile(path, buf, 0644)
- if err != nil {
- return err
- }
- return nil
-}
-
-// Sync dirty entries to disk
-func (d *Fsdb) Sync() error {
- d.lock.Lock()
- defer d.lock.Unlock()
- for k, v := range d.dbMap {
- if v.dirty {
- err := d.fsWrite(k, v.data)
- if err != nil {
- return err
- }
- d.dbMap[k] = fsdbVal{false, v.data}
- fmt.Printf("Synced entry (%d, %v)\n",
- k, v.data)
- }
- }
- return nil
-}
-
-// Print DB
-func (d *Fsdb) String() string {
- d.lock.Lock()
- defer d.lock.Unlock()
- s := fmt.Sprintf("*** %s DB DUMP ***\n", d.name)
- for k, v := range d.dbMap {
- dirty := ""
- if v.dirty {
- dirty = "yes"
- } else {
- dirty = "no"
- }
- s += fmt.Sprintf("k: %d - dirty: %s\n",
- k, dirty)
- }
- return s
-}
-
-// Mark all entries as synced but do not actually write them out to disk
-func (d *Fsdb) virtSync() {
- d.lock.Lock()
- defer d.lock.Unlock()
- for k, v := range d.dbMap {
- d.dbMap[k] = fsdbVal{false, v.data}
- }
-}
-
-// Load the DB from disk
-func (d *Fsdb) Load() error {
- _, err := os.Stat(d.path)
- if err != nil {
- // Just create the db if it does not exist
- return os.MkdirAll(d.path, 0755)
- }
- walkFunc := func(p string, fi os.FileInfo, err error) error {
- if fi.IsDir() {
- return nil
- }
- if err != nil {
- return err
- }
- base, ext := path.Base(p), path.Ext(p)
- entry := base[len(d.prefix) : len(base)-len(ext)]
- i, err := strconv.Atoi(entry)
- if err != nil {
- return err
- }
- b, err := d.fsRead(i)
- if err != nil {
- return err
- }
- if d.Dup(b) {
- return fmt.Errorf("Duplicate entry: %s", b)
- }
- err = d.Put(i, b)
- if err != nil {
- return err
- }
- return nil
- }
- err = filepath.Walk(d.path, walkFunc)
- if err == nil {
- d.virtSync()
- }
- return err
-}
-
-// Check if `buf' already exists in the DB
-// Expects `d.lock' to be held by caller
-func (d *Fsdb) Dup(buf []byte) bool {
- d.lock.Lock()
- defer d.lock.Unlock()
- for _, v := range d.dbMap {
- if string(v.data) == string(buf) {
- return true
- }
- }
- return false
-}
-
-func (d *Fsdb) Put(key int, buf []byte) error {
- d.lock.Lock()
- defer d.lock.Unlock()
- if key < 0 {
- return fmt.Errorf("Invalid key: %d", key)
- }
- _, ok := d.dbMap[key]
- if ok {
- return fmt.Errorf("Key %d already in use", key)
- }
- d.dbMap[key] = fsdbVal{true, buf}
- return nil
-}
-
-// Append buf into the DB
-func (d *Fsdb) Append(buf []byte) (int, error) {
- d.lock.Lock()
- defer d.lock.Unlock()
- d.dbMap[len(d.dbMap)] = fsdbVal{true, buf}
- return -1, nil
-}
-
-// Return the raw data based on the key
-func (d *Fsdb) Get(key int) ([]byte, error) {
- d.lock.Lock()
- defer d.lock.Unlock()
- if len(d.dbMap) == 0 {
- return nil, errors.New("Empty DB, can't fetch entry")
- }
- val, ok := d.dbMap[key]
- if !ok {
- return nil, fmt.Errorf("No entry with key: %d", key)
- }
- return val.data, nil
-}
-
-func (d *Fsdb) Rand() ([]byte, int) {
- d.lock.Lock()
- defer d.lock.Unlock()
- idx := rand.Intn(len(d.dbMap))
- i := 0
- for k, _ := range d.dbMap {
- if i == idx {
- val := d.dbMap[k]
- return val.data, k
- }
- i++
- }
- return nil, -1
-}
-
-func (d *Fsdb) Empty() bool {
- d.lock.Lock()
- defer d.lock.Unlock()
- if len(d.dbMap) == 0 {
- return true
- }
- return false
-}
-
-func (d *Fsdb) Len() int {
- d.lock.Lock()
- defer d.lock.Unlock()
- return len(d.dbMap)
-}
diff --git a/src/kunt/kunt.go b/src/kunt/kunt.go
@@ -4,11 +4,11 @@ import (
"bytes"
"flag"
"fmt"
- "fsdb"
"games"
"io/ioutil"
"irc"
"log"
+ "mapfs"
"math/rand"
"net/http"
"os"
@@ -260,8 +260,8 @@ func cmdGame(msg irc.IrcMessage) {
var sslon = flag.Bool("s", false, "SSL support")
-var quoteDb *fsdb.Fsdb
-var urlDb *fsdb.Fsdb
+var quoteDb *mapfs.Mapfs
+var urlDb *mapfs.Mapfs
var kunt kuntCtx
var geng games.GameEnger
var botname string
@@ -281,8 +281,8 @@ func main() {
hostport := strings.Split(flag.Arg(0), ":")
- quoteDb = fsdb.NewFsdb("Quotes", "db/quotes", "quote")
- urlDb = fsdb.NewFsdb("Urls", "db/urls", "url")
+ quoteDb = mapfs.NewMapfs("Quotes", "db/quotes", "quote")
+ urlDb = mapfs.NewMapfs("Urls", "db/urls", "url")
err := quoteDb.Load()
if err != nil {
diff --git a/src/fsdb/TODO b/src/mapfs/TODO
diff --git a/src/mapfs/mapfs.go b/src/mapfs/mapfs.go
@@ -0,0 +1,223 @@
+// Simple fs backed up dictionary implementation
+package mapfs
+
+import (
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "math/rand"
+ "os"
+ "path"
+ "path/filepath"
+ "strconv"
+ "sync"
+)
+
+type Mapfs struct {
+ name string
+ path string
+ prefix string
+ dict map[int]mapfsVal
+ lock sync.Mutex
+}
+
+type mapfsVal struct {
+ dirty bool // Do we need to sync this entry to the disk?
+ data []byte // Actual raw data
+}
+
+func NewMapfs(name string, path string, prefix string) *Mapfs {
+ return &Mapfs{
+ name: name,
+ path: path,
+ prefix: prefix,
+ dict: make(map[int]mapfsVal),
+ }
+}
+
+func (m *Mapfs) fsRead(key int) ([]byte, error) {
+ path := fmt.Sprintf("%s/%s%d.txt", m.path, m.prefix, key)
+ b, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+ return b, err
+}
+
+func (m *Mapfs) fsWrite(key int, buf []byte) error {
+ path := fmt.Sprintf("%s/%s%d.txt", m.path, m.prefix, key)
+ _, err := os.Stat(path)
+ if err == nil {
+ return fmt.Errorf("Entry %s already exists in %s db",
+ path, m.name)
+ }
+ err = ioutil.WriteFile(path, buf, 0644)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// Sync dirty entries to disk
+func (m *Mapfs) Sync() error {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ for k, v := range m.dict {
+ if v.dirty {
+ err := m.fsWrite(k, v.data)
+ if err != nil {
+ return err
+ }
+ m.dict[k] = mapfsVal{false, v.data}
+ fmt.Printf("Synced entry (%d, %v)\n",
+ k, v.data)
+ }
+ }
+ return nil
+}
+
+// Print map
+func (m *Mapfs) String() string {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ s := fmt.Sprintf("*** %s MAP DUMP ***\n", m.name)
+ for k, v := range m.dict {
+ dirty := ""
+ if v.dirty {
+ dirty = "yes"
+ } else {
+ dirty = "no"
+ }
+ s += fmt.Sprintf("k: %d - dirty: %s\n",
+ k, dirty)
+ }
+ return s
+}
+
+// Mark all entries as synced but do not actually write them out to disk
+func (m *Mapfs) virtSync() {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ for k, v := range m.dict {
+ m.dict[k] = mapfsVal{false, v.data}
+ }
+}
+
+// Load the map from disk
+func (m *Mapfs) Load() error {
+ _, err := os.Stat(m.path)
+ if err != nil {
+ // Just create the db if it does not exist
+ return os.MkdirAll(m.path, 0755)
+ }
+ walkFunc := func(p string, fi os.FileInfo, err error) error {
+ if fi.IsDir() {
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+ base, ext := path.Base(p), path.Ext(p)
+ entry := base[len(m.prefix) : len(base)-len(ext)]
+ i, err := strconv.Atoi(entry)
+ if err != nil {
+ return err
+ }
+ b, err := m.fsRead(i)
+ if err != nil {
+ return err
+ }
+ if m.Dup(b) {
+ return fmt.Errorf("Duplicate entry: %s", b)
+ }
+ err = m.Put(i, b)
+ if err != nil {
+ return err
+ }
+ return nil
+ }
+ err = filepath.Walk(m.path, walkFunc)
+ if err == nil {
+ m.virtSync()
+ }
+ return err
+}
+
+// Check if `buf' already exists in the map
+func (m *Mapfs) Dup(buf []byte) bool {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ for _, v := range m.dict {
+ if string(v.data) == string(buf) {
+ return true
+ }
+ }
+ return false
+}
+
+func (m *Mapfs) Put(key int, buf []byte) error {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ if key < 0 {
+ return fmt.Errorf("Invalid key: %d", key)
+ }
+ _, ok := m.dict[key]
+ if ok {
+ return fmt.Errorf("Key %d already in use", key)
+ }
+ m.dict[key] = mapfsVal{true, buf}
+ return nil
+}
+
+// Append buf to the map
+func (m *Mapfs) Append(buf []byte) (int, error) {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ key := len(m.dict)
+ m.dict[key] = mapfsVal{true, buf}
+ return key, nil
+}
+
+// Return the raw data based on the key
+func (m *Mapfs) Get(key int) ([]byte, error) {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ if len(m.dict) == 0 {
+ return nil, errors.New("Empty map, can't fetch entry")
+ }
+ val, ok := m.dict[key]
+ if !ok {
+ return nil, fmt.Errorf("No entry with key: %d", key)
+ }
+ return val.data, nil
+}
+
+func (m *Mapfs) Rand() ([]byte, int) {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ idx := rand.Intn(len(m.dict))
+ i := 0
+ for k, _ := range m.dict {
+ if i == idx {
+ val := m.dict[k]
+ return val.data, k
+ }
+ i++
+ }
+ return nil, -1
+}
+
+func (m *Mapfs) Empty() bool {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ if len(m.dict) == 0 {
+ return true
+ }
+ return false
+}
+
+func (m *Mapfs) Len() int {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ return len(m.dict)
+}