From 1b764586840cba6f255e0aa95f1476c9ad60e2fb Mon Sep 17 00:00:00 2001
From: Alex Vanin <alexey@nspcc.ru>
Date: Tue, 1 Dec 2020 10:35:25 +0300
Subject: [PATCH] [#222] Add writeCache instance to shard

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
---
 pkg/local_object_storage/shard/control.go | 45 ++++++++++++++---------
 pkg/local_object_storage/shard/shard.go   | 27 ++++++++++++--
 2 files changed, 50 insertions(+), 22 deletions(-)

diff --git a/pkg/local_object_storage/shard/control.go b/pkg/local_object_storage/shard/control.go
index 0fc7e683e..edb18273a 100644
--- a/pkg/local_object_storage/shard/control.go
+++ b/pkg/local_object_storage/shard/control.go
@@ -6,12 +6,15 @@ import (
 
 // Open opens all Shard's components.
 func (s *Shard) Open() error {
-	for _, component := range []interface {
-		Open() error
-	}{
-		s.blobStor,
-		s.metaBase,
-	} {
+	components := []interface{ Open() error }{
+		s.blobStor, s.metaBase,
+	}
+
+	if s.hasWriteCache() {
+		components = append(components, s.writeCache)
+	}
+
+	for _, component := range components {
 		if err := component.Open(); err != nil {
 			return errors.Wrapf(err, "could not open %s", component)
 		}
@@ -22,12 +25,15 @@ func (s *Shard) Open() error {
 
 // Init initializes all Shard's components.
 func (s *Shard) Init() error {
-	for _, component := range []interface {
-		Init() error
-	}{
-		s.blobStor,
-		s.metaBase,
-	} {
+	components := []interface{ Init() error }{
+		s.blobStor, s.metaBase,
+	}
+
+	if s.hasWriteCache() {
+		components = append(components, s.writeCache)
+	}
+
+	for _, component := range components {
 		if err := component.Init(); err != nil {
 			return errors.Wrapf(err, "could not initialize %s", component)
 		}
@@ -38,12 +44,15 @@ func (s *Shard) Init() error {
 
 // Close releases all Shard's components.
 func (s *Shard) Close() error {
-	for _, component := range []interface {
-		Close() error
-	}{
-		s.blobStor,
-		s.metaBase,
-	} {
+	components := []interface{ Close() error }{
+		s.blobStor, s.metaBase,
+	}
+
+	if s.hasWriteCache() {
+		components = append(components, s.writeCache)
+	}
+
+	for _, component := range components {
 		if err := component.Close(); err != nil {
 			return errors.Wrapf(err, "could not close %s", component)
 		}
diff --git a/pkg/local_object_storage/shard/shard.go b/pkg/local_object_storage/shard/shard.go
index f05b38ec0..838fc0723 100644
--- a/pkg/local_object_storage/shard/shard.go
+++ b/pkg/local_object_storage/shard/shard.go
@@ -13,6 +13,8 @@ type Shard struct {
 
 	mode *atomic.Uint32
 
+	writeCache *blobstor.BlobStor
+
 	blobStor *blobstor.BlobStor
 
 	metaBase *meta.DB
@@ -45,11 +47,23 @@ func New(opts ...Option) *Shard {
 		opts[i](c)
 	}
 
+	var writeCache *blobstor.BlobStor
+
+	if c.useWriteCache {
+		writeCache = blobstor.New(
+			blobstor.WithBlobovniczaShallowDepth(0),
+			blobstor.WithBlobovniczaShallowWidth(1),
+			blobstor.WithLogger(c.log),
+			// ? what about path
+		)
+	}
+
 	return &Shard{
-		cfg:      c,
-		mode:     atomic.NewUint32(0), // TODO: init with particular mode
-		blobStor: blobstor.New(c.blobOpts...),
-		metaBase: meta.New(c.metaOpts...),
+		cfg:        c,
+		mode:       atomic.NewUint32(0), // TODO: init with particular mode
+		blobStor:   blobstor.New(c.blobOpts...),
+		metaBase:   meta.New(c.metaOpts...),
+		writeCache: writeCache,
 	}
 }
 
@@ -87,3 +101,8 @@ func WithWriteCache(use bool) Option {
 		c.useWriteCache = use
 	}
 }
+
+// hasWriteCache returns bool if write cache exists on shars.
+func (s Shard) hasWriteCache() bool {
+	return s.cfg.useWriteCache
+}