Answer the question
In order to leave comments, you need to log in
Am I doing the right thing with memory?
I'm trying to write thread-safe data manipulation. Came out to this:
package storage
import (
"errors"
"sort"
"sync"
)
type Book struct {
r sync.RWMutex
name string
description string
chapters []Chapter
}
type Chapter struct {
SerialNumber int64
Name string
Value string
}
func LoadBook(name, description string) *Book {
return &Book{name: name, description: description}
}
func (b *Book) GetName() string {
b.r.RLock()
defer b.r.RUnlock()
return b.name
}
func (b *Book) GetDescription() string {
b.r.RLock()
defer b.r.RUnlock()
return b.description
}
func (b *Book) GetListChapters() map[string]int64 {
m := map[string]int64{}
b.r.RLock()
for _, v := range b.chapters {
m[v.Name] = v.SerialNumber
}
b.r.RUnlock()
return m
}
func (b *Book) NormalizeChapters() {
b.r.Lock()
defer b.r.Unlock()
sort.SliceStable(b.chapters, func(i, j int) bool {
return b.chapters[i].SerialNumber < b.chapters[j].SerialNumber
})
}
func (b *Book) NewChapter(name, value string) error {
c := Chapter{
SerialNumber: b.GetMaxSerialNumber() + 1,
Name: name,
Value: value,
}
if !b.ChapterSerialNumberIsQnique(c.SerialNumber) {
return errors.New("SerialNumber not qnique")
}
b.r.Lock()
defer b.r.Unlock()
b.chapters = append(b.chapters, c)
return nil
}
func (b *Book) ChapterSerialNumberIsQnique(serialNumber int64) bool {
b.r.RLock()
defer b.r.RUnlock()
for _, v := range b.chapters {
if v.SerialNumber == serialNumber {
return false
}
}
return true
}
func (b *Book) UpdateChapter(c Chapter) error {
b.r.Lock()
defer b.r.Unlock()
for k, v := range b.chapters {
if v.SerialNumber == c.SerialNumber {
b.chapters[k] = c
return nil
}
}
return errors.New("Chapter not found")
}
func (b *Book) UpdateChapterByName(name, value string) error {
b.r.Lock()
defer b.r.Unlock()
for k, v := range b.chapters {
if v.Name == name {
b.chapters[k].Value = value
return nil
}
}
return errors.New("Chapter not found")
}
func (b *Book) DeleteChapter(serialNumber int64) {
b.r.Lock()
defer b.r.Unlock()
for k, v := range b.chapters {
if v.SerialNumber == serialNumber {
b.chapters = append(b.chapters[:k], b.chapters[k+1:]...)
}
}
}
func (b *Book) DeleteChapterByName(name string) {
b.r.Lock()
defer b.r.Unlock()
for k, v := range b.chapters {
if v.Name == name {
b.chapters = append(b.chapters[:k], b.chapters[k+1:]...)
}
}
}
func (b *Book) GetChapter(serialNumber int64) (Chapter, bool) {
b.r.RLock()
defer b.r.RUnlock()
for _, v := range b.chapters {
if v.SerialNumber == serialNumber {
return v, true
}
}
return Chapter{}, false
}
func (b *Book) GetChapterByName(name string) (Chapter, bool) {
b.r.RLock()
defer b.r.RUnlock()
for _, v := range b.chapters {
if v.Name == name {
return v, true
}
}
return Chapter{}, false
}
func (b *Book) GetMaxSerialNumber() int64 {
b.NormalizeChapters()
b.r.RLock()
defer b.r.RUnlock()
l := len(b.chapters)
if l == 0 {
return 0
} else {
return b.chapters[l-1].SerialNumber
}
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question