github.com/cayleygraph/cayley@v0.7.7/graph/transaction.go (about) 1 // Copyright 2015 The Cayley 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 graph 16 17 import "github.com/cayleygraph/quad" 18 19 // Transaction stores a bunch of Deltas to apply together in an atomic step on the database. 20 type Transaction struct { 21 // Deltas stores the deltas in the right order 22 Deltas []Delta 23 // deltas stores the deltas in a map to avoid duplications 24 deltas map[Delta]struct{} 25 } 26 27 // NewTransaction initialize a new transaction. 28 func NewTransaction() *Transaction { 29 return NewTransactionN(10) 30 } 31 32 // NewTransactionN initialize a new transaction with a predefined capacity. 33 func NewTransactionN(n int) *Transaction { 34 return &Transaction{Deltas: make([]Delta, 0, n), deltas: make(map[Delta]struct{}, n)} 35 } 36 37 // AddQuad adds a new quad to the transaction if it is not already present in it. 38 // If there is a 'remove' delta for that quad, it will remove that delta from 39 // the transaction instead of actually adding the quad. 40 func (t *Transaction) AddQuad(q quad.Quad) { 41 ad, rd := createDeltas(q) 42 43 if _, adExists := t.deltas[ad]; !adExists { 44 if _, rdExists := t.deltas[rd]; rdExists { 45 t.deleteDelta(rd) 46 } else { 47 t.addDelta(ad) 48 } 49 } 50 } 51 52 // RemoveQuad adds a quad to remove to the transaction. 53 // The quad will be removed from the database if it is not present in the 54 // transaction, otherwise it simply remove it from the transaction. 55 func (t *Transaction) RemoveQuad(q quad.Quad) { 56 ad, rd := createDeltas(q) 57 58 if _, adExists := t.deltas[ad]; adExists { 59 t.deleteDelta(ad) 60 } else { 61 if _, rdExists := t.deltas[rd]; !rdExists { 62 t.addDelta(rd) 63 } 64 } 65 } 66 67 func createDeltas(q quad.Quad) (ad, rd Delta) { 68 ad = Delta{ 69 Quad: q, 70 Action: Add, 71 } 72 rd = Delta{ 73 Quad: q, 74 Action: Delete, 75 } 76 return 77 } 78 79 func (t *Transaction) addDelta(d Delta) { 80 t.Deltas = append(t.Deltas, d) 81 t.deltas[d] = struct{}{} 82 } 83 84 func (t *Transaction) deleteDelta(d Delta) { 85 delete(t.deltas, d) 86 87 for i, id := range t.Deltas { 88 if id == d { 89 t.Deltas = append(t.Deltas[:i], t.Deltas[i+1:]...) 90 break 91 } 92 } 93 }