示例#1
0
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)
	}
}
示例#2
0
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
}
示例#3
0
文件: ot.go 项目: AaronO/lightwave
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()")
	}
}
示例#4
0
文件: ot.go 项目: AaronO/lightwave
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
}
示例#5
0
文件: ot.go 项目: AaronO/lightwave
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
}
示例#6
0
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)
}
示例#7
0
文件: main.go 项目: nunb/GoForth
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 + "\"")
		}
	}
}
示例#8
0
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++
		}

	}

}
示例#9
0
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
					}
				}
			}}


		}
	*/

}