1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/*
* Copyright (c) 2013 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Seth Hoenig
* Allan Stockdill-Mander
* Mike Robertson
*/
package mqtt
import (
"sync"
"github.com/eclipse/paho.mqtt.golang/packets"
)
// MemoryStore implements the store interface to provide a "persistence"
// mechanism wholly stored in memory. This is only useful for
// as long as the client instance exists.
type MemoryStore struct {
sync.RWMutex
messages map[string]packets.ControlPacket
opened bool
}
// NewMemoryStore returns a pointer to a new instance of
// MemoryStore, the instance is not initialized and ready to
// use until Open() has been called on it.
func NewMemoryStore() *MemoryStore {
store := &MemoryStore{
messages: make(map[string]packets.ControlPacket),
opened: false,
}
return store
}
// Open initializes a MemoryStore instance.
func (store *MemoryStore) Open() {
store.Lock()
defer store.Unlock()
store.opened = true
DEBUG.Println(STR, "memorystore initialized")
}
// Put takes a key and a pointer to a Message and stores the
// message.
func (store *MemoryStore) Put(key string, message packets.ControlPacket) {
store.Lock()
defer store.Unlock()
if !store.opened {
ERROR.Println(STR, "Trying to use memory store, but not open")
return
}
store.messages[key] = message
}
// Get takes a key and looks in the store for a matching Message
// returning either the Message pointer or nil.
func (store *MemoryStore) Get(key string) packets.ControlPacket {
store.RLock()
defer store.RUnlock()
if !store.opened {
ERROR.Println(STR, "Trying to use memory store, but not open")
return nil
}
mid := mIDFromKey(key)
m := store.messages[key]
if m == nil {
CRITICAL.Println(STR, "memorystore get: message", mid, "not found")
} else {
DEBUG.Println(STR, "memorystore get: message", mid, "found")
}
return m
}
// All returns a slice of strings containing all the keys currently
// in the MemoryStore.
func (store *MemoryStore) All() []string {
store.RLock()
defer store.RUnlock()
if !store.opened {
ERROR.Println(STR, "Trying to use memory store, but not open")
return nil
}
keys := []string{}
for k := range store.messages {
keys = append(keys, k)
}
return keys
}
// Del takes a key, searches the MemoryStore and if the key is found
// deletes the Message pointer associated with it.
func (store *MemoryStore) Del(key string) {
store.Lock()
defer store.Unlock()
if !store.opened {
ERROR.Println(STR, "Trying to use memory store, but not open")
return
}
mid := mIDFromKey(key)
m := store.messages[key]
if m == nil {
WARN.Println(STR, "memorystore del: message", mid, "not found")
} else {
delete(store.messages, key)
DEBUG.Println(STR, "memorystore del: message", mid, "was deleted")
}
}
// Close will disallow modifications to the state of the store.
func (store *MemoryStore) Close() {
store.Lock()
defer store.Unlock()
if !store.opened {
ERROR.Println(STR, "Trying to close memory store, but not open")
return
}
store.opened = false
DEBUG.Println(STR, "memorystore closed")
}
// Reset eliminates all persisted message data in the store.
func (store *MemoryStore) Reset() {
store.Lock()
defer store.Unlock()
if !store.opened {
ERROR.Println(STR, "Trying to reset memory store, but not open")
}
store.messages = make(map[string]packets.ControlPacket)
WARN.Println(STR, "memorystore wiped")
}
|