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  }