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 WaysCache 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 newWaysCache(path string) (*WaysCache, error) {
|
2013-05-17 17:30:22 +04:00
|
|
|
cache := WaysCache{}
|
2013-07-04 19:27:22 +04:00
|
|
|
cache.options = &globalCacheOptions.Ways
|
2013-05-17 17:30:22 +04:00
|
|
|
err := cache.open(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &cache, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *WaysCache) PutWay(way *element.Way) error {
|
2013-11-12 12:21:17 +04:00
|
|
|
if way.Id == SKIP {
|
|
|
|
return nil
|
|
|
|
}
|
2013-05-17 17:30:22 +04:00
|
|
|
keyBuf := idToKeyBuf(way.Id)
|
|
|
|
data, err := binary.MarshalWay(way)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return p.db.Put(p.wo, keyBuf, data)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *WaysCache) PutWays(ways []element.Way) error {
|
|
|
|
batch := levigo.NewWriteBatch()
|
|
|
|
defer batch.Close()
|
|
|
|
|
|
|
|
for _, way := range ways {
|
2013-11-12 12:21:17 +04:00
|
|
|
if way.Id == SKIP {
|
|
|
|
continue
|
|
|
|
}
|
2013-05-17 17:30:22 +04:00
|
|
|
keyBuf := idToKeyBuf(way.Id)
|
|
|
|
data, err := binary.MarshalWay(&way)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
batch.Put(keyBuf, data)
|
|
|
|
}
|
|
|
|
return p.db.Write(p.wo, batch)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *WaysCache) GetWay(id int64) (*element.Way, error) {
|
|
|
|
keyBuf := idToKeyBuf(id)
|
|
|
|
data, err := p.db.Get(p.ro, keyBuf)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if data == nil {
|
|
|
|
return nil, NotFound
|
|
|
|
}
|
|
|
|
way, err := binary.UnmarshalWay(data)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2013-06-05 09:47:28 +04:00
|
|
|
way.Id = id
|
2013-05-17 17:30:22 +04:00
|
|
|
return way, nil
|
|
|
|
}
|
|
|
|
|
2013-07-05 17:14:21 +04:00
|
|
|
func (p *WaysCache) DeleteWay(id int64) error {
|
|
|
|
keyBuf := idToKeyBuf(id)
|
|
|
|
return p.db.Delete(p.wo, keyBuf)
|
|
|
|
}
|
|
|
|
|
2013-06-21 13:05:29 +04:00
|
|
|
func (p *WaysCache) Iter() chan *element.Way {
|
|
|
|
ways := make(chan *element.Way, 1024)
|
2013-05-17 17:30:22 +04:00
|
|
|
go func() {
|
|
|
|
ro := levigo.NewReadOptions()
|
|
|
|
ro.SetFillCache(false)
|
|
|
|
it := p.db.NewIterator(ro)
|
2013-11-08 13:18:14 +04:00
|
|
|
// 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
|
|
|
|
defer close(ways)
|
2013-05-17 17:30:22 +04:00
|
|
|
defer it.Close()
|
|
|
|
it.SeekToFirst()
|
|
|
|
for ; it.Valid(); it.Next() {
|
2013-06-21 13:05:29 +04:00
|
|
|
way, err := binary.UnmarshalWay(it.Value())
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
way.Id = idFromKeyBuf(it.Key())
|
|
|
|
ways <- way
|
2013-05-17 17:30:22 +04:00
|
|
|
}
|
|
|
|
}()
|
2013-06-05 09:47:28 +04:00
|
|
|
return ways
|
2013-05-17 17:30:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (self *WaysCache) FillMembers(members []element.Member) error {
|
|
|
|
if members == nil || len(members) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
for i, member := range members {
|
|
|
|
if member.Type != element.WAY {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
way, err := self.GetWay(member.Id)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
members[i].Way = way
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-01-05 11:56:39 +03:00
|
|
|
func (self *WaysCache) FirstMemberIsCached(members []element.Member) (bool, error) {
|
2013-11-12 12:21:17 +04:00
|
|
|
for _, m := range members {
|
|
|
|
if m.Type == element.WAY {
|
|
|
|
_, err := self.GetWay(m.Id)
|
2015-01-05 11:56:39 +03:00
|
|
|
if err == NotFound {
|
|
|
|
return false, nil
|
|
|
|
}
|
2013-11-12 12:21:17 +04:00
|
|
|
if err != nil {
|
2015-01-05 11:56:39 +03:00
|
|
|
return false, err
|
2013-11-12 12:21:17 +04:00
|
|
|
}
|
2015-01-05 11:56:39 +03:00
|
|
|
return true, nil
|
2013-11-12 12:21:17 +04:00
|
|
|
}
|
|
|
|
}
|
2015-01-05 11:56:39 +03:00
|
|
|
return false, nil
|
2013-11-12 12:21:17 +04:00
|
|
|
}
|
|
|
|
|
2013-05-17 17:30:22 +04:00
|
|
|
type InsertedWaysCache 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 newInsertedWaysCache(path string) (*InsertedWaysCache, error) {
|
2013-05-17 17:30:22 +04:00
|
|
|
cache := InsertedWaysCache{}
|
2013-07-04 19:27:22 +04:00
|
|
|
cache.options = &globalCacheOptions.InsertedWays
|
2013-06-18 17:53:04 +04:00
|
|
|
|
2013-05-17 17:30:22 +04:00
|
|
|
err := cache.open(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &cache, err
|
|
|
|
}
|
|
|
|
|
2013-12-12 20:12:05 +04:00
|
|
|
func (p *InsertedWaysCache) PutWay(way *element.Way) error {
|
|
|
|
keyBuf := idToKeyBuf(way.Id)
|
|
|
|
return p.db.Put(p.wo, keyBuf, []byte{})
|
|
|
|
}
|
|
|
|
|
2013-05-17 17:30:22 +04:00
|
|
|
func (p *InsertedWaysCache) PutMembers(members []element.Member) error {
|
|
|
|
batch := levigo.NewWriteBatch()
|
|
|
|
defer batch.Close()
|
|
|
|
|
|
|
|
for _, m := range members {
|
|
|
|
if m.Type != element.WAY {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
keyBuf := idToKeyBuf(m.Id)
|
|
|
|
batch.Put(keyBuf, []byte{})
|
|
|
|
}
|
|
|
|
return p.db.Write(p.wo, batch)
|
|
|
|
}
|
|
|
|
|
2013-08-01 16:07:06 +04:00
|
|
|
func (p *InsertedWaysCache) DeleteMembers(members []element.Member) error {
|
|
|
|
batch := levigo.NewWriteBatch()
|
|
|
|
defer batch.Close()
|
|
|
|
|
|
|
|
for _, m := range members {
|
|
|
|
if m.Type != element.WAY {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
keyBuf := idToKeyBuf(m.Id)
|
|
|
|
batch.Delete(keyBuf)
|
|
|
|
}
|
|
|
|
return p.db.Write(p.wo, batch)
|
|
|
|
}
|
|
|
|
|
2013-05-17 17:30:22 +04:00
|
|
|
func (p *InsertedWaysCache) IsInserted(id int64) (bool, error) {
|
|
|
|
keyBuf := idToKeyBuf(id)
|
|
|
|
data, err := p.db.Get(p.ro, keyBuf)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
if data == nil {
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
return true, nil
|
|
|
|
}
|