imposm3/cache/nodes.go

107 lines
2.1 KiB
Go
Raw Permalink Normal View History

2013-05-17 17:30:22 +04:00
package cache
import (
"github.com/jmhodges/levigo"
2014-08-04 17:19:35 +04:00
"github.com/omniscale/imposm3/cache/binary"
"github.com/omniscale/imposm3/element"
2013-05-17 17:30:22 +04:00
)
type NodesCache struct {
2013-07-04 19:27:22 +04:00
cache
2013-05-17 17:30:22 +04:00
}
2013-07-04 19:27:22 +04:00
func newNodesCache(path string) (*NodesCache, error) {
2013-05-17 17:30:22 +04:00
cache := NodesCache{}
2013-07-04 19:27:22 +04:00
cache.options = &globalCacheOptions.Nodes
2013-05-17 17:30:22 +04:00
err := cache.open(path)
if err != nil {
return nil, err
}
return &cache, err
}
func (p *NodesCache) PutNode(node *element.Node) error {
2013-11-04 11:51:21 +04:00
if node.Id == SKIP {
return nil
}
2013-05-17 17:30:22 +04:00
if node.Tags == nil {
return nil
}
keyBuf := idToKeyBuf(node.Id)
data, err := binary.MarshalNode(node)
if err != nil {
return err
}
return p.db.Put(p.wo, keyBuf, data)
}
func (p *NodesCache) PutNodes(nodes []element.Node) (int, error) {
batch := levigo.NewWriteBatch()
defer batch.Close()
var n int
for _, node := range nodes {
2013-11-04 11:51:21 +04:00
if node.Id == SKIP {
continue
}
2013-05-17 17:30:22 +04:00
if len(node.Tags) == 0 {
continue
}
keyBuf := idToKeyBuf(node.Id)
data, err := binary.MarshalNode(&node)
if err != nil {
return 0, err
}
batch.Put(keyBuf, data)
n += 1
}
return n, p.db.Write(p.wo, batch)
}
func (p *NodesCache) GetNode(id int64) (*element.Node, error) {
keyBuf := idToKeyBuf(id)
data, err := p.db.Get(p.ro, keyBuf)
if err != nil {
return nil, err
}
if data == nil {
return nil, NotFound
}
node, err := binary.UnmarshalNode(data)
if err != nil {
return nil, err
}
node.Id = id
2013-05-17 17:30:22 +04:00
return node, nil
}
func (p *NodesCache) DeleteNode(id int64) error {
keyBuf := idToKeyBuf(id)
return p.db.Delete(p.wo, keyBuf)
}
2013-05-17 17:30:22 +04:00
func (p *NodesCache) Iter() chan *element.Node {
nodes := make(chan *element.Node)
2013-05-17 17:30:22 +04:00
go func() {
ro := levigo.NewReadOptions()
ro.SetFillCache(false)
it := p.db.NewIterator(ro)
// we need to Close the iter before closing the
// chan (and thus signaling that we are done)
// to avoid race where db is closed before the iterator
2013-11-08 18:03:20 +04:00
defer close(nodes)
2013-05-17 17:30:22 +04:00
defer it.Close()
it.SeekToFirst()
for ; it.Valid(); it.Next() {
node, err := binary.UnmarshalNode(it.Value())
2013-05-17 17:30:22 +04:00
if err != nil {
panic(err)
}
node.Id = idFromKeyBuf(it.Key())
nodes <- node
2013-05-17 17:30:22 +04:00
}
}()
return nodes
2013-05-17 17:30:22 +04:00
}