github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/meta/graph.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 meta 16 17 import ( 18 "encoding/json" 19 "fmt" 20 21 "github.com/pingcap/errors" 22 "github.com/vescale/zgraph/parser/model" 23 ) 24 25 func (*Meta) graphKey(id int64) []byte { 26 return GraphKey(id) 27 } 28 29 // GraphKey encodes the graph identifier into graph key. 30 func GraphKey(id int64) []byte { 31 return []byte(fmt.Sprintf("%s:%d", mGraphPrefix, id)) 32 } 33 34 func (m *Meta) checkGraphExists(graphKey []byte) error { 35 v, err := m.txn.HGet(mGraphs, graphKey) 36 if err == nil && v == nil { 37 err = ErrGraphNotExists 38 } 39 return errors.Trace(err) 40 } 41 42 func (m *Meta) checkGraphNotExists(graphKey []byte) error { 43 v, err := m.txn.HGet(mGraphs, graphKey) 44 if err == nil && v != nil { 45 err = ErrGraphExists 46 } 47 return errors.Trace(err) 48 } 49 50 // CreateGraph creates a graph. 51 func (m *Meta) CreateGraph(info *model.GraphInfo) error { 52 graphKey := m.graphKey(info.ID) 53 54 if err := m.checkGraphNotExists(graphKey); err != nil { 55 return errors.Trace(err) 56 } 57 58 data, err := json.Marshal(info) 59 if err != nil { 60 return errors.Trace(err) 61 } 62 63 return m.txn.HSet(mGraphs, graphKey, data) 64 } 65 66 // UpdateGraph updates a graph. 67 func (m *Meta) UpdateGraph(info *model.GraphInfo) error { 68 graphKey := m.graphKey(info.ID) 69 70 if err := m.checkGraphExists(graphKey); err != nil { 71 return errors.Trace(err) 72 } 73 74 data, err := json.Marshal(info) 75 if err != nil { 76 return errors.Trace(err) 77 } 78 79 return m.txn.HSet(mGraphs, graphKey, data) 80 } 81 82 // DropGraph drops whole graph. 83 func (m *Meta) DropGraph(graphID int64) error { 84 // Check if graph exists. 85 graphKey := m.graphKey(graphID) 86 if err := m.txn.HClear(graphKey); err != nil { 87 return errors.Trace(err) 88 } 89 90 if err := m.txn.HDel(mGraphs, graphKey); err != nil { 91 return errors.Trace(err) 92 } 93 94 return nil 95 } 96 97 // ListGraphs shows all graphs. 98 func (m *Meta) ListGraphs() ([]*model.GraphInfo, error) { 99 res, err := m.txn.HGetAll(mGraphs) 100 if err != nil { 101 return nil, errors.Trace(err) 102 } 103 104 graphs := make([]*model.GraphInfo, 0, len(res)) 105 for _, r := range res { 106 graphInfo := &model.GraphInfo{} 107 err = json.Unmarshal(r.Value, graphInfo) 108 if err != nil { 109 return nil, errors.Trace(err) 110 } 111 graphs = append(graphs, graphInfo) 112 } 113 return graphs, nil 114 } 115 116 // GetGraph gets the database value with ID. 117 func (m *Meta) GetGraph(graphID int64) (*model.GraphInfo, error) { 118 graphKey := m.graphKey(graphID) 119 value, err := m.txn.HGet(mGraphs, graphKey) 120 if err != nil || value == nil { 121 return nil, errors.Trace(err) 122 } 123 124 graphInfo := &model.GraphInfo{} 125 err = json.Unmarshal(value, graphInfo) 126 return graphInfo, errors.Trace(err) 127 } 128 129 // AdvanceID advances the local ID allocator by n, and return the old global ID. 130 // NOTE: It's better to call graph.MDLock() to reduce transaction conflicts. 131 func (m *Meta) AdvanceID(graphID int64, n int) (int64, error) { 132 // Check if graph exists. 133 graphKey := m.graphKey(graphID) 134 if err := m.checkGraphExists(graphKey); err != nil { 135 return 0, errors.Trace(err) 136 } 137 138 newID, err := m.txn.HInc(graphKey, mNextIDKey, int64(n)) 139 if err != nil { 140 return 0, err 141 } 142 if newID > MaxGlobalID { 143 return 0, errors.Errorf("global id:%d exceeds the limit:%d", newID, MaxGlobalID) 144 } 145 origID := newID - int64(n) 146 return origID, nil 147 }