// Float64bits returns the IEEE 754 binary representation of f, // with the sign bit of f and the result in the same bit position, // and Float64bits(Float64frombits(x)) == x. funcFloat64bits(f float64)uint64 { return *(*uint64)(unsafe.Pointer(&f)) }
// Float64frombits returns the floating-point number corresponding // to the IEEE 754 binary representation b, with the sign bit of b // and the result in the same bit position. // Float64frombits(Float64bits(x)) == x. funcFloat64frombits(b uint64)float64 { return *(*float64)(unsafe.Pointer(&b)) }
// StoreUint64 atomically stores val into *addr. funcStoreUint64(addr *uint64, val uint64)
转换为uint64类型,使用atomic包下到存储和去出uint64类型。
Map
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Var is an abstract type for all exported variables. type Var interface { // String returns a valid JSON value for the variable. // Types with String methods that do not return valid JSON // (such as time.Time) must not be used as a Var. String() string }
// Map is a string-to-Var map variable that satisfies the Var interface. type Map struct { m sync.Map // map[string]Var keysMu sync.RWMutex keys []string// sorted }
// Do calls f for each entry in the map. // The map is locked during the iteration, // but existing entries may be concurrently updated. func(v *Map)Do(f func(KeyValue)) { v.keysMu.RLock() defer v.keysMu.RUnlock() for _, k := range v.keys { i, _ := v.m.Load(k) f(KeyValue{k, i.(Var)}) } }
接下来我看看添加key的方法
1 2 3 4 5 6 7 8 9 10 11 12 13
// addKey updates the sorted list of keys in v.keys. func(v *Map)addKey(key string) { v.keysMu.Lock() defer v.keysMu.Unlock() // Using insertion sort to place key into the already-sorted v.keys. if i := sort.SearchStrings(v.keys, key); i >= len(v.keys) { v.keys = append(v.keys, key) } elseif v.keys[i] != key { v.keys = append(v.keys, "") copy(v.keys[i+1:], v.keys[i:]) v.keys[i] = key } }
func(v *Map)Get(key string)Var { i, _ := v.m.Load(key) av, _ := i.(Var) return av }
func(v *Map)Set(key string, av Var) { // Before we store the value, check to see whether the key is new. Try a Load // before LoadOrStore: LoadOrStore causes the key interface to escape even on // the Load path. if _, ok := v.m.Load(key); !ok { if _, dup := v.m.LoadOrStore(key, av); !dup { v.addKey(key) return } }
// Add adds delta to the *Int value stored under the given map key. func(v *Map)Add(key string, delta int64) { i, ok := v.m.Load(key) if !ok { var dup bool i, dup = v.m.LoadOrStore(key, new(Int)) if !dup { v.addKey(key) } }
// Add to Int; ignore otherwise. if iv, ok := i.(*Int); ok { iv.Add(delta) } }
// AddFloat adds delta to the *Float value stored under the given map key. func(v *Map)AddFloat(key string, delta float64) { i, ok := v.m.Load(key) if !ok { var dup bool i, dup = v.m.LoadOrStore(key, new(Float)) if !dup { v.addKey(key) } }
// Add to Float; ignore otherwise. if iv, ok := i.(*Float); ok { iv.Add(delta) } }
// Deletes the given key from the map. func(v *Map)Delete(key string) { v.keysMu.Lock() defer v.keysMu.Unlock() i := sort.SearchStrings(v.keys, key) if i < len(v.keys) && key == v.keys[i] { v.keys = append(v.keys[:i], v.keys[i+1:]...) v.m.Delete(key) } }
// String is a string variable, and satisfies the Var interface. type String struct { s atomic.Value // string }
func(v *String)Value()string { p, _ := v.s.Load().(string) return p }
// String implements the Var interface. To get the unquoted string // use Value. func(v *String)String()string { s := v.Value() b, _ := json.Marshal(s) returnstring(b) }
// All published variables. var ( vars sync.Map // map[string]Var varKeysMu sync.RWMutex varKeys []string// sorted )
// Publish declares a named exported variable. This should be called from a // package's init function when it creates its Vars. If the name is already // registered then this will log.Panic. funcPublish(name string, v Var) { if _, dup := vars.LoadOrStore(name, v); dup { log.Panicln("Reuse of exported var name:", name) } varKeysMu.Lock() defer varKeysMu.Unlock() varKeys = append(varKeys, name) sort.Strings(varKeys) }
// Get retrieves a named exported variable. It returns nil if the name has // not been registered. funcGet(name string)Var { i, _ := vars.Load(name) v, _ := i.(Var) return v }
// Do calls f for each exported variable. // The global variable map is locked during the iteration, // but existing entries may be concurrently updated. funcDo(f func(KeyValue)) { varKeysMu.RLock() defer varKeysMu.RUnlock() for _, k := range varKeys { val, _ := vars.Load(k) f(KeyValue{k, val.(Var)}) } }
expvarHandler(w http.ResponseWriter, r *http.Request),通过http服务器,查看当前所有的公共发布变量,同样保存了机器的命令行启动参数以及内存状态
funcexpvarHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=utf-8") fmt.Fprintf(w, "{\n") first := true Do(func(kv KeyValue) { if !first { fmt.Fprintf(w, ",\n") } first = false fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value) }) fmt.Fprintf(w, "\n}\n") }
// Handler returns the expvar HTTP Handler. // // This is only needed to install the handler in a non-standard location. funcHandler()http.Handler { return http.HandlerFunc(expvarHandler) }