@vgrabkowot

Правильно ли я работаю с памятью?

Я пытаюсь написать потоко-безопасную работу с данными. Вышло во это:
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
	}
}


Все ли правильно сделал? Буду благодарен любым советам.
  • Вопрос задан
  • 228 просмотров
Решения вопроса 1
@quiex
Ну да, норм. Сойдет.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы