Commit d901e489 by lancet

further WIP

parent abb0698b
package vault package vault
import (
"errors"
"fmt"
"time"
)
// Init - инициализация хранилища
func (store *store) Init(ttl uint64) error {
if store.ttl != 0 {
return errors.New("Already up")
}
if ttl < 1 {
return errors.New("Wrong TTL")
}
store.ttl = ttl
store.Exchange = make(chan Message)
store.flat = make(map[string]*node)
var i uint64
for i = 0; i < ttl; i++ {
store.addNode("", "", false)
}
go store.control() // запускаем управление хранилищем
go store.cleaner() // запускаем устаревание записей
return nil
}
func (store *store) cleaner() {
reply := make(chan Message)
msg := Message{Action: "POP", Reply: reply}
for {
store.Exchange <- msg
got := <-reply
if got.Error == true {
fmt.Print("Cleaner sleeps.\n")
time.Sleep(1 * time.Second)
}
}
}
// control - управление хранилищем
func (store *store) control() {
tick := time.Tick(time.Second) // Каждую секунду ставим в очередь разделитель "вёдер"
for {
select {
case <-tick:
fmt.Print("Got time tick\n")
store.addNode("", "", false)
case request := <-store.Exchange:
fmt.Print("Got request", request, "\n")
reply := new(Message)
switch request.Action {
case "POP": // внутренний метод, часть механизма устаревания. Недоступен клиентам.
err := store.popNode()
if err != nil {
reply.Error = true
}
case "SET":
err := store.setNode(request.Key, request.Value)
reply.Key = request.Key
if err != nil {
reply.Error = true
}
case "GET":
v, err := store.getNode(request.Key)
if err != nil {
reply.Error = true
} else {
reply.Key = request.Key
reply.Value = v
}
case "DEL":
err := store.delNode(request.Key)
if err != nil {
reply.Key = request.Key
reply.Error = true
}
}
}
}
}
package vault package vault
import "time"
// Message - структура данных для двустороннего обмена с хранилищем, // Message - структура данных для двустороннего обмена с хранилищем,
// запрос/ответ // запрос/ответ
type Message struct { type Message struct {
Key string Key string
Value string Value string
Action string Action string // SET, GET, DEL, POP
Error bool Error bool
Reply chan Message Reply chan Message
} }
...@@ -23,8 +21,8 @@ type node struct { ...@@ -23,8 +21,8 @@ type node struct {
// Store - корневая структура для хранения данных // Store - корневая структура для хранения данных
type store struct { type store struct {
exchange chan Message // Небуферизованный канал для синхронизации доступа Exchange chan Message // Небуферизованный канал для синхронизации доступа
ttl time.Duration // Время жизни узла ttl uint64 // Время жизни узла, сек
head *node // Голова, выходит первым head *node // Голова, выходит первым
tail *node // Добавлен последним tail *node // Добавлен последним
flat map[string]*node // Карта для быстрого доступа к значениям flat map[string]*node // Карта для быстрого доступа к значениям
......
...@@ -5,9 +5,11 @@ import "errors" ...@@ -5,9 +5,11 @@ import "errors"
// addNode - добавляем новый узел в хвост очереди. // addNode - добавляем новый узел в хвост очереди.
func (store *store) addNode(key, value string, kind bool) { func (store *store) addNode(key, value string, kind bool) {
prev := store.tail prev := store.tail
store.tail = &node{Key: key, Value: value, Prev: prev, Kind: true} store.tail = &node{Key: key, Value: value, Prev: prev, Kind: kind}
prev.Next = store.tail prev.Next = store.tail
store.flat[key] = store.tail if kind == true {
store.flat[key] = store.tail
}
} }
// setNode - собираемся добавить новый узел. // setNode - собираемся добавить новый узел.
......
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