菲葑不弃,敝帚自珍
接口
package main
import(
"fmt"
)
type SendAlgorithm interface{
OnDataAvailable(byte uint32)
GetCongestionWindow() uint64
OnPacketLost()
}
const MinimalWindow uint64=1
const InitialWindow uint64=12
const SSthresh uint64 =30
const Mss uint64 =1500
type CubicSender struct{
CongestionWindow uint64
CwndCnt uint64
total uint64
alpha float32
beta float32
}
func NewCubicSender(a float32,b float32) SendAlgorithm{
return &CubicSender{
CongestionWindow:InitialWindow,
alpha:a,
beta:b,
}
}
func (c*CubicSender)OnDataAvailable(byte uint32){
c.total+=uint64(byte)
c.CwndCnt=uint64(c.total/Mss)
if c.CwndCnt>=c.CongestionWindow{
c.total=0;
c.CongestionWindow++
}
fmt.Printf("%f,%f\n",c.alpha,c.beta)
}
func (c*CubicSender) GetCongestionWindow() uint64{
return c.CongestionWindow
}
func (c*CubicSender) OnPacketLost(){
var cwnd float32 =float32(c.CongestionWindow)*c.beta
c.CongestionWindow=uint64(cwnd)
c.total=0
}
// just some simulation with different a ,b
func NewRenoSender(a float32,b float32) SendAlgorithm{
return &CubicSender{
CongestionWindow:InitialWindow,
alpha:a,
beta:b,
}
}
type State int
const (
TCP_RENO State = iota // value --> 0
TCP_CUBIC // value --> 1
)
type PathManager struct{
senders map[uint32]interface{}
}
func (pm*PathManager) SetUp(id uint32,tcp State,p*Path){
var cong SendAlgorithm
switch(tcp){
case TCP_RENO:
cong=NewRenoSender(1,0.5)
case TCP_CUBIC:
cong=NewRenoSender(1,0.7)
default:
cong=NewRenoSender(1,0.5)
}
p.sendAlgorithm=cong
pm.senders[id]=cong
p.SetUp(pm.senders);
}
type Path struct{
senders map[uint32]interface{}
sendAlgorithm SendAlgorithm
}
func (p*Path)SetUp(senders map[uint32]interface{}){
p.senders=senders
}
func (p*Path) OndataAvailble(byte uint32){
p.sendAlgorithm.OnDataAvailable(byte)
}
func (p*Path) OnPacketLost(){
p.sendAlgorithm.OnPacketLost()
}
func (p*Path) GetTotalCwnd() uint64{
var totalcwnd uint64
for _,s:=range p.senders{
var cubicSender SendAlgorithm=s.(*CubicSender)//this is ok
//var cubicSender SendAlgorithm=s.(SendAlgorithm)//this is ok
//var cubicSender SendAlgorithm=SendAlgorithm(s) this is not work
//cwnd:=s.(SendAlgorithm).GetCongestionWindow() this is ok
cwnd:=cubicSender.GetCongestionWindow()
totalcwnd+=cwnd
}
return totalcwnd
}
func (p*Path) GetPathCwnd() uint64{
return p.sendAlgorithm.GetCongestionWindow()
}
func main(){
pm:=new(PathManager)
pm.senders=make(map[uint32]interface{})
p1:=new(Path)
p2:=new(Path)
pm.SetUp(1,TCP_CUBIC,p1)
pm.SetUp(2,TCP_RENO,p2)
total1:=p1.GetTotalCwnd()
total2:=p2.GetTotalCwnd()
fmt.Printf("%d,%d\n",total1,total2)
pathcwnd:=p1.GetPathCwnd()
fmt.Printf("%d\n",pathcwnd)
}
获取系统时间(毫秒)
package main
import
(
"fmt"
"flag"
"time"
)
type Config struct{
CreatePath *bool
}
func Test(config *Config){
fmt.Println(*config.CreatePath);
}
func GetMilliSeconds() int64{
now := time.Now()
nanos := now.UnixNano()
millis := nanos / 1000000
return millis
}
func main(){
var millis int64=GetMilliSeconds()
verbose := flag.Bool("v", false, "verbose")
multipath := flag.Bool("m", false, "multipath")
output := flag.String("o", "out.txt", "logging output")
flag.Parse()
fmt.Println(*verbose)
fmt.Println(*multipath)
fmt.Println(*output)
var config *Config=new(Config)
config.CreatePath=multipath;
Test(config)
var delta int64=GetMilliSeconds()-millis;
fmt.Println(delta);
}
thus not work.
var config Config=new Config{
CreatePath:multipath,
})
multi value in single value context
package main
import
(
"fmt"
"github.com/emirpasic/gods/lists/arraylist"
"github.com/emirpasic/gods/utils"
)
func first(args ...interface{})interface{} {
return args[0]
}
func main(){
list := arraylist.New()
list.Add("abc") // ["a"]
list.Add("c", "b") // ["a","c","b"]
list.Sort(utils.StringComparator) // ["a","b","c"]
var ele string
ele=first(list.Get(0)).(string)
fmt.Println(ele);
}
ele,=list.Get(0), error, since the first return value is a interface.
but ele,=list.Get(0) would be ok.
interface{} 即为引用
interface cast
import(
"fmt"
"unsafe"
)
var a int32
a=123
var b int64
b=123
var c *int64
c=&b;
var d interface{}
d=&b
var e *int64;
e=d.(*int64)
fmt.Println("size a in main",unsafe.Sizeof(a))
fmt.Println("size b in main",unsafe.Sizeof(b))
fmt.Println("size c in main",unsafe.Sizeof(c))
fmt.Println("size d in main",unsafe.Sizeof(d))
fmt.Println("value e in main",*e)
interface function
package main
import (
"fmt"
)
type StreamSender interface{
onDataAvailable(int32)
}
func Test(sender StreamSender){
sender.onDataAvailable(32);
}
type Session struct{
id int32
}
func (s *Session)onDataAvailable(len int32){
fmt.Printf("sesion %d data len %d\n",s.id,len)
}
func main(){
s:=new(Session);
s.id=1;
Test(s)
}
interface{} to string
package main
import(
"fmt"
"strings"
)
func GetString(value interface{}) int{
return strings.Count(value.(string),"")-1
}
func main(){
s:="hello world"
fmt.Printf("length %d\n",GetString(s))
}
回调
package main
import(
"fmt"
)
type stream struct{
id int
OnIncomingData func(len int)
}
func newStream(id int, cb func(len int)) *stream{
return &stream{
id:id,
OnIncomingData:cb,
}
}
func OnIncomingData(len int){
fmt.Printf("incoming data len %d\n",len)
}
func main(){
stream:=newStream(1,OnIncomingData)
stream.OnIncomingData(1400)
}