Commit 630da929 by lancet

more WIP

parent 05f5a5c6
...@@ -8,20 +8,23 @@ type Message struct { ...@@ -8,20 +8,23 @@ type Message struct {
Key string Key string
Value string Value string
Action string Action string
Code int Error bool
} }
// node - узел данных для очереди устаревания // node - узел данных для очереди устаревания
type node struct { type node struct {
Kind bool // 0 - таймаут, 1 - данные Kind bool // 0 - таймаут, 1 - данные
Key string // Ключ
Value string // Хранимое значение Value string // Хранимое значение
Prev *node // Ближе к голове, извлекается раньше
Next *node // Ближе к хвосту, выйдёт позже
} }
// Store - корневая структура для хранения данных // Store - корневая структура для хранения данных
type Store struct { type store struct {
Exchange chan Message // Небуферизованный канал для синхронизации доступа exchange chan Message // Небуферизованный канал для синхронизации доступа
TTL time.Time // Время жизни узла ttl time.Time // Время жизни узла
Head *node head *node
Tail *node tail *node
Map map[string]node // Карта для быстрого доступа к значениям flat map[string]*node // Карта для быстрого доступа к значениям
} }
package vault package vault
// setNode - добавляем новый узел в очередь. import "errors"
// Если такой ключ уже есть - переносим узел в начало очереди.
func (store *Store) setNode(key, value string) error { // addNode - добавляем новый узел в хвост очереди.
func (store *store) addNode(key, value string) {
prev := store.tail
store.tail = &node{Key: key, Value: value, Prev: prev, Kind: true}
prev.Next = store.tail
store.flat[key] = store.tail
}
// setNode - собираемся добавить новый узел.
// Если ключа ещё нет - просто добавляем в хвост.
// Если ключ есть - переносим в хвост.
func (store *store) setNode(key, value string) error {
if _, ok := store.flat[key]; ok == false {
store.addNode(key, value)
return nil
}
// Вместо того, чтобы удалить и пересоздать, просто правим ссылки.
// Так будет эффективней, чем удалять и создавать объекты данных.
node := store.flat[key]
head := store.head
prev := node.Prev
next := node.Next
if prev != nil {
prev.Next = next
}
if next != nil {
next.Prev = prev
}
if store.head == node {
store.head = prev
}
if store.tail == node {
store.tail = next
}
store.head = node
node.Prev = head
return nil return nil
} }
// popNode - извлекаем узел из очереди и уничтожаем его. // popNode - извлекаем узел из гловы очереди и уничтожаем его.
// Если Kind == 0 - то возвращаем ошибку. // Если Kind == 0 - то возвращаем ошибку.
// При ошибке устаревание приостанавливается на секунду. // При ошибке устаревание приостанавливается на секунду.
func (store *Store) popNode() error { func (store *store) popNode() error {
if store.head == nil {
return errors.New("No nodes")
}
if store.head.Kind == false {
return errors.New("Decay timeout")
}
key := store.head.Key
delete(store.flat, key)
store.head = store.head.Next
return nil return nil
} }
// getNode - получить значение ключа, или ошибку, если такого нет. // getNode - получить значение ключа, или ошибку, если такого нет.
func (store *Store) getNode(key string) (string, error) { func (store *store) getNode(key string) (string, error) {
return "", nil if v, ok := store.flat[key]; ok != false {
return v.Value, nil
}
return "", errors.New("No such key")
} }
// delNode - удалить узел с указанным ключом. // delNode - удалить узел с указанным ключом.
// Если такого ключа не было - вернуть ошибку. // Если такого ключа не было - вернуть ошибку.
func (store *Store) delNode(key string) error { func (store *store) delNode(key string) error {
if _, ok := store.flat[key]; ok == false {
return errors.New("No such key")
}
node := store.flat[key]
prev := node.Prev
next := node.Next
if prev != nil {
prev.Next = next
}
if next != nil {
next.Prev = prev
}
if store.head == node {
store.head = prev
}
if store.tail == node {
store.tail = next
}
delete(store.flat, key)
node = nil
return nil return nil
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment