mirror of
				https://bitbucket.org/s_l_teichmann/mtsatellite
				synced 2025-11-04 01:55:25 +01:00 
			
		
		
		
	Implemented a simple LRU cache with max 256 entries for base tile hasing. TODO: Improve test.
This commit is contained in:
		@@ -48,7 +48,7 @@
 | 
				
			|||||||
    <script type="text/javascript" src="js/leaflet.awesome-markers.js"></script>
 | 
					    <script type="text/javascript" src="js/leaflet.awesome-markers.js"></script>
 | 
				
			||||||
    <script>
 | 
					    <script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var useWebsocket = false; // Set to true if you want websocket support
 | 
					var useWebsocket = true; // Set to true if you want websocket support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
L.Projection.NoWrap = {
 | 
					L.Projection.NoWrap = {
 | 
				
			||||||
    project: function (latlng) {
 | 
					    project: function (latlng) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,27 +9,81 @@ import (
 | 
				
			|||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const btMaxEntries = 256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type btKey struct {
 | 
				
			||||||
 | 
						x int
 | 
				
			||||||
 | 
						y int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type btHashEntry struct {
 | 
				
			||||||
 | 
						prev *btHashEntry
 | 
				
			||||||
 | 
						next *btHashEntry
 | 
				
			||||||
 | 
						hash []byte
 | 
				
			||||||
 | 
						btKey
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BaseTileHash struct {
 | 
					type BaseTileHash struct {
 | 
				
			||||||
	// XXX: Maybe use some kind of LRU cache instead?
 | 
						hashes map[btKey]*btHashEntry
 | 
				
			||||||
	hashes map[struct{ x, y int }][]byte
 | 
						root   btHashEntry
 | 
				
			||||||
	sync.Mutex
 | 
						sync.Mutex
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewBaseTileHash() *BaseTileHash {
 | 
					func NewBaseTileHash() *BaseTileHash {
 | 
				
			||||||
	return &BaseTileHash{hashes: map[struct{ x, y int }][]byte{}}
 | 
						bth := &BaseTileHash{
 | 
				
			||||||
 | 
							hashes: map[btKey]*btHashEntry{}}
 | 
				
			||||||
 | 
						bth.root.next = &bth.root
 | 
				
			||||||
 | 
						bth.root.prev = &bth.root
 | 
				
			||||||
 | 
						return bth
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (bth *BaseTileHash) toFront(entry *btHashEntry) {
 | 
				
			||||||
 | 
						if bth.root.next == entry {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						entry.prev.next = entry.next
 | 
				
			||||||
 | 
						entry.next.prev = entry.prev
 | 
				
			||||||
 | 
						entry.next = bth.root.next
 | 
				
			||||||
 | 
						entry.prev = &bth.root
 | 
				
			||||||
 | 
						bth.root.next = entry
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (bth *BaseTileHash) removeLast() *btHashEntry {
 | 
				
			||||||
 | 
						last := bth.root.prev
 | 
				
			||||||
 | 
						bth.root.prev = last.prev
 | 
				
			||||||
 | 
						last.prev.next = &bth.root
 | 
				
			||||||
 | 
						delete(bth.hashes, last.btKey)
 | 
				
			||||||
 | 
						return last
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (bth *BaseTileHash) insertFront(entry *btHashEntry) {
 | 
				
			||||||
 | 
						entry.next = bth.root.next
 | 
				
			||||||
 | 
						entry.prev = &bth.root
 | 
				
			||||||
 | 
						bth.root.next.prev = entry
 | 
				
			||||||
 | 
						bth.root.next = entry
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (bth *BaseTileHash) Update(x, y int, hash []byte) bool {
 | 
					func (bth *BaseTileHash) Update(x, y int, hash []byte) bool {
 | 
				
			||||||
	key := struct{ x, y int }{x, y}
 | 
					 | 
				
			||||||
	bth.Lock()
 | 
						bth.Lock()
 | 
				
			||||||
	defer bth.Unlock()
 | 
						defer bth.Unlock()
 | 
				
			||||||
 | 
						key := btKey{x, y}
 | 
				
			||||||
	if old, found := bth.hashes[key]; found {
 | 
						if old, found := bth.hashes[key]; found {
 | 
				
			||||||
		if !bytes.Equal(old, hash) {
 | 
							if !bytes.Equal(old.hash, hash) {
 | 
				
			||||||
			bth.hashes[key] = hash
 | 
								old.hash = hash
 | 
				
			||||||
 | 
								bth.toFront(old)
 | 
				
			||||||
			return true
 | 
								return true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	bth.hashes[key] = hash
 | 
						var entry *btHashEntry
 | 
				
			||||||
 | 
						if len(bth.hashes) >= btMaxEntries {
 | 
				
			||||||
 | 
							entry = bth.removeLast()
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							entry = new(btHashEntry)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						entry.btKey = key
 | 
				
			||||||
 | 
						entry.hash = hash
 | 
				
			||||||
 | 
						bth.hashes[key] = entry
 | 
				
			||||||
 | 
						bth.insertFront(entry)
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								common/basetilehash_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								common/basetilehash_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					// Copyright 2016 by Sascha L. Teichmann
 | 
				
			||||||
 | 
					// Use of this source code is governed by the MIT license
 | 
				
			||||||
 | 
					// that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package common
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestBaseTileHash(t *testing.T) {
 | 
				
			||||||
 | 
						bth := NewBaseTileHash()
 | 
				
			||||||
 | 
						h1 := []byte{1}
 | 
				
			||||||
 | 
						h2 := []byte{2}
 | 
				
			||||||
 | 
						for i := 0; i < 600; i++ {
 | 
				
			||||||
 | 
							x := i % 200
 | 
				
			||||||
 | 
							for j := 0; j < 600; j++ {
 | 
				
			||||||
 | 
								y := j % 200
 | 
				
			||||||
 | 
								var h []byte
 | 
				
			||||||
 | 
								if j%2 == 0 {
 | 
				
			||||||
 | 
									h = h1
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									h = h2
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								_ = bth.Update(x, y, h)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Logf("size: %d\n", len(bth.hashes))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user