github.com/matrixorigin/matrixone@v1.2.0/pkg/txn/storage/memorystorage/dynamic_storage.go (about)

     1  // Copyright 2022 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package memorystorage
    16  
    17  import (
    18  	"context"
    19  	"sync"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    22  	"github.com/matrixorigin/matrixone/pkg/pb/timestamp"
    23  	"github.com/matrixorigin/matrixone/pkg/pb/txn"
    24  	"github.com/matrixorigin/matrixone/pkg/txn/storage"
    25  )
    26  
    27  type DynamicStorage struct {
    28  	newStorage func() (*Storage, error)
    29  	keyFunc    func(context.Context) (any, error)
    30  	storages   struct {
    31  		sync.Mutex
    32  		Map map[any]*Storage
    33  	}
    34  }
    35  
    36  func NewDynamicStorage(
    37  	newStorage func() (*Storage, error),
    38  	keyFunc func(context.Context) (any, error),
    39  ) *DynamicStorage {
    40  	s := &DynamicStorage{
    41  		newStorage: newStorage,
    42  		keyFunc:    keyFunc,
    43  	}
    44  	s.storages.Map = make(map[any]*Storage)
    45  	return s
    46  }
    47  
    48  var _ storage.TxnStorage = new(DynamicStorage)
    49  
    50  func (d *DynamicStorage) Start() error {
    51  	return nil
    52  }
    53  
    54  func (d *DynamicStorage) Close(ctx context.Context) error {
    55  	storage, err := d.get(ctx)
    56  	if err != nil {
    57  		return err
    58  	}
    59  	return storage.Close(ctx)
    60  }
    61  
    62  func (d *DynamicStorage) Commit(ctx context.Context, txnMeta txn.TxnMeta) (timestamp.Timestamp, error) {
    63  	storage, err := d.get(ctx)
    64  	if err != nil {
    65  		return timestamp.Timestamp{}, err
    66  	}
    67  	return storage.Commit(ctx, txnMeta)
    68  }
    69  
    70  func (d *DynamicStorage) Committing(ctx context.Context, txnMeta txn.TxnMeta) error {
    71  	storage, err := d.get(ctx)
    72  	if err != nil {
    73  		return err
    74  	}
    75  	return storage.Committing(ctx, txnMeta)
    76  }
    77  
    78  func (d *DynamicStorage) Destroy(ctx context.Context) error {
    79  	storage, err := d.get(ctx)
    80  	if err != nil {
    81  		return err
    82  	}
    83  	return storage.Destroy(ctx)
    84  }
    85  
    86  func (d *DynamicStorage) Prepare(ctx context.Context, txnMeta txn.TxnMeta) (ts timestamp.Timestamp, err error) {
    87  	storage, err := d.get(ctx)
    88  	if err != nil {
    89  		return
    90  	}
    91  	return storage.Prepare(ctx, txnMeta)
    92  }
    93  
    94  func (d *DynamicStorage) Read(ctx context.Context, txnMeta txn.TxnMeta, op uint32, payload []byte) (res storage.ReadResult, err error) {
    95  	storage, err := d.get(ctx)
    96  	if err != nil {
    97  		return
    98  	}
    99  	return storage.Read(ctx, txnMeta, op, payload)
   100  }
   101  
   102  func (d *DynamicStorage) Rollback(ctx context.Context, txnMeta txn.TxnMeta) error {
   103  	storage, err := d.get(ctx)
   104  	if err != nil {
   105  		return nil
   106  	}
   107  	return storage.Rollback(ctx, txnMeta)
   108  }
   109  
   110  func (d *DynamicStorage) StartRecovery(ctx context.Context, ch chan txn.TxnMeta) {
   111  	storage, err := d.get(ctx)
   112  	if err != nil {
   113  		return
   114  	}
   115  	storage.StartRecovery(ctx, ch)
   116  }
   117  
   118  func (d *DynamicStorage) Write(ctx context.Context, txnMeta txn.TxnMeta, op uint32, payload []byte) ([]byte, error) {
   119  	storage, err := d.get(ctx)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  	return storage.Write(ctx, txnMeta, op, payload)
   124  }
   125  
   126  func (d *DynamicStorage) get(ctx context.Context) (*Storage, error) {
   127  	key, err := d.keyFunc(ctx)
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  	d.storages.Lock()
   132  	defer d.storages.Unlock()
   133  	storage, ok := d.storages.Map[key]
   134  	if !ok {
   135  		var err error
   136  		storage, err = d.newStorage()
   137  		if err != nil {
   138  			return nil, err
   139  		}
   140  		d.storages.Map[key] = storage
   141  	}
   142  	return storage, nil
   143  }
   144  
   145  func (d *DynamicStorage) Debug(context.Context, txn.TxnMeta, uint32, []byte) ([]byte, error) {
   146  	return nil, moerr.NewNotSupportedNoCtx("DynamicStorage not support debug method")
   147  }