Copy-On-Write is a classic way to deal with concurrency problems in the 
"frequently read, but infrequently updated" scenario.

I noticed an interesting discussion from a previous conversation: 
https://groups.google.com/g/golang-nuts/c/zyQnord8hyc. The author of 
weed-fs tried to implement Copy-On-Write by simply assigning a new value to 
a string variable in a struct. Like this: `vs.masterNode = master`.

So here comes the question, what's the recommend way of implmentating COW?

The atomic package provides an example: 
https://pkg.go.dev/sync/atomic#example-Value-ReadMostly

import (
  "sync"
  "sync/atomic"
)

func main() {
  type Map map[string]string
  var m atomic.Value
  m.Store(make(Map))
  var mu sync.Mutex // used only by writers
  // read function can be used to read the data without further 
synchronization
  read := func(key string) (val string) {
    m1 := m.Load().(Map)
    return m1[key]
  }
  // insert function can be used to update the data without further 
synchronization
  insert := func(key, val string) {
    mu.Lock() // synchronize with other potential writers
    defer mu.Unlock()
    m1 := m.Load().(Map) // load current value of the data structure
    m2 := make(Map)      // create a new value
    for k, v := range m1 {
      m2[k] = v // copy all data from the current object to the new one
    }
    m2[key] = val // do the update that we need
    m.Store(m2)   // atomically replace the current object with the new one
    // At this point all new readers start working with the new version.
    // The old version will be garbage collected once the existing readers
    // (if any) are done with it.
  }
  _, _ = read, insert
}


Acutally, most of the usecase I saw use map as the underlying data 
structure for demonstration.

What's the correct way to implement COW on a string variable, or maybe 
other primitive type like int64 ? Should I just replace the `Map` type, and 
keep everything else the same in the above official example ?

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/b74eca1a-40c5-4ec8-b025-f48c5037f214n%40googlegroups.com.

Reply via email to