Skip to content

Commit 2def2af

Browse files
committed
Merge branch 'feature/crdt-refactoring'
2 parents 3a45ae6 + 69e6c72 commit 2def2af

File tree

2 files changed

+230
-195
lines changed

2 files changed

+230
-195
lines changed

crdt/or-set.go

Lines changed: 61 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
// Structs
1717

1818
// ORSet conforms to the specification of an observed-
19-
// removed set defined by Shapiro, Preguiça, Baquero
19+
// removed set defined by Shapiro, Preguiça, Baquero,
2020
// and Zawirski. It consists of unique IDs and data items.
2121
type ORSet struct {
2222
lock *sync.RWMutex
@@ -36,7 +36,7 @@ type sendFunc func(string)
3636
func InitORSet() *ORSet {
3737

3838
return &ORSet{
39-
lock: new(sync.RWMutex),
39+
lock: &sync.RWMutex{},
4040
elements: make(map[string]string),
4141
}
4242
}
@@ -46,28 +46,25 @@ func InitORSet() *ORSet {
4646
// designated log file.
4747
func InitORSetWithFile(fileName string) (*ORSet, error) {
4848

49-
// Init an empty ORSet.
50-
s := InitORSet()
51-
5249
// Attempt to create a new CRDT file.
5350
f, err := os.Create(fileName)
5451
if err != nil {
55-
return nil, fmt.Errorf("opening CRDT file '%s' failed with: %s\n", fileName, err.Error())
52+
return nil, fmt.Errorf("opening CRDT file '%s' failed with: %v", fileName, err)
5653
}
5754

5855
// Change permissions.
5956
err = f.Chmod(0600)
6057
if err != nil {
61-
return nil, fmt.Errorf("changing permissions of CRDT file '%s' failed with: %s\n", fileName, err.Error())
58+
return nil, fmt.Errorf("changing permissions of CRDT file '%s' failed with: %v", fileName, err)
6259
}
6360

64-
// Assign it to ORSet.
61+
// Init an empty ORSet.
62+
s := InitORSet()
6563
s.file = f
6664

6765
// Write newly created CRDT file to stable storage.
68-
err = s.WriteORSetToFile(false)
69-
if err != nil {
70-
return nil, fmt.Errorf("error during CRDT file write-back: %s\n", err.Error())
66+
if err = s.WriteORSetToFile(false); err != nil {
67+
return nil, fmt.Errorf("error during CRDT file write-back: %v", err)
7168
}
7269

7370
return s, nil
@@ -78,20 +75,20 @@ func InitORSetWithFile(fileName string) (*ORSet, error) {
7875
// elements saved in file.
7976
func InitORSetFromFile(fileName string) (*ORSet, error) {
8077

81-
// Init an empty ORSet.
82-
s := InitORSet()
83-
8478
// Attempt to open CRDT file and assign to set afterwards.
8579
f, err := os.OpenFile(fileName, os.O_RDWR, 0600)
8680
if err != nil {
87-
return nil, fmt.Errorf("opening CRDT file '%s' failed with: %s\n", fileName, err.Error())
81+
return nil, fmt.Errorf("opening CRDT file '%s' failed with: %v", fileName, err)
8882
}
83+
84+
// Init an empty ORSet.
85+
s := InitORSet()
8986
s.file = f
9087

9188
// Parse contained CRDT state from file.
9289
contentsRaw, err := ioutil.ReadAll(s.file)
9390
if err != nil {
94-
return nil, fmt.Errorf("reading all contents from CRDT file '%s' failed with: %s\n", fileName, err.Error())
91+
return nil, fmt.Errorf("reading all contents from CRDT file '%s' failed with: %v", fileName, err)
9592
}
9693
contents := string(contentsRaw)
9794

@@ -105,7 +102,7 @@ func InitORSetFromFile(fileName string) (*ORSet, error) {
105102

106103
// Check even number of elements.
107104
if (len(parts) % 2) != 0 {
108-
return nil, fmt.Errorf("odd number of elements in CRDT file '%s'\n", fileName)
105+
return nil, fmt.Errorf("odd number of elements in CRDT file '%s'", fileName)
109106
}
110107

111108
// Range over all value-tag-pairs.
@@ -116,7 +113,7 @@ func InitORSetFromFile(fileName string) (*ORSet, error) {
116113
// Decode string from base64.
117114
decValue, err := base64.StdEncoding.DecodeString(parts[value])
118115
if err != nil {
119-
return nil, fmt.Errorf("decoding base64 string in CRDT file '%s' failed: %s\n", fileName, err.Error())
116+
return nil, fmt.Errorf("decoding base64 string in CRDT file '%s' failed: %v", fileName, err)
120117
}
121118

122119
// Assign decoded value to corresponding
@@ -157,25 +154,23 @@ func (s *ORSet) WriteORSetToFile(needsLocking bool) error {
157154
// Reset position in file to beginning.
158155
_, err := s.file.Seek(0, os.SEEK_SET)
159156
if err != nil {
160-
return fmt.Errorf("error while setting head back to beginning in CRDT file '%s': %s\n", s.file.Name(), err.Error())
157+
return fmt.Errorf("error while setting head back to beginning in CRDT file '%s': %v", s.file.Name(), err)
161158
}
162159

163160
// Write marshalled set to file.
164161
newNumOfBytes, err := s.file.WriteString(marshalled)
165162
if err != nil {
166-
return fmt.Errorf("failed to write ORSet contents to file '%s': %s\n", s.file.Name(), err.Error())
163+
return fmt.Errorf("failed to write ORSet contents to file '%s': %v", s.file.Name(), err)
167164
}
168165

169166
// Adjust file size to just written length of string.
170-
err = s.file.Truncate(int64(newNumOfBytes))
171-
if err != nil {
172-
return fmt.Errorf("error while truncating CRDT file '%s' to new size: %s\n", s.file.Name(), err.Error())
167+
if err := s.file.Truncate(int64(newNumOfBytes)); err != nil {
168+
return fmt.Errorf("error while truncating CRDT file '%s' to new size: %v", s.file.Name(), err)
173169
}
174170

175171
// Save to stable storage.
176-
err = s.file.Sync()
177-
if err != nil {
178-
return fmt.Errorf("could not synchronise CRDT file '%s' contents to stable storage: %s\n", s.file.Name(), err.Error())
172+
if err := s.file.Sync(); err != nil {
173+
return fmt.Errorf("could not synchronise CRDT file '%s' contents to stable storage: %v", s.file.Name(), err)
179174
}
180175

181176
return nil
@@ -185,6 +180,10 @@ func (s *ORSet) WriteORSetToFile(needsLocking bool) error {
185180
// of a supplied ORSet.
186181
func (s *ORSet) GetAllValues() []string {
187182

183+
// Read-lock set and unlock on exit.
184+
s.lock.RLock()
185+
defer s.lock.RUnlock()
186+
188187
// Make a slice of initial size 0.
189188
allValues := make([]string, 0)
190189

@@ -214,9 +213,6 @@ func (s *ORSet) GetAllValues() []string {
214213
// false otherwise.
215214
func (s *ORSet) Lookup(e string, needsLocking bool) bool {
216215

217-
// Fallback return value is false.
218-
found := false
219-
220216
if needsLocking {
221217
// Read-lock set and unlock on exit.
222218
s.lock.RLock()
@@ -226,15 +222,14 @@ func (s *ORSet) Lookup(e string, needsLocking bool) bool {
226222
for _, value := range s.elements {
227223

228224
// When we find the value while iterating
229-
// through set, we set return value to true
230-
// and end loop execution at this point.
225+
// through set, we return true and end loop
226+
// execution at this point.
231227
if e == value {
232-
found = true
233-
break
228+
return true
234229
}
235230
}
236231

237-
return found
232+
return false
238233
}
239234

240235
// AddEffect is the effect part of an update add operation
@@ -252,23 +247,24 @@ func (s *ORSet) AddEffect(e string, tag string, needsLocking bool, needsWriteBac
252247
// Insert data element e at key tag.
253248
s.elements[tag] = e
254249

255-
if needsWriteBack {
250+
if !needsWriteBack {
251+
return nil
252+
}
256253

257-
// Instructed to write changes back to file.
258-
err := s.WriteORSetToFile(false)
259-
if err != nil {
254+
// Instructed to write changes back to file.
255+
err := s.WriteORSetToFile(false)
256+
if err != nil {
260257

261-
// Error during write-back to stable storage.
258+
// Error during write-back to stable storage.
262259

263-
// Prepare remove set consistent of just added element.
264-
rSet := make(map[string]string)
265-
rSet[tag] = e
260+
// Prepare remove set consistent of just added element.
261+
rSet := make(map[string]string)
262+
rSet[tag] = e
266263

267-
// Revert just made changes.
268-
s.RemoveEffect(rSet, false, false)
264+
// Revert just made changes.
265+
s.RemoveEffect(rSet, false, false)
269266

270-
return fmt.Errorf("error during writing CRDT file back: %s\n", err.Error())
271-
}
267+
return fmt.Errorf("error during writing CRDT file back: %v", err)
272268
}
273269

274270
return nil
@@ -324,21 +320,22 @@ func (s *ORSet) RemoveEffect(rSet map[string]string, needsLocking bool, needsWri
324320
}
325321
}
326322

327-
if needsWriteBack {
328-
329-
// Instructed to write changes back to file.
330-
err := s.WriteORSetToFile(false)
331-
if err != nil {
323+
if !needsWriteBack {
324+
return nil
325+
}
332326

333-
// Error during write-back to stable storage.
327+
// Instructed to write changes back to file.
328+
err := s.WriteORSetToFile(false)
329+
if err != nil {
334330

335-
// Revert just made changes.
336-
for tag, value := range rSet {
337-
s.AddEffect(value, tag, false, false)
338-
}
331+
// Error during write-back to stable storage.
339332

340-
return fmt.Errorf("error during writing CRDT file back: %s\n", err.Error())
333+
// Revert just made changes.
334+
for tag, value := range rSet {
335+
s.AddEffect(value, tag, false, false)
341336
}
337+
338+
return fmt.Errorf("error during writing CRDT file back: %v", err)
342339
}
343340

344341
return nil
@@ -352,12 +349,6 @@ func (s *ORSet) RemoveEffect(rSet map[string]string, needsLocking bool, needsWri
352349
// sends out the remove message to all other replicas.
353350
func (s *ORSet) Remove(e string, send sendFunc) error {
354351

355-
// Initialize string to send out.
356-
var msg string
357-
358-
// Initialize set of elements to remove.
359-
rmElements := make(map[string]string)
360-
361352
// Write-lock set and unlock on exit.
362353
s.lock.Lock()
363354
defer s.lock.Unlock()
@@ -367,6 +358,12 @@ func (s *ORSet) Remove(e string, send sendFunc) error {
367358
return fmt.Errorf("element to be removed not found in set")
368359
}
369360

361+
// Initialize string to send out.
362+
var msg string
363+
364+
// Initialize set of elements to remove.
365+
rmElements := make(map[string]string)
366+
370367
// Otherwise range over set elements.
371368
for tag, value := range s.elements {
372369

@@ -389,8 +386,7 @@ func (s *ORSet) Remove(e string, send sendFunc) error {
389386
// Execute the effect part of the update remove but do
390387
// not lock the set structure as we already maintain a lock.
391388
// Also, write changes back to stable storage.
392-
err := s.RemoveEffect(rmElements, false, true)
393-
if err != nil {
389+
if err := s.RemoveEffect(rmElements, false, true); err != nil {
394390
return err
395391
}
396392

0 commit comments

Comments
 (0)