func test1() { var a [1000]*S for i := 0; i < len(a); i++ { a[i] = new(S).Init(i) } v := new(vector.Vector) for i := 0; i < len(a); i++ { v.Insert(0, a[i]) if v.Len() != i+1 { panic("len = ", v.Len(), "\n") } } for i := 0; i < v.Len(); i++ { x := v.At(i).(*S) if x.val != v.Len()-i-1 { panic("expected ", i, ", found ", x.val, "\n") } } for v.Len() > 10 { v.Delete(10) } }
func (self DocumentMutation) applyArrayMutation(arr []interface{}, mutation ArrayMutation, flags uint32) []interface{} { index := 0 var v vec.Vector = arr // Find the lifts lifts := make(map[string]interface{}) for _, mut := range mutation.Array() { switch { case IsInsertMutation(mut), IsSqueezeMutation(mut): continue case IsDeleteMutation(mut): index += toDeleteMutation(mut).Count() case IsSkipMutation(mut): index += toSkipMutation(mut).Count() case IsObjectMutation(mut), IsArrayMutation(mut), IsTextMutation(mut): index++ case IsLiftMutation(mut): l := toLiftMutation(mut) val := v[index] if l.HasMutation() { val = self.apply(val, l.Mutation(), flags) } lifts[l.Id()] = val index++ default: panic("Should never happen") } } index = 0 for _, m := range mutation.Array() { switch { case IsDeleteMutation(m): count := toDeleteMutation(m).Count() for i := 0; i < count; i++ { v.Delete(i) } case IsSkipMutation(m): index += toSkipMutation(m).Count() case IsLiftMutation(m): v.Delete(index) case IsSqueezeMutation(m): v.Insert(index, lifts[toSqueezeMutation(m).Id()]) index++ case IsObjectMutation(m), IsArrayMutation(m), IsTextMutation(m): v[index] = self.apply(v[index], m, flags) index++ default: // Must be an insert mutation v.Insert(index, self.apply(nil, m, flags)) index++ } } return v }
func (self Transformer) split(arr *vec.Vector, index, inside int) { mut := arr.At(index) if IsDeleteMutation(mut) { arr.Insert(index+1, NewDeleteMutation(toDeleteMutation(mut).Count()-inside)) toDeleteMutation(mut).SetCount(inside) } else if IsSkipMutation(mut) { arr.Insert(index+1, NewSkipMutation(toSkipMutation(mut).Count()-inside)) toSkipMutation(mut).SetCount(inside) } else { panic("Unsupported mutation for split()") } }
func (self Transformer) transform_pass1_text(sobj, cobj TextMutation) os.Error { var ( sarr vec.Vector = sobj.Array() carr vec.Vector = cobj.Array() sindex int = 0 cindex int = 0 sinside int = 0 cinside int = 0 ) // Loop until end of one mutation is reached for sindex < len(sarr) || cindex < len(carr) { var smut, cmut interface{} if sindex < len(sarr) { smut = sarr[sindex] } if cindex < len(carr) { cmut = carr[cindex] } // Server insertions go first if IsInsertMutation(smut) { // In the middle of a client skip/delete? Split it if cinside > 0 { self.split(&carr, cindex, cinside) cinside = 0 cindex++ cmut = carr[cindex] } str, err := smut.(string) if !err { panic("Only strings allowed inside a text mutation") } sindex++ if len(str) > 0 { carr.Insert(cindex, NewSkipMutation(len(str))) cindex++ } continue } // Client insertions go next if IsInsertMutation(cmut) { // In the middle of a server skip/delete? Split it if sinside > 0 { self.split(&sarr, sindex, sinside) sinside = 0 sindex++ smut = sarr[sindex] } str, err := cmut.(string) if !err { return os.NewError("Only strings allowed inside a text mutation") } cindex++ if len(str) > 0 { sarr.Insert(sindex, NewSkipMutation(len(str))) sindex++ } continue } if sindex == len(sarr) && cindex == len(carr) { break } if sindex == len(sarr) || cindex == len(carr) { return os.NewError("The mutations do not have equal length") } if IsDeleteMutation(smut) && IsDeleteMutation(cmut) { sdel := toDeleteMutation(smut).Count() cdel := toDeleteMutation(cmut).Count() del := IntMin(sdel-sinside, cdel-cinside) sindex, sinside = self.shorten(sarr, sindex, sinside, del) cindex, cinside = self.shorten(carr, cindex, cinside, del) } else if IsSkipMutation(smut) && IsSkipMutation(cmut) { sskip := toSkipMutation(smut).Count() cskip := toSkipMutation(cmut).Count() skip := IntMin(sskip-sinside, cskip-cinside) sinside += skip cinside += skip if sinside == sskip { sinside = 0 sindex++ } if cinside == cskip { cinside = 0 cindex++ } } else if IsDeleteMutation(smut) && IsSkipMutation(cmut) { sdel := toDeleteMutation(smut).Count() cskip := toSkipMutation(cmut).Count() count := IntMin(sdel-sinside, cskip-cinside) sinside += count if sinside == sdel { sinside = 0 sindex++ } cindex, cinside = self.shorten(carr, cindex, cinside, count) } else if IsSkipMutation(smut) && IsDeleteMutation(cmut) { sskip := toSkipMutation(smut).Count() cdel := toDeleteMutation(cmut).Count() count := IntMin(sskip-sinside, cdel-cinside) sindex, sinside = self.shorten(sarr, sindex, sinside, count) cinside += count if cinside == cdel { cinside = 0 cindex++ } } else { return os.NewError(fmt.Sprintf("Mutation not allowed in a text mutation:\n%v %v\n%v %v", smut, IsSkipMutation(smut), cmut, IsSkipMutation(cmut))) } } sobj.SetArray(sarr) cobj.SetArray(carr) return nil }
func (self Transformer) transform_pass1_array(sobj, cobj ArrayMutation) os.Error { var ( sarr vec.Vector = sobj.Array() carr vec.Vector = cobj.Array() sindex int = 0 cindex int = 0 sinside int = 0 cinside int = 0 ) // Loop until end of one mutation is reached for sindex < len(sarr) || cindex < len(carr) { var smut, cmut interface{} if sindex < len(sarr) { smut = sarr[sindex] } if cindex < len(carr) { cmut = carr[cindex] } // Server insert/squeeze go first for IsInsertMutation(smut) || IsSqueezeMutation(smut) { if cinside > 0 { self.split(&carr, cindex, cinside) cinside = 0 cindex++ cmut = carr[cindex] } if IsInsertMutation(smut) { // TODO: check the Insert mutation individually for correctness carr.Insert(cindex, NewSkipMutation(1)) cindex++ sindex++ } else if IsSqueezeMutation(smut) { sSqueeze := toSqueezeMutation(smut) // Which operation does the client side have for this object? c, hasCounterpart := self.cLiftCounterpart[sSqueeze.Id()] if !hasCounterpart || IsSkipMutation(c) { // Server lift remains, client skips it at the new position carr.Insert(cindex, NewSkipMutation(1)) cindex++ sindex++ } else if IsDeleteMutation(c) { // Client deletes the object at its new position carr.Insert(cindex, NewDeleteMutation(1)) cindex++ // Server removes squeeze because it is already deleted by the client sarr.Delete(sindex) } else if IsLiftMutation(c) { // sLift := self.sLifts[sSqueeze.Id()] cLift := toLiftMutation(c) if cLift.HasMutation() { // The client does not lift it and therefore it mutates it at the new position carr.Insert(cindex, cLift.Mutation()) cindex++ // Server keeps its squeeze at this position sindex++ } else { // Client skips the squeezed object and does not lift it carr.Insert(cindex, NewSkipMutation(1)) cindex++ // Server keeps its squeeze at this position sindex++ } } else { // The client somehow mutates the object. It must do so at its new position carr.Insert(cindex, c) cindex++ sindex++ } } if sindex < len(sarr) { smut = sarr[sindex] } else { smut = nil } } // Client insert/squeeze go next for IsInsertMutation(cmut) || IsSqueezeMutation(cmut) { if sinside > 0 { self.split(&sarr, sindex, sinside) sinside = 0 sindex++ smut = sarr[sindex] } if IsInsertMutation(cmut) { // TODO: check the Insert mutation individually for correctness cindex++ sarr.Insert(sindex, NewSkipMutation(1)) sindex++ } else { cSqueeze := toSqueezeMutation(cmut) // Which operation does the server side have for this object? s, hasCounterpart := self.sLiftCounterpart[cSqueeze.Id()] if !hasCounterpart || IsSkipMutation(s) { sarr.Insert(sindex, NewSkipMutation(1)) sindex++ cindex++ } else if IsDeleteMutation(s) { // Server deletes the object at its the new position sarr.Insert(sindex, NewDeleteMutation(1)) sindex++ // Client removes squeeze because it is already deleted by the client carr.Delete(cindex) } else if IsLiftMutation(s) { // The server must lift the object here instead sarr.Insert(sindex, s) sindex++ // The server lifted this object as well -> the client cannot lift it -> // then the client cannot squeeze it in here carr.Delete(cindex) } else { // The server mutates the object at its new position sarr.Insert(sindex, s) sindex++ // The client squeezes the object in here cindex++ } } if cindex < len(carr) { cmut = carr[sindex] } else { cmut = nil } } if sindex == len(sarr) && cindex == len(carr) { break } if sindex == len(sarr) || cindex == len(carr) { return os.NewError("The mutations do not have equal length") } // // Lift, Skip, Delete, mutations // if IsLiftMutation(smut) { // Both are lifting the same object? if IsLiftMutation(cmut) { // The client removes its lift. If it has a mutation then it will be moved to the corresponding squeeze carr.Delete(cindex) // The server removes its lift. It will be placed where the client moved it. sarr.Delete(sindex) } else if IsDeleteMutation(cmut) { // The server does not lift the object because it is deleted sarr.Delete(sindex) // The client removes its delete. The delete is put where the server squeezed it. cindex, cinside = self.shorten(carr, cindex, cinside, 1) } else if IsSkipMutation(cmut) { // The client does not skip this element here. It is skipped where it is squeezed in cindex, cinside = self.shorten(carr, cindex, cinside, 1) // Server remains with its lift sindex++ } else { // Q_ASSERT(cmut.isArrayMutation() || cmut.isObjectMutation() || cmut.isTextMutation() || cmut.isRichTextMutation() ); // The client removes its mutation here. It is shifted to the new position where the object is squeezed in. carr.Delete(cindex) // Server remains with its lift sindex++ } } else if IsLiftMutation(cmut) { if IsDeleteMutation(smut) { // The client does not lift the object because it is deleted carr.Delete(cindex) // The server removes its delete. The delete is put where the client squeezed it. sindex, sinside = self.shorten(sarr, sindex, sinside, 1) } else if IsSkipMutation(smut) { // The server does not skip this element here. It is skipped where it is squeezed in sindex, sinside = self.shorten(sarr, sindex, sinside, 1) // Client remains with its lift cindex++ } else { // Q_ASSERT(smut.isArrayMutation() || smut.isObjectMutation() || smut.isTextMutation() || smut.isRichTextMutation() ); // The server removes its mutation here. It is shifted to the new position where the object is squeezed in. sarr.Delete(sindex) // Client remains with its lift cindex++ } } else if IsDeleteMutation(smut) && IsDeleteMutation(cmut) { sdel := toDeleteMutation(smut).Count() cdel := toDeleteMutation(cmut).Count() del := IntMin(sdel-sinside, cdel-cinside) sindex, sinside = self.shorten(sarr, sindex, sinside, del) cindex, cinside = self.shorten(carr, cindex, cinside, del) } else if IsSkipMutation(smut) && IsSkipMutation(cmut) { sskip := toSkipMutation(smut).Count() cskip := toSkipMutation(cmut).Count() skip := IntMin(sskip-sinside, cskip-cinside) sinside += skip cinside += skip if sinside == sskip { sinside = 0 sindex++ } if cinside == cskip { cinside = 0 cindex++ } } else if IsDeleteMutation(smut) && IsSkipMutation(cmut) { sdel := toDeleteMutation(smut).Count() cskip := toSkipMutation(cmut).Count() count := IntMin(sdel-sinside, cskip-cinside) sinside += count if sinside == sdel { sinside = 0 sindex++ } cindex, cinside = self.shorten(carr, cindex, cinside, count) } else if IsSkipMutation(smut) && IsDeleteMutation(cmut) { sskip := toSkipMutation(smut).Count() cdel := toDeleteMutation(cmut).Count() count := IntMin(sskip-sinside, cdel-cinside) sindex, sinside = self.shorten(sarr, sindex, sinside, count) cinside += count if cinside == cdel { cinside = 0 cindex++ } } else if IsSkipMutation(smut) { // ... and mutation at the client cindex++ sinside++ if toSkipMutation(smut).Count() == sinside { sinside = 0 sindex++ } } else if IsSkipMutation(cmut) { // ... and mutation at the srver sindex++ cinside++ if toSkipMutation(cmut).Count() == cinside { cinside = 0 cindex++ } } else if IsDeleteMutation(smut) { // ... and mutation at the client carr.Delete(cindex) sinside++ if toDeleteMutation(smut).Count() == sinside { sinside = 0 sindex++ } } else if IsDeleteMutation(cmut) { // ... and mutation at the server sarr.Delete(sindex) cinside++ if toDeleteMutation(cmut).Count() == cinside { cinside = 0 cindex++ } } else { if IsObjectMutation(smut) && IsObjectMutation(cmut) { if err := self.transform_pass1_object(toObjectMutation(smut), toObjectMutation(cmut)); err != nil { return err } } else if IsArrayMutation(smut) && IsArrayMutation(cmut) { if err := self.transform_pass1_array(toArrayMutation(smut), toArrayMutation(cmut)); err != nil { return err } } else if IsTextMutation(smut) && IsTextMutation(cmut) { if err := self.transform_pass1_text(toTextMutation(smut), toTextMutation(cmut)); err != nil { return err } } else if IsRichTextMutation(smut) && IsRichTextMutation(cmut) { if err := self.transform_pass1_richtext(toRichTextMutation(smut), toRichTextMutation(cmut)); err != nil { return err } } else { return os.NewError("The mutations are not compatible or not allowed inside an array mutation") } sindex++ cindex++ } } sobj.SetArray(sarr) cobj.SetArray(carr) return nil }
func (self DocumentMutation) applyRichTextMutation(obj map[string]interface{}, mutation RichTextMutation, flags uint32) { if flags&CreateIDs == CreateIDs { if _, ok := obj["_id"]; !ok { obj["_id"] = uniqueId() } obj["_rev"] = self.AppliedAtRevision() } var text vec.Vector = obj["text"].([]interface{}) index := 0 inside := 0 for _, m := range mutation.TextArray() { switch { case IsDeleteMutation(m): count := toDeleteMutation(m).Count() for count > 0 { if str, ok := text[index].(string); ok { l := min(len(str)-inside, count) // inside += l // str = str[inside:] str = str[:inside] + str[inside+l:] if len(str) == 0 { text.Delete(index) inside = 0 } else if inside == len(str) { text[index] = str index++ inside = 0 } else { text[index] = str } count -= l } else { inside = 0 text.Delete(index) count-- } } // ** Ended up in the middle between two strings? -> Join them ** if inside == 0 && index < len(text) { if str1, ok := text[index-1].(string); ok { if str2, ok := text[index].(string); ok { text[index-1] = str1 + str2 text.Delete(index) index-- inside = len(str1) continue } } } else if index < len(text)-1 { if str1, ok := text[index].(string); inside == len(str1) && ok { if str2, ok := text[index+1].(string); ok { text[index] = str1 + str2 inside = len(str1) text.Delete(index + 1) continue } } } case IsSkipMutation(m): count := toSkipMutation(m).Count() for count > 0 { if str, ok := text[index].(string); ok { l := min(len(str)-inside, count) inside += l count -= count if inside == len(str) { index++ inside = 0 } } else { inside = 0 index++ count-- } } default: // *** A string? *** if s, ok := m.(string); ok { // Appending to a string? if inside == 0 && index > 0 { if str, ok := text[index-1].(string); ok { text[index-1] = str + s continue } } // End of string? if index == len(text) { text.Insert(index, s) index++ continue } // Prepending/Inserting to an existing string? if str, ok := text[index].(string); ok { // Insert into an existing string ? text[index] = str[0:inside] + s + str[inside:] inside += len(str) continue } // Insert in front of an object text.Insert(index, s) index++ continue } // *** Insert an object *** if index < len(text) && inside > 0 && inside == len(text[index].(string)) { // End of string? inside = 0 index++ } // Middle of a string -> split it if inside > 0 { str := text[index].(string) text.Insert(index+1, str[inside:]) text[index] = str[:inside] text.Insert(index+1, m) inside = 0 index += 2 } else { text.Insert(index, m) index++ } } } obj["text"] = []interface{}(text) }
func parse_forth(dat string, DataStack *vector.Vector) { L := DataStack.Len() switch strings.TrimSpace(string(dat)) { case "": case "<cr>": return case "t": //check the DataStack size using the popped value // if it passes, then the program continues minimum := int(DataStack.Pop().(float32)) if DataStack.Len() < minimum { log.Println("DataStack has not enough minerals (values)") } case ".": log.Println(DataStack.Pop()) case "0SP": DataStack.Cut(0, L) case ".S": log.Println(DataStack) case "2/": DataStack.Push(DataStack.Pop().(float32) / 2) case "2*": DataStack.Push(DataStack.Pop().(float32) * 2) case "2-": DataStack.Push(DataStack.Pop().(float32) - 2) case "2+": DataStack.Push(DataStack.Pop().(float32) + 2) case "1-": DataStack.Push(DataStack.Pop().(float32) - 1) case "1+": DataStack.Push(DataStack.Pop().(float32) + 1) case "DUP": DataStack.Push(DataStack.Last()) case "?DUP": if DataStack.Last().(float32) != 0 { DataStack.Push(DataStack.Last().(float32)) } case "PICK": number := int(DataStack.Pop().(float32)) if number < L { DataStack.Push(DataStack.At(L - 1 - number).(float32)) } else { log.Fatal("picking out of stack not allowed. Stack Length: " + string(L) + ". Selecting: " + string(number) + ".") return } case "TUCK": DataStack.Insert(L-2, int(DataStack.Last().(float32))) case "NIP": DataStack.Delete(L - 2) case "2DROP": DataStack.Pop() DataStack.Pop() case "2DUP": DataStack.Push(DataStack.At(L - 2)) DataStack.Push(DataStack.At(DataStack.Len() - 2)) case "DROP": DataStack.Pop() case "OVER": DataStack.Push(DataStack.At(L - 2)) case "SWAP": l := DataStack.Len() DataStack.Swap(l-2, l-1) case "*": num1 := DataStack.Pop().(float32) num2 := DataStack.Pop().(float32) DataStack.Push(num1 * num2) case "+": num1 := DataStack.Pop().(float32) num2 := DataStack.Pop().(float32) DataStack.Push(num1 + num2) case "-": num1 := DataStack.Pop().(float32) num2 := DataStack.Pop().(float32) DataStack.Push(num2 - num1) case "/": num1 := DataStack.Pop().(float32) num2 := DataStack.Pop().(float32) DataStack.Push(num2 / num1) case "-ROT": DataStack.Swap(L-1, L-2) DataStack.Swap(L-2, L-3) case "ROT": DataStack.Swap(L-3, L-2) DataStack.Swap(L-2, L-1) case "2OVER": DataStack.Push(DataStack.At(L - 4)) DataStack.Push(DataStack.At(DataStack.Len() - 4)) case "2SWAP": DataStack.Swap(L-4, L-2) DataStack.Swap(L-3, L-1) case "EMIT": log.Println(string([]byte{uint8(DataStack.Last().(float32))})) default: val, ok := strconv.Atof32(dat) if ok == nil { DataStack.Push(val) } else { log.Println(ok) log.Fatalln("error, unknown token \"" + dat + "\"") } } }
func (dbs *DBS) channelHopping() { //pour trier les connections actives var MobileList vector.Vector //pour trier les canaux dbs.RandomChan() // find a mobile for e := dbs.Connec.Front(); e != nil; e = e.Next() { c := e.Value.(*Connection) if c.Status == 0 { // only change if master if c.E.GetCh() == 0 { //if the mobile is waiting to be assigned a proper channel var ratio float64 nch := 0 //Parse channels in some order given by dbs.RndCh to find a suitable channel for j := NChRes; j < NCh; j++ { i := dbs.RndCh[j] if !dbs.IsInUse(i) && i != c.E.GetCh() { _, snr, _, _ := dbs.R.EvalSignalSNR(c.E, i) if 10*math.Log10(snr) > SNRThresChHop { if snr > ratio { ratio = snr nch = i //assign and exit } } } } if nch != 0 { dbs.changeChannel(c, nch) return } // sort mobile connection for channel hopping } else { ratio := c.EvalRatio(dbs.R) var i int for i = 0; i < MobileList.Len(); i++ { co := MobileList.At(i).(ConnecType) if ratio < co.EvalRatio(dbs.R) { break } } MobileList.Insert(i, c) } } } // change channel to some mobiles for k := 0; k < MobileList.Len() && k < 2; k++ { co := MobileList.At(k).(ConnecType) ratio := co.EvalRatio(dbs.R) chHop := 0 for j := NChRes; j < NCh; j++ { i := dbs.RndCh[j] if !dbs.IsInUse(i) && i != co.GetE().GetCh() { _, snr, _, _ := dbs.R.EvalSignalSNR(co.GetE(), i) if snr > ratio { ratio = snr chHop = i } } } if chHop > 0 { dbs.changeChannel(co, chHop) Hopcount++ } } }
func (dbs *DBS) channelHopping2() { //pour trier les connections actives var MobileList vector.Vector //pour trier les canaux dbs.RandomChan() // find a mobile for e := dbs.Connec.Front(); e != nil; e = e.Next() { c := e.Value.(*Connection) if c.Status == 0 { // only change if master if c.E.GetCh() == 0 { //if the mobile is waiting to be assigned a proper channel var ratio float64 nch := 0 //Parse channels in some order given by dbs.RndCh to find a suitable channel for j := NChRes; j < NCh; j++ { i := dbs.RndCh[j] if !dbs.IsInUse(i) && i != c.E.GetCh() { _, ber, snr, _ := dbs.R.EvalSignalBER(c.E, i) if ber < math.Log10(BERThres/10) { if snr > ratio { ratio = snr nch = i //assign and exit } } } } if nch != 0 { dbs.changeChannel(c, nch) return } // sort mobile connection for channel hopping } else { ratio := c.EvalRatio(dbs.R) var i int for i = 0; i < MobileList.Len(); i++ { co := MobileList.At(i).(ConnecType) if ratio < co.EvalRatio(dbs.R) { break } } MobileList.Insert(i, c) } } } // change channel to some mobiles for k := 0; k < MobileList.Len() && k < 15; k++ { co := MobileList.At(k).(ConnecType) //ratio := co.EvalRatio(&dbs.R) d := co.GetE().GetPos().Distance(dbs.R.GetPos()) //if (10*math.Log10(co.GetSNR())< SNRThres){ //var ir int //ir:= NCh-NChRes + (6+int(math.Log10(Pr))) //if d<100 {ir=28 //}else {ir=0} // ir:= NCh-NChRes + int(( -float(d)/1500*float(NCh-NChRes) )) //if (ir<0) {ir=0} // if ir> NCh-2 {ir=NCh-2} ir := 5 if d < 300 { if !(co.GetE().GetCh() > NCh-ir) || (co.GetSNR() < SNRThresChHop-3) { for j := NCh - ir; j < NCh; j++ { i := dbs.RndCh[j] if !dbs.IsInUse(i) && i != co.GetE().GetCh() { _, snr, _, _ := dbs.R.EvalSignalSNR(co.GetE(), i) if snr > SNRThresChHop { dbs.changeChannel(co, i) Hopcount++ break } } } } } else { if !(co.GetE().GetCh() < NCh-ir) || (co.GetSNR() < SNRThresChHop-3) { for j := NChRes; j < NCh-ir; j++ { i := dbs.RndCh[j] if !dbs.IsInUse(i) && i != co.GetE().GetCh() { _, snr, _, _ := dbs.R.EvalSignalSNR(co.GetE(), i) if snr > SNRThresChHop { dbs.changeChannel(co, i) Hopcount++ break } } } } } } //} /* for k := 0; k < MobileList.Len() && k < 1; k++ { co := MobileList.At(k).(ConnecType) ratio := co.EvalRatio(&dbs.R) if (Pr<8e-9) && co.GetE().GetCh()>NCh-3{ //push down for j := NChRes; j < NCh; j++ { i := dbs.RndCh[j] if !dbs.IsInUse(i) && i != co.GetE().GetCh() { Rnew, ev, Pr:=dbs.R.EvalSignalBER(co.E,i) if Pr/(Rnew.Pint+WNoise) > ratio/2 { dbs.changeChannel(co, i) Hopcount++ break } } }} else{ //push up for j := NCh-2; j < NCh; j++ { i := dbs.RndCh[j] if !dbs.IsInUse(i) && i != co.GetE().GetCh() { Rnew, ev, Pr:=dbs.R.EvalSignalBER(co.E,i) if Pr/(Rnew.Pint+WNoise) > ratio/2 { dbs.changeChannel(co, i) Hopcount++ break } } }} } */ }