Commit 630da929 by lancet

more WIP

parent 05f5a5c6
......@@ -8,20 +8,23 @@ type Message struct {
Key string
Value string
Action string
Code int
Error bool
}
// node - узел данных для очереди устаревания
type node struct {
Kind bool // 0 - таймаут, 1 - данные
Key string // Ключ
Value string // Хранимое значение
Prev *node // Ближе к голове, извлекается раньше
Next *node // Ближе к хвосту, выйдёт позже
}
// Store - корневая структура для хранения данных
type Store struct {
Exchange chan Message // Небуферизованный канал для синхронизации доступа
TTL time.Time // Время жизни узла
Head *node
Tail *node
Map map[string]node // Карта для быстрого доступа к значениям
type store struct {
exchange chan Message // Небуферизованный канал для синхронизации доступа
ttl time.Time // Время жизни узла
head *node
tail *node
flat map[string]*node // Карта для быстрого доступа к значениям
}
package vault
// setNode - добавляем новый узел в очередь.
// Если такой ключ уже есть - переносим узел в начало очереди.
func (store *Store) setNode(key, value string) error {
import "errors"
// 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
}
// popNode - извлекаем узел из очереди и уничтожаем его.
// popNode - извлекаем узел из гловы очереди и уничтожаем его.
// Если 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
}
// getNode - получить значение ключа, или ошибку, если такого нет.
func (store *Store) getNode(key string) (string, error) {
return "", nil
func (store *store) getNode(key string) (string, error) {
if v, ok := store.flat[key]; ok != false {
return v.Value, nil
}
return "", errors.New("No such key")
}
// 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
}
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