github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/storage/memdb_snapshot.go (about)

     1  // Copyright 2022 zGraph Authors. All rights reserved.
     2  //
     3  // Copyright 2020 PingCAP, Inc.
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package storage
    18  
    19  import (
    20  	"context"
    21  
    22  	"github.com/vescale/zgraph/storage/kv"
    23  )
    24  
    25  // SnapshotGetter returns a Getter for a snapshot of MemBuffer.
    26  func (db *MemDB) SnapshotGetter() kv.Getter {
    27  	return &memdbSnapGetter{
    28  		db: db,
    29  		cp: db.getSnapshot(),
    30  	}
    31  }
    32  
    33  // SnapshotIter returns a Iterator for a snapshot of MemBuffer.
    34  func (db *MemDB) SnapshotIter(start, end []byte) kv.Iterator {
    35  	it := &memdbSnapIter{
    36  		MemDBIter: &MemDBIter{
    37  			db:    db,
    38  			start: start,
    39  			end:   end,
    40  		},
    41  		cp: db.getSnapshot(),
    42  	}
    43  	it.init()
    44  	return it
    45  }
    46  
    47  func (db *MemDB) getSnapshot() MemDBCheckpoint {
    48  	if len(db.stages) > 0 {
    49  		return db.stages[0]
    50  	}
    51  	return db.vlog.checkpoint()
    52  }
    53  
    54  type memdbSnapGetter struct {
    55  	db *MemDB
    56  	cp MemDBCheckpoint
    57  }
    58  
    59  func (snap *memdbSnapGetter) Get(_ context.Context, key kv.Key) ([]byte, error) {
    60  	x := snap.db.traverse(key, false)
    61  	if x.isNull() {
    62  		return nil, kv.ErrNotExist
    63  	}
    64  	if x.vptr.isNull() {
    65  		// A flag only key, act as value not exists
    66  		return nil, kv.ErrNotExist
    67  	}
    68  	v, ok := snap.db.vlog.getSnapshotValue(x.vptr, &snap.cp)
    69  	if !ok {
    70  		return nil, kv.ErrNotExist
    71  	}
    72  	return v, nil
    73  }
    74  
    75  type memdbSnapIter struct {
    76  	*MemDBIter
    77  	value []byte
    78  	cp    MemDBCheckpoint
    79  }
    80  
    81  func (i *memdbSnapIter) Value() []byte {
    82  	return i.value
    83  }
    84  
    85  func (i *memdbSnapIter) Next() error {
    86  	i.value = nil
    87  	for i.Valid() {
    88  		if err := i.MemDBIter.Next(); err != nil {
    89  			return err
    90  		}
    91  		if i.setValue() {
    92  			return nil
    93  		}
    94  	}
    95  	return nil
    96  }
    97  
    98  func (i *memdbSnapIter) setValue() bool {
    99  	if !i.Valid() {
   100  		return false
   101  	}
   102  	if v, ok := i.db.vlog.getSnapshotValue(i.curr.vptr, &i.cp); ok {
   103  		i.value = v
   104  		return true
   105  	}
   106  	return false
   107  }
   108  
   109  func (i *memdbSnapIter) init() {
   110  	if len(i.start) == 0 {
   111  		i.seekToFirst()
   112  	} else {
   113  		i.seek(i.start)
   114  	}
   115  
   116  	if !i.setValue() {
   117  		err := i.Next()
   118  		_ = err // memdbIterator will never fail
   119  	}
   120  }