github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/storage/storage.go (about) 1 // Copyright 2022 zGraph Authors. All rights reserved. 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 storage 16 17 import ( 18 "time" 19 20 "github.com/cockroachdb/pebble" 21 "github.com/vescale/zgraph/storage/gc" 22 "github.com/vescale/zgraph/storage/kv" 23 "github.com/vescale/zgraph/storage/latch" 24 "github.com/vescale/zgraph/storage/resolver" 25 ) 26 27 type mvccStorage struct { 28 db *pebble.DB 29 latches *latch.LatchesScheduler 30 resolver *resolver.Scheduler 31 gcManager *gc.Manager 32 } 33 34 // Open returns a new storage instance. 35 func Open(dirname string, options ...Option) (kv.Storage, error) { 36 opt := &pebble.Options{} 37 for _, op := range options { 38 op(opt) 39 } 40 db, err := pebble.Open(dirname, opt) 41 if err != nil { 42 return nil, err 43 } 44 45 s := &mvccStorage{ 46 db: db, 47 latches: latch.NewScheduler(8), 48 resolver: resolver.NewScheduler(4), 49 gcManager: gc.NewManager(2), 50 } 51 s.resolver.SetDB(db) 52 s.gcManager.SetDB(db) 53 s.gcManager.SetResolver(s.resolver) 54 55 // Run all background services. 56 s.latches.Run() 57 s.resolver.Run() 58 s.gcManager.Run() 59 60 return s, nil 61 } 62 63 // Begin implements the Storage interface 64 func (s *mvccStorage) Begin() (kv.Transaction, error) { 65 curVer := s.CurrentVersion() 66 snap, err := s.Snapshot(curVer) 67 if err != nil { 68 return nil, err 69 } 70 txn := &Txn{ 71 vp: s, 72 db: s.db, 73 us: NewUnionStore(snap), 74 latches: s.latches, 75 resolver: s.resolver, 76 valid: true, 77 startTime: time.Now(), 78 startVer: curVer, 79 snapshot: snap, 80 } 81 return txn, nil 82 } 83 84 // Snapshot implements the Storage interface. 85 func (s *mvccStorage) Snapshot(ver kv.Version) (kv.Snapshot, error) { 86 snap := &KVSnapshot{ 87 db: s.db, 88 vp: s, 89 ver: ver, 90 resolver: s.resolver, 91 } 92 return snap, nil 93 } 94 95 // CurrentVersion implements the VersionProvider interface. 96 // Currently, we use the system time as our startVer, and the system time 97 // rewind cannot be tolerant. 98 func (s *mvccStorage) CurrentVersion() kv.Version { 99 return kv.Version(time.Now().UnixNano()) 100 } 101 102 // Close implements the Storage interface. 103 func (s *mvccStorage) Close() error { 104 s.latches.Close() 105 s.resolver.Close() 106 s.gcManager.Close() 107 if s.db != nil { 108 return s.db.Close() 109 } 110 return nil 111 }