github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/db.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 zgraph
    16  
    17  import (
    18  	"sync"
    19  
    20  	"github.com/vescale/zgraph/catalog"
    21  	"github.com/vescale/zgraph/session"
    22  	"github.com/vescale/zgraph/storage"
    23  	"github.com/vescale/zgraph/storage/kv"
    24  )
    25  
    26  // DB represents the zGraph database instance.
    27  type DB struct {
    28  	// All fields are not been protected by Mutex will be read-only.
    29  	options *Options
    30  	store   kv.Storage
    31  	catalog *catalog.Catalog
    32  
    33  	mu struct {
    34  		sync.RWMutex
    35  		sessions map[int64]*session.Session
    36  	}
    37  }
    38  
    39  // Open opens a zGraph database instance with specified directory name.
    40  func Open(dirname string, opt *Options) (*DB, error) {
    41  	if opt == nil {
    42  		opt = &Options{}
    43  	}
    44  	opt.SetDefaults()
    45  
    46  	store, err := storage.Open(dirname)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	// Load the catalog from storage.
    52  	snapshot, err := store.Snapshot(store.CurrentVersion())
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  	catalog, err := catalog.Load(snapshot)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	db := &DB{
    62  		options: opt,
    63  		store:   store,
    64  		catalog: catalog,
    65  	}
    66  	db.mu.sessions = map[int64]*session.Session{}
    67  
    68  	return db, nil
    69  }
    70  
    71  // Store returns the storage engine object.
    72  func (db *DB) Store() kv.Storage {
    73  	return db.store
    74  }
    75  
    76  // Catalog returns the catalog object.
    77  func (db *DB) Catalog() *catalog.Catalog {
    78  	return db.catalog
    79  }
    80  
    81  // NewSession returns a new session.
    82  func (db *DB) NewSession() *session.Session {
    83  	// TODO: concurrency limitation
    84  	db.mu.Lock()
    85  	defer db.mu.Unlock()
    86  
    87  	s := session.New(db.store, db.catalog)
    88  	s.OnClosed(db.onSessionClosed)
    89  	db.mu.sessions[s.ID()] = s
    90  	return s
    91  }
    92  
    93  // Close destroys the zGraph database instances and all sessions will be terminated.
    94  func (db *DB) Close() error {
    95  	db.mu.Lock()
    96  	defer db.mu.Unlock()
    97  
    98  	for _, s := range db.mu.sessions {
    99  		s.OnClosed(db.onSessionClosedLocked)
   100  		s.Close()
   101  	}
   102  
   103  	return nil
   104  }
   105  
   106  func (db *DB) onSessionClosed(s *session.Session) {
   107  	db.mu.Lock()
   108  	defer db.mu.Unlock()
   109  	db.onSessionClosedLocked(s)
   110  }
   111  
   112  func (db *DB) onSessionClosedLocked(s *session.Session) {
   113  	delete(db.mu.sessions, s.ID())
   114  }