예제 #1
0
func Overcapacity(i int) string {
	deck := deque.New(i)
	for j := 1; j <= i; j++ {
		deck.Push(j)
	}
	for j := 1; j <= i; j++ {
		deck.Pop()
	}
	// now the internal buffer is filled with the numbers 1,...,i
	raw, _ := deck.Raw(-1)
	if len(raw) != i {
		return fmt.Sprintf("len(%v) != %v", raw, i)
	}
	if cap(raw) != i {
		return fmt.Sprintf("cap(%v) != %v", raw, i)
	}
	if deck.Overcapacity(uint(i)) != deck {
		return fmt.Sprintf("Overcapacity(%v) does not return self", i)
	}
	deck.CheckInvariant()
	raw2, _ := deck.Raw(-1)
	if fmt.Sprintf("%v", raw2) != fmt.Sprintf("%v", raw) {
		return fmt.Sprintf("Overcapacity(i) with i==Capacity() must leave internal buffer untouched")
	}

	data := []interface{}{"bar", 1, 2, 3, 4, 5, 6, 7, 8, 9, "foo"}
	for _, rotation := range []int{0, 1, 4, 7, len(data) - 1, len(data) - 2} {
		deck = deque.New(data)
		deck.Raw(rotation)
		deck.CheckInvariant()
		for j := 0; j <= i; j++ {
			if deck.Overcapacity(uint(j)) != deck {
				return fmt.Sprintf("Overcapacity(%v) does not return self", j)
			}
			res := Deque(deck, data...)
			if res != "" {
				return res
			}
			if deck.Capacity() != len(data)+j {
				return fmt.Sprintf("Overcapacity(%v) resulted in %v", j, deck.Capacity()-len(data))
			}
		}
		for j := i; j >= 0; j-- {
			deck.Raw(i >> 1)
			if deck.Overcapacity(uint(j)) != deck {
				return fmt.Sprintf("Overcapacity(%v) does not return self", j)
			}
			res := Deque(deck, data...)
			if res != "" {
				return res
			}
			if deck.Capacity() != len(data)+j {
				return fmt.Sprintf("Overcapacity(%v) resulted in %v", j, deck.Capacity()-len(data))
			}
		}
	}

	return ""
}
예제 #2
0
func Search(item int, x ...int) int {
	deck := deque.New(len(x) * 2)
	for _, xx := range x {
		deck.Push(xx)
	}
	return deck.Search(item, intcmp)
}
예제 #3
0
func Insert(maxcapacity int) string {
	for capa := 0; capa <= maxcapacity; capa++ {
		for sz := 0; sz <= capa; sz++ {
			testdata := []interface{}{}
			for n := 1; n <= sz; n++ {
				testdata = append(testdata, n)
			}
			for a := 0; a < capa; a++ {
				for idx := -2; idx <= capa+2; idx++ {
					testdeque := deque.New(capa, testdata)
					_, rawidx := testdeque.Raw(a)
					if rawidx != a {
						return fmt.Sprintf("Raw(%v) is broken", a)
					}
					var res bool
					if idx >= 0 && idx <= len(testdata) {
						res = true
					}
					x := testdeque.InsertAt(idx, "foo")
					if x != res {
						return fmt.Sprintf("After Raw(%v) Deque(%v,%v).InsertAt(%v) == %v but should be %v", a, capa, testdata, idx, x, res)
					}
					var testdata2 []interface{}
					if x {
						testdata2 = make([]interface{}, len(testdata)+1)
						copy(testdata2[0:idx], testdata[0:idx])
						testdata2[idx] = "foo"
						copy(testdata2[idx+1:], testdata[idx:])
					} else {
						testdata2 = testdata
					}
					ck := Deque(testdeque, testdata2...)
					if ck != "" {
						return ck
					}
				}
			}
		}
	}
	return ""
}
예제 #4
0
// Returns all system templates that apply to the given system (which may be
// incomplete).
//
// The format of the reply is:
//   <systemdb>
//     <xml>
//       <dn>...</dn>
//       <objectclass>objectclass_1</objectclass>
//       <objectclass>objectclass_2</objectclass>
//       ...
//     </xml>
//     <xml>
//       <dn>...</dn>
//       ...
//     </xml>
//     ...
//   </systemdb>
//
// The order of the template objects is such that the first entry is the
// best match (i.e. the template with the most specific matching rules).
// See "detected_hardware" documentation in the go-susi operator's manual for
// information on how to mark a system object as a template and how to specify
// the systems to which it should apply.
//
// If there is no matching template, the returned hash is <systemdb></systemdb>.
//
// NOTE: The returned template objects always contain only the attributes from
// the objects themselves, not from any groups they may be members of.
//
// ATTENTION! This function accesses LDAP and may therefore take a while.
// If possible you should use it asynchronously.
func SystemGetTemplatesFor(system *xml.Hash) *xml.Hash {
	// ATTENTION: No space between "for" and "*" because there may be some other
	// kind of whitespace (such as CR)
	x, err := xml.LdifToHash("xml", true, ldapSearch(fmt.Sprintf("(&(objectClass=GOhard)(gocomment=Template for*/*/*)%v)", config.UnitTagFilter)))
	if err != nil {
		util.Log(0, "ERROR! LDAP error while looking for template objects: %v", err)
		return xml.NewHash("systemdb")
	}

	templates := deque.New()                                              // templates.At(0) is the most specific match
	templates.Push(xml.NewHash("xml", "TEMPLATE_MATCH_SPECIFICITY", "0")) //sentinel

	for t := x.RemoveFirst("xml"); t != nil; t = x.RemoveFirst("xml") {
		specificity := templateMatch(system, t.Text("gocomment"))
		if specificity > 0 {
			t.Add("TEMPLATE_MATCH_SPECIFICITY", specificity)
			for i := 0; i < templates.Count(); i++ {
				tspec, _ := strconv.Atoi(templates.At(i).(*xml.Hash).Text("TEMPLATE_MATCH_SPECIFICITY"))
				if specificity >= tspec {
					templates.InsertAt(i, t)
					break
				}
			}
		}
	}

	templates.Pop() // remove sentinel

	ret := xml.NewHash("systemdb")

	for !templates.IsEmpty() {
		t := templates.Next().(*xml.Hash)
		t.RemoveFirst("TEMPLATE_MATCH_SPECIFICITY")
		ret.AddWithOwnership(t)
	}

	return ret
}
예제 #5
0
// Unit tests for the package github.com/mbenkmann/golib/deque.
func Deque_test() {
	fmt.Printf("\n==== deque ===\n\n")

	whatever := []uint{0, 1, 2, 3, 4, 5, 21, 127, 200}
	zero := []uint{0}
	one := []uint{1}
	check(Growth(deque.Double, zero, zero, whatever, one), "")
	check(Growth(deque.Double, zero, one, whatever, one), "")
	check(Growth(deque.Double, []uint{1, 2, 3, 4, 8, 16, 32, 111}, one, []uint{11}, []uint{1, 2, 3, 4, 8, 16, 32, 111}), "")
	check(Growth(deque.Double, []uint{1, 2, 3, 4, 8, 16, 32, 111}, []uint{11}, []uint{11}, []uint{15, 14, 21, 12, 24, 16, 32, 111}), "")

	deque.GrowthFactor = 0
	check(Growth(deque.Exponential, whatever, zero, zero, one), "")
	check(Growth(deque.Exponential, whatever, one, zero, one), "")
	check(Growth(deque.Exponential, whatever, one, one, []uint{2}), "")
	check(Growth(deque.Exponential, whatever, one, []uint{2}, []uint{4}), "")
	deque.GrowthFactor = 7
	check(Growth(deque.Exponential, []uint{666}, one, []uint{0, 1, 2, 3, 4}, []uint{7, 14, 28, 56, 112}), "")
	check(Growth(deque.Exponential, []uint{666}, []uint{30}, []uint{0, 1, 2, 3, 4}, []uint{56, 56, 56, 56, 112}), "")

	deque.GrowthFactor = 0
	var i uint
	for i = 0; i < 5; i++ {
		check(Growth(deque.Accelerated, whatever, []uint{i}, whatever, []uint{i}), "")
	}

	deque.GrowthFactor = 7
	check(Growth(deque.Accelerated, []uint{111}, one, []uint{0, 1, 2, 3, 4}, []uint{7, 14, 21, 28, 35}), "")

	check(Growth(deque.GrowBy(0), []uint{111}, []uint{0, 1, 2, 3, 4, 5, 6, 7, 8}, []uint{222}, []uint{0, 1, 2, 3, 4, 5, 6, 7, 8}), "")
	check(Growth(deque.GrowBy(1), []uint{111}, []uint{0, 1, 2, 3, 4, 5, 6, 7, 8}, []uint{222}, []uint{1, 1, 2, 3, 4, 5, 6, 7, 8}), "")
	check(Growth(deque.GrowBy(2), []uint{111}, []uint{0, 1, 2, 3, 4, 5, 6, 7, 8}, []uint{222}, []uint{2, 2, 2, 3, 4, 5, 6, 7, 8}), "")
	check(Growth(deque.GrowBy(3), []uint{111}, []uint{0, 1, 2, 3, 4, 5, 6, 7, 8}, []uint{222}, []uint{3, 3, 3, 3, 4, 5, 6, 7, 8}), "")

	check(Growth(deque.BlockIfFull, whatever, whatever, whatever, zero), "")

	func() {
		defer func() {
			check(recover(), deque.Overflow)
		}()
		deque.PanicIfOverflow(1, 2, 3)
	}()

	d2 := deque.New(deque.GrowthFunc(deque.Exponential))
	d2.CheckInvariant()
	check(d2.Growth, deque.Exponential)

	check(deque.New(111).Capacity(), 111)
	check(deque.New(22, []interface{}{1, "foo", 2, "bar"}, 111).Capacity(), 111)
	check(deque.New([]interface{}{1, "foo", 2, "bar"}, 2).Capacity(), 4)
	d1 := deque.New([]interface{}{1, "foo", 2, "bar"}, 2, deque.Accelerated, []interface{}{3, "foobar", 10, "xxx", "yyy"})
	check(Deque(d1, 1, "foo", 2, "bar", 3, "foobar", 10, "xxx", "yyy"), "")
	check(d1.Capacity(), 9)
	check(d1.Growth, deque.Accelerated)
	d1.Init([]interface{}{"bla", "argl", "bart"}, d1, []interface{}{}, []interface{}{"mark", "susi", "karl", "peter"}, []interface{}{}, d1)
	check(Deque(d1, "bla", "argl", "bart", 1, "foo", 2, "bar", 3, "foobar", 10, "xxx", "yyy", "mark", "susi", "karl", "peter", 1, "foo", 2, "bar", 3, "foobar", 10, "xxx", "yyy"), "")
	check(d1.Capacity(), 25)
	check(d1.Count(), 25)
	check(d1.String(), "Deque[bla argl bart 1 foo 2 bar 3 foobar 10 xxx yyy mark susi karl peter 1 foo 2 bar 3 foobar 10 xxx yyy]")
	check(deque.New().String(), "Deque[]")
	check(deque.New([]interface{}{"foobar"}).String(), "Deque[foobar]")

	var stack deque.Deque
	check(Deque(&stack), "")
	check(stack.Capacity(), deque.CapacityDefault)
	stack.Push(1)
	stack.Push(2)
	stack.Push(3)
	stack.Push(4)
	stack.Push(5)
	check(Deque(&stack, 1, 2, 3, 4, 5), "")
	check(stack.Next(), 1)
	check(Deque(&stack, 2, 3, 4, 5), "")
	check(stack.Next(), 2)
	check(Deque(&stack, 3, 4, 5), "")
	check(stack.Pop(), 5)
	check(Deque(&stack, 3, 4), "")
	check(stack.Next(), 3)
	check(Deque(&stack, 4), "")
	check(stack.Pop().(int), 4)
	check(Deque(&stack), "")
	go func() {
		time.Sleep(1 * time.Second)
		stack.Insert("foo")
		time.Sleep(1 * time.Second)
		stack.Insert("bar")
	}()
	check(stack.Pop().(string), "foo")
	check(Deque(&stack), "")
	check(stack.Next(), "bar")
	check(Deque(&stack), "")

	check(Remove(11), "")
	check(Insert(11), "")

	deck := deque.New([]interface{}{1})
	check(Wait(deck, (*deque.Deque).WaitForItem, true, 0), "")
	check(Wait(deque.New(), (*deque.Deque).WaitForItem, false, 3*time.Second), "")
	deck.Init()
	go func() {
		time.Sleep(1 * time.Second)
		deck.Push(1)
	}()
	check(Wait(deck, (*deque.Deque).WaitForItem, true, 1*time.Second), "")
	deck.Init()
	go func() {
		time.Sleep(1 * time.Second)
		deck.Init()
	}()
	check(Wait(deck, (*deque.Deque).WaitForItem, false, 3*time.Second), "")
	go func() {
		time.Sleep(1 * time.Second)
		deck.Init([]interface{}{1, 2})
	}()
	check(Wait(deck, (*deque.Deque).WaitForItem, true, 1*time.Second), "")

	deck = deque.New(4, []interface{}{1, 2, 3}, deque.BlockIfFull)
	check(Wait(deck, (*deque.Deque).WaitForSpace, true, 0), "")
	deck.Push(4)
	check(Wait(deck, (*deque.Deque).WaitForSpace, false, 3*time.Second), "")
	go func() {
		time.Sleep(1 * time.Second)
		deck.Pop()
	}()
	check(Wait(deck, (*deque.Deque).WaitForSpace, true, 1*time.Second), "")
	deck.Push(1)
	go func() {
		time.Sleep(1 * time.Second)
		deck.Init(3, []interface{}{1, 2, 3})
	}()
	check(Wait(deck, (*deque.Deque).WaitForSpace, false, 3*time.Second), "")
	go func() {
		time.Sleep(1 * time.Second)
		deck.Init(4, []interface{}{1, 2, 3})
	}()
	check(Wait(deck, (*deque.Deque).WaitForSpace, true, 1*time.Second), "")

	check(Wait(deck, (*deque.Deque).WaitForEmpty, false, 3*time.Second), "")
	go func() {
		time.Sleep(1 * time.Second)
		deck.Pop()
		deck.Pop()
		deck.Pop()
	}()
	check(Wait(deck, (*deque.Deque).WaitForEmpty, true, 1*time.Second), "")
	check(Wait(deck, (*deque.Deque).WaitForEmpty, true, 0), "")
	deck.Push(1)
	go func() {
		time.Sleep(1 * time.Second)
		deck.Init(4, []interface{}{1, 2, 3})
	}()
	check(Wait(deck, (*deque.Deque).WaitForEmpty, false, 3*time.Second), "")
	go func() {
		time.Sleep(1 * time.Second)
		deck.Init(4)
	}()
	check(Wait(deck, (*deque.Deque).WaitForEmpty, true, 1*time.Second), "")

	for i := 0; i < 33; i++ {
		check(Overcapacity(i), "")
	}

	deck = deque.New(4)
	deck.Raw(2)
	check(deck.Overcapacity(0) == deck, true)
	check(Deque(deck), "")
	check(deck.Capacity(), 0)

	deck = deque.New(4)
	deck.Raw(5)
	check(deck.Overcapacity(10) == deck, true)
	check(Deque(deck), "")
	check(deck.Capacity(), 10)

	deck.Init(deque.BlockIfFull, []interface{}{1, 2, 3})
	go func() {
		time.Sleep(500 * time.Millisecond)
		check(Deque(deck, 1, 2, 3), "")
		check(deck.Capacity(), 3)
		deck.Overcapacity(1)
	}()
	deck.Push(4)
	check(Deque(deck, 1, 2, 3, 4), "")
	check(deck.Capacity(), 4)

	deck = deque.New()
	check(deck.Push(1), true)
	check(Deque(deck, 1), "")
	check(deck.Push(2), true)
	check(Deque(deck, 1, 2), "")
	check(deck.PushAt(-2, "x"), false)
	check(Deque(deck, 1, 2), "")
	check(deck.PushAt(-1, "x"), false)
	check(Deque(deck, 1, 2), "")
	check(deck.PushAt(3, "x"), false)
	check(Deque(deck, 1, 2), "")
	check(deck.PushAt(4, "x"), false)
	check(Deque(deck, 1, 2), "")
	check(deck.PushAt(0, "foo"), true)
	check(Deque(deck, 1, 2, "foo"), "")
	check(deck.PushAt(1, "bar"), true)
	check(Deque(deck, 1, 2, "bar", "foo"), "")
	check(deck.PushAt(4, "FOO"), true)
	check(Deque(deck, "FOO", 1, 2, "bar", "foo"), "")
	check(deck.PushAt(5, "BAR"), true)
	check(Deque(deck, "BAR", "FOO", 1, 2, "bar", "foo"), "")
	check(deck.PushAt(3, 1.5), true)
	check(Deque(deck, "BAR", "FOO", 1, 1.5, 2, "bar", "foo"), "")
	check(deck.Pop(), "foo")
	check(Deque(deck, "BAR", "FOO", 1, 1.5, 2, "bar"), "")
	check(deck.PopAt(0), "bar")
	check(Deque(deck, "BAR", "FOO", 1, 1.5, 2), "")
	check(deck.PopAt(5), nil)
	check(Deque(deck, "BAR", "FOO", 1, 1.5, 2), "")
	check(deck.PopAt(4), "BAR")
	check(Deque(deck, "FOO", 1, 1.5, 2), "")
	check(deck.PopAt(1), 1.5)
	check(Deque(deck, "FOO", 1, 2), "")
	deck = deque.New()
	go func() { time.Sleep(1 * time.Second); deck.Push("Yeah!") }()
	for i := -2; i <= 2; i++ {
		check(deck.PopAt(i), nil)
		check(Deque(deck), "")
	}
	check(deck.PopAt(0), nil)
	time.Sleep(2 * time.Second)
	check(deck.PopAt(0), "Yeah!")
	for i := 0; i < 50; i++ {
		go func() {
			p := deck.Pop().(string)
			if p != "MSB" {
				check(p, "MSB")
			}
		}()
	}
	for i = 0; i < 50; i++ {
		deck.Push("MSB")
		time.Sleep(100 * time.Millisecond)
	}

	deck = deque.New()
	check(deck.Insert(1), true)
	check(DequeReversed(deck, 1), "")
	check(deck.Insert(2), true)
	check(DequeReversed(deck, 1, 2), "")
	check(deck.InsertAt(-2, "x"), false)
	check(DequeReversed(deck, 1, 2), "")
	check(deck.InsertAt(-1, "x"), false)
	check(DequeReversed(deck, 1, 2), "")
	check(deck.InsertAt(3, "x"), false)
	check(DequeReversed(deck, 1, 2), "")
	check(deck.InsertAt(4, "x"), false)
	check(DequeReversed(deck, 1, 2), "")
	check(deck.InsertAt(0, "foo"), true)
	check(DequeReversed(deck, 1, 2, "foo"), "")
	check(deck.InsertAt(1, "bar"), true)
	check(DequeReversed(deck, 1, 2, "bar", "foo"), "")
	check(deck.InsertAt(4, "FOO"), true)
	check(DequeReversed(deck, "FOO", 1, 2, "bar", "foo"), "")
	check(deck.InsertAt(5, "BAR"), true)
	check(DequeReversed(deck, "BAR", "FOO", 1, 2, "bar", "foo"), "")
	check(deck.InsertAt(3, 1.5), true)
	check(DequeReversed(deck, "BAR", "FOO", 1, 1.5, 2, "bar", "foo"), "")
	check(deck.Next(), "foo")
	check(DequeReversed(deck, "BAR", "FOO", 1, 1.5, 2, "bar"), "")
	check(deck.RemoveAt(0), "bar")
	check(DequeReversed(deck, "BAR", "FOO", 1, 1.5, 2), "")
	check(deck.RemoveAt(5), nil)
	check(DequeReversed(deck, "BAR", "FOO", 1, 1.5, 2), "")
	check(deck.RemoveAt(4), "BAR")
	check(DequeReversed(deck, "FOO", 1, 1.5, 2), "")
	check(deck.RemoveAt(1), 1.5)
	check(DequeReversed(deck, "FOO", 1, 2), "")
	deck = deque.New()
	go func() { time.Sleep(1 * time.Second); deck.Insert("Yeah!") }()
	for i := -2; i <= 2; i++ {
		check(deck.RemoveAt(i), nil)
		check(DequeReversed(deck), "")
	}
	check(deck.RemoveAt(0), nil)
	time.Sleep(2 * time.Second)
	check(deck.RemoveAt(0), "Yeah!")
	for i := 0; i < 50; i++ {
		go func() {
			p := deck.Next().(string)
			if p != "MSB" {
				check(p, "MSB")
			}
		}()
	}
	for i = 0; i < 50; i++ {
		deck.Insert("MSB")
		time.Sleep(100 * time.Millisecond)
	}

	deck.Init()
	check(deck.Remove(nil), 0)
	check(deck.Remove("foo"), 0)
	check(deck.Remove(nil, strcmp), 0)
	check(deck.Remove("foo", strcmp), 0)
	check(Deque(deck), "")
	deck.Push("foobar")
	check(deck.Remove(nil), 0)
	check(deck.Remove("foo"), 0)
	check(deck.Remove("foo", strcmp), 0)
	check(Deque(deck, "foobar"), "")
	tmp := []byte{0, 'o', 'o', 'b', 'a', 'r'}
	tmp[0] = 'f'
	check(deck.Remove(string(tmp), strcmp), 1)
	check(Deque(deck), "")
	deck.Push("foobar")
	check(deck.Remove(string(tmp)), 1)
	check(Deque(deck), "")
	deck.Init([]interface{}{"foobar", "foobar"})
	check(deck.Remove("foobar"), 2)
	check(Deque(deck), "")
	deck.Init([]interface{}{"foobar", "foobar"})
	check(deck.Remove("foobar", strcmp), 2)
	check(Deque(deck), "")
	deck.Init([]interface{}{"foobar", "a", "b", "foobar", "c", "foobar", "d", "e", "f", "foobar"})
	deck.Raw(5)
	check(deck.Remove("foobart"), 0)
	check(Deque(deck, "foobar", "a", "b", "foobar", "c", "foobar", "d", "e", "f", "foobar"), "")
	check(deck.Remove("foobar"), 4)
	check(Deque(deck, "a", "b", "c", "d", "e", "f"), "")
	deck.Init([]interface{}{"foobar", "a", "b", "foobar", "c", "foobar", "d", "e", "f", "foobar"})
	deck.Raw(5)
	check(deck.Remove("foobart", strcmp), 0)
	check(Deque(deck, "foobar", "a", "b", "foobar", "c", "foobar", "d", "e", "f", "foobar"), "")
	check(deck.Remove("foobar", strcmp), 4)
	check(Deque(deck, "a", "b", "c", "d", "e", "f"), "")
	var errormsg interface{}
	func() {
		defer func() { errormsg = recover() }()
		deck.Remove("foobar", strcmp, strcmp)
	}()
	check(errormsg, "Remove() takes 1 or 2 parameters")

	func() {
		defer func() { errormsg = recover() }()
		deck.Init(nil)
	}()
	check(errormsg, "Argument #1 is unsupported by deque.Init()")

	func() {
		defer func() { errormsg = recover() }()
		deck.Init(stack) // stack is not a pointer. That's why this doesn't work.
	}()
	check(errormsg, "Argument #1 is unsupported by deque.Init()")

	growth := func(uint, uint, uint) uint { return 10 }
	var uninitialized deque.Deque
	check(Deque(deque.New(&uninitialized, &uninitialized)), "")
	d1 = deque.New([]interface{}{1, 2, 3, 4, 5}, 10)
	d1.Raw(6)
	d2 = deque.New([]interface{}{6, 7, 8})
	d3 := deque.New([]interface{}{}, 4)
	deck.Init(&uninitialized, d1, d2, d3, []interface{}{"a", "b", "c", "d"}, []interface{}{"e", "f", "g", "h"}, growth)
	check(Deque(deck, 1, 2, 3, 4, 5, 6, 7, 8, "a", "b", "c", "d", "e", "f", "g", "h"), "")
	deck.Init([]interface{}{"a", "b", "c", "d"}, []interface{}{"e", "f", "g", "h"}, growth, d1, d2)
	check(Deque(deck, "a", "b", "c", "d", "e", "f", "g", "h", 1, 2, 3, 4, 5, 6, 7, 8), "")

	check(deque.New(0).Capacity(), 0)
	check(deque.New(1).Capacity(), 1)
	check(deque.New(-100).Capacity(), deque.CapacityDefault)
	check(deque.New(3, []interface{}{}).Capacity(), 3)
	check(deque.New(int64(3), []interface{}{1}).Capacity(), 3)
	check(deque.New(uint(3), []interface{}{1, 2}).Capacity(), 3)
	check(deque.New(uint64(3), []interface{}{1, 2}).Capacity(), 3)
	check(deque.New(uint64(3), []interface{}{1, 2, 3}).Capacity(), 3)
	check(deque.New(3, []interface{}{1, 2, 3, 4}).Capacity(), 4)
	check(deque.New(3, []interface{}{1, 2}, []interface{}{3, 4}).Capacity(), 4)

	deck.Init(3, []interface{}{1, 2}, []interface{}{3, 4})
	deck.Clear()
	check(deck.Capacity(), deque.CapacityDefault)
	check(deck.Count(), 0)

	deck.Init([]interface{}{0, 1, 2, 3, 4, 5})
	deck.Raw(3) // 3,4,5,[b][a]0,1,2
	check(deck.RemoveAt(-1), nil)
	check(deck.RemoveAt(deck.Count()), nil)
	check(deck.RemoveAt(3), 3) // 2,4,5,[b]_,[a]0,1
	check(Deque(deck, 0, 1, 2, 4, 5), "")
	check(deck.RemoveAt(2), 2) // 1,4,5,[b]_,_,[a]0
	check(Deque(deck, 0, 1, 4, 5), "")
	check(deck.RemoveAt(2), 4) // [a]0,1,5,[b]_,_,_
	check(Deque(deck, 0, 1, 5), "")

	deck.Init([]interface{}{0, 1, 2, 3, 4, 5})
	deck.Raw(3)                  // 3,4,5,[b][a]0,1,2
	check(deck.RemoveAt(0), "0") // 3,4,5,[b]_,[a]1,2
	check(Deque(deck, 1, 2, 3, 4, 5), "")

	deck.Init([]interface{}{0, 1, 2, 3, 4, 5})
	deck.Raw(3)                  // 3,4,5,[b][a]0,1,2
	check(deck.RemoveAt(4), "4") // 3,5,[b]_,[a]0,1,2
	check(Deque(deck, 0, 1, 2, 3, 5), "")

	deck.Init([]interface{}{0, 1, 2, 3, 4, 5, 6, 7})
	deck.Raw(2)                  // 6,7,[b][a]0,1,2,3,4,5
	check(deck.RemoveAt(7), "7") // 6,[b]_,[a]0,1,2,3,4,5
	check(Deque(deck, 0, 1, 2, 3, 4, 5, 6), "")
	check(deck.RemoveAt(4), "4") // [b]_,_,[a]0,1,2,3,5,6
	check(Deque(deck, 0, 1, 2, 3, 5, 6), "")
	check(deck.RemoveAt(5), "6") // _,_,[a]0,1,2,3,5,[b]_
	check(Deque(deck, 0, 1, 2, 3, 5), "")

	deck.Init([]interface{}{0, 1, 2, 3, 4, 5, 6, 7})
	deck.Overcapacity(4)         // [a]0,1,2,3,4,5,6,7,[b]_,_,_,_
	deck.Raw(2)                  // _,_,[a]0,1,2,3,4,5,6,7,[b]_,_
	check(deck.RemoveAt(6), "6") // _,_,[a]0,1,2,3,4,5,7,[b]_,_,_
	check(Deque(deck, 0, 1, 2, 3, 4, 5, 7), "")
	check(deck.RemoveAt(2), "2") // _,_,_,[a]0,1,3,4,5,7,[b]_,_,_
	check(Deque(deck, 0, 1, 3, 4, 5, 7), "")

	deck.Init([]interface{}{}, deque.GrowBy(1))
	check(deck.InsertAt(-1, "foo"), false)
	check(deck.InsertAt(1, "foo"), false)
	check(deck.InsertAt(0, 11), true)
	check(Deque(deck, 11), "")
	deck.Init(deck, deque.BlockIfFull)
	go func() { time.Sleep(1 * time.Second); deck.Pop() }()
	check(deck.InsertAt(0, 22), true)
	check(Deque(deck, 22), "")

	deck.Init([]interface{}{0, 1, 2}, deque.GrowBy(1))
	check(deck.InsertAt(0, -1), true)
	check(Deque(deck, -1, 0, 1, 2), "")
	deck.Init([]interface{}{0, 1, 2}, deque.GrowBy(1))
	deck.Raw(1)
	check(deck.InsertAt(0, -1), true)
	check(Deque(deck, -1, 0, 1, 2), "")
	deck.Init([]interface{}{0, 1, 2}, deque.GrowBy(1))
	deck.Raw(2)
	check(deck.InsertAt(0, -1), true)
	check(Deque(deck, -1, 0, 1, 2), "")

	deck.Init(0, deque.GrowBy(2))
	go func() {
		time.Sleep(500 * time.Millisecond)
		deck.InsertAt(0, 0)
	}()
	check(deck.Capacity(), 0)
	check(deck.WaitForSpace(2*time.Second), true)
	check(deck.Capacity(), 2)

	deck.Init([]interface{}{0, 1, 2, 3, 4, 5, 6, 7}, deque.BlockIfFull)
	go func() {
		time.Sleep(500 * time.Millisecond)
		deck.Init([]interface{}{0, 1}, 3)
	}()
	check(deck.Push(2), true)
	check(Deque(deck, 0, 1, 2), "")

	deck.Init(0, deque.DropFarEndIfOverflow)
	check(deck.Push("should be discarded"), false)
	check(Deque(deck), "")

	deck.Init([]interface{}{0}, deque.DropFarEndIfOverflow)
	check(deck.PushAt(0, 1), true)
	check(Deque(deck, 1), "")
	check(deck.PushAt(1, 2), true)
	check(Deque(deck, 2), "")

	deck.Init([]interface{}{3, 5}, deque.DropFarEndIfOverflow)
	check(deck.InsertAt(0, 1), true)
	check(Deque(deck, 1, 3), "")
	check(deck.InsertAt(1, 2), true)
	if deck.At(0).(int) == 2 {
		check(Deque(deck, 2, 3), "")
	} else {
		check(Deque(deck, 1, 2), "")
	}

	deck.Init([]interface{}{3, 5}, deque.DropFarEndIfOverflow)
	deck.Raw(1)
	check(deck.InsertAt(0, 1), true)
	check(Deque(deck, 1, 3), "")
	check(deck.InsertAt(1, 2), true)
	if deck.At(0).(int) == 2 {
		check(Deque(deck, 2, 3), "")
	} else {
		check(Deque(deck, 1, 2), "")
	}

	deck.Init([]interface{}{1, 3, 5}, deque.DropFarEndIfOverflow)
	check(deck.InsertAt(1, 2), true)
	check(Deque(deck, 1, 2, 3), "")
	check(deck.InsertAt(2, 2.5), true)
	check(Deque(deck, 2, 2.5, 3), "")

	deck.Init(0, deque.DropItemIfOverflow)
	check(deck.InsertAt(1, 2), false)
	check(deck.Insert(2), false)
	check(deck.Push(2), false)
	check(Deque(deck), "")

	deck.Init([]interface{}{1, 2, 3}, deque.DropItemIfOverflow)
	check(deck.InsertAt(1, 2), false)
	check(deck.Insert(2), false)
	check(deck.Push(2), false)
	check(Deque(deck, 1, 2, 3), "")

	deck.Init(0, deque.GrowBy(1))
	check(deck.Push(42), true)
	check(deck.Push(43), true)
	check(Deque(deck, 42, 43), "")

	deck.Init(0, deque.GrowBy(2))
	go func() {
		deck.WaitForSpace(0)
		deck.Push(2)
	}()
	time.Sleep(500 * time.Millisecond)
	check(deck.Push(1), true)
	time.Sleep(500 * time.Millisecond)
	check(deck.Push(3), true)
	check(Deque(deck, 1, 2, 3), "")
	check(deck.Capacity(), 4)

	deck.Init([]interface{}{0, 1}, 3)
	deck.Raw(2)
	check(deck.Push(2), true)
	check(Deque(deck, 0, 1, 2), "")

	deck.Init(3)
	go func() {
		deck.WaitForItem(0)
		deck.Push(2)
	}()
	time.Sleep(500 * time.Millisecond)
	check(deck.Push(1), true)
	time.Sleep(500 * time.Millisecond)
	deck.Push(3)
	deck.Push(4)
	deck.Push(5)
	check(deck.InsertAt(2, 2.5), true)
	check(Deque(deck, 1, 2, 2.5, 3, 4, 5), "")

	deck.Init([]interface{}{1, 2, 3, 4, 5}, 7)
	check(deck.InsertAt(0, -1), true)
	check(Deque(deck, -1, 1, 2, 3, 4, 5), "")

	deck.Raw(0)
	check(deck.InsertAt(4, 3.5), true)
	check(Deque(deck, -1, 1, 2, 3, 3.5, 4, 5), "")

	deck.Init([]interface{}{1, 2, 3, 4, 5}, 10)
	deck.Raw(8)
	check(deck.InsertAt(2, 2.5), true)
	check(Deque(deck, 1, 2, 2.5, 3, 4, 5), "")

	deck.Init([]interface{}{1, 2, 3, 4, 5, 6, 7}, 10)
	deck.Raw(8)
	check(deck.InsertAt(3, 3.5), true)
	check(Deque(deck, 1, 2, 3, 3.5, 4, 5, 6, 7), "")

	deck.Init([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 12)
	deck.Raw(10)
	check(deck.InsertAt(4, 4.5), true)
	check(Deque(deck, 1, 2, 3, 4, 4.5, 5, 6, 7, 8, 9, 10), "")

	deck.Init([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 12)
	deck.Raw(10)
	check(deck.InsertAt(5, 5.5), true)
	check(Deque(deck, 1, 2, 3, 4, 5, 5.5, 6, 7, 8, 9, 10), "")

	deck.Init([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 12)
	deck.Raw(5)
	check(deck.InsertAt(6, 6.5), true)
	check(Deque(deck, 1, 2, 3, 4, 5, 6, 6.5, 7, 8, 9, 10), "")

	deck.Init([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 11)
	deck.Raw(5)
	check(deck.InsertAt(5, 5.5), true)
	check(Deque(deck, 1, 2, 3, 4, 5, 5.5, 6, 7, 8, 9, 10), "")

	check(Search(2), 0)
	check(Search(2, 1), 1)
	check(Search(2, 2), 0)
	check(Search(2, 3), 0)
	check(Search(2, 1, 2), 1)
	check(Search(2, 2, 2), 0)
	check(Search(2, 1, 1), 2)
	check(Search(2, 3, 4), 0)
	check(Search(2, 2, 3, 4), 0)
	check(Search(2, 1, 1, 2), 2)
	check(Search(2, 1, 1, 1), 3)
	check(Search(2, 1, 2, 3), 1)
	check(Search(2, 3, 4, 5, 6), 0)
	check(Search(2, 2, 3, 4, 5), 0)
	check(Search(2, 1, 2, 3, 4), 1)
	check(Search(2, 1, 3, 4, 5), 1)
	check(Search(2, 1, 1, 4, 5), 2)
	check(Search(2, 1, 1, 2, 5), 2)
	check(Search(2, 1, 1, 1, 5), 3)
	check(Search(2, 1, 1, 1, 2), 3)
	check(Search(2, 1, 1, 1, 1), 4)
	check(Search(2, 2, 2, 2, 2), 0)

	deck.Init(deque.DropItemIfOverflow, 0)
	check(deck.InsertSorted(42, intcmp), -1)

	deck.Init(deque.BlockIfFull, 0)
	go func() {
		time.Sleep(500 * time.Millisecond)
		deck.Init([]interface{}{1, 2, 3, 4, 5, 6}, 10, deque.BlockIfFull)
	}()
	check(deck.InsertSorted(3, intcmp), 2)
	check(Deque(deck, 1, 2, 3, 3, 4, 5, 6), "")

	check(deck.InsertSorted(5, intcmp), 5)
	check(Deque(deck, 1, 2, 3, 3, 4, 5, 5, 6), "")
}
예제 #6
0
// Handles the message "gosa_query_jobdb".
//  xmlmsg: the decrypted and parsed message
// Returns:
//  unencrypted reply
func gosa_query_jobdb(xmlmsg *xml.Hash) *xml.Hash {
	where := xmlmsg.First("where")
	if where == nil {
		where = xml.NewHash("where")
	}
	filter, err := xml.WhereFilter(where)
	if err != nil {
		util.Log(0, "ERROR! gosa_query_jobdb: Error parsing <where>: %v", err)
		filter = xml.FilterNone
	}

	// If necessary, wait for the effects of forwarded modify requests
	t_forward := db.MostRecentForwardModifyRequestTime.At(0).(time.Time)
	delay := config.GosaQueryJobdbMaxDelay - time.Since(t_forward)
	if delay > 0 {
		util.Log(1, "INFO! Waiting %v before replying to gosa_query_jobdb to allow forwarded job modifications to take effect", delay)
		time.Sleep(delay)
	}

	jobdb_xml := db.JobsQuery(filter)

	// sort jobs
	cmp := func(a, b interface{}) int {
		x := a.(*xml.Hash)
		y := b.(*xml.Hash)
		ts := x.Text("timestamp") + "00000000000000"
		// NOTE: The first component has only the 1st 10 digits of the timestamp.
		// This quantizes jobs by hour (i.e. ignoring minutes and seconds).
		// For this reason we have "timestamp" listed a 2nd time as the final component,
		// in that case including all digits.
		c1 := ts[0:10] + x.Text("headertag", "status", "plainname", "macaddress", "timestamp")
		ts = y.Text("timestamp") + "00000000000000"
		c2 := ts[0:10] + y.Text("headertag", "status", "plainname", "macaddress", "timestamp")
		if c1 < c2 {
			return -1
		}
		if c1 > c2 {
			return +1
		}
		return 0
	}
	answers := deque.New()
	for child := jobdb_xml.FirstChild(); child != nil; child = child.Next() {
		answer := child.Remove()
		answers.InsertSorted(answer, cmp)
	}

	// maps IP:PORT to a string representation of that peer's downtime
	// the empty string represents a peer that is up
	downtime := map[string]string{config.ServerSourceAddress: ""}

	// maps IP:PORT to server name
	servername := map[string]string{}

	for count := 0; count < answers.Count(); {
		answer := answers.At(count).(*xml.Hash)
		count++
		{
			siserver := answer.Text("siserver")

			// If we encounter this siserver for the first time,
			// get its downtime (if any) and cache it.
			if _, found := downtime[siserver]; !found {
				dur := Peer(siserver).Downtime()
				if t := dur / time.Second; t == 0 {
					downtime[siserver] = ""
				} else {
					downtime[siserver] = verbalDuration(dur)
				}
			}

			// If the server is down, set status="error" and result=<error message>
			if downtime[siserver] != "" {

				// Look up server name if we don't have it cached, yet.
				if _, have := servername[siserver]; !have {
					servername[siserver] = siserver
					host, _, err := net.SplitHostPort(siserver)
					if err != nil {
						util.Log(0, "ERROR! SplitHostPort(%v): %v", siserver, err)
					} else {
						names, err := net.LookupAddr(host)
						if err != nil {
							util.Log(0, "ERROR! LookupAddr: %v", err)
						} else {
							if len(names) == 0 {
								names = []string{siserver}
							}
							servername[siserver] = names[0]
						}
					}
				}

				answer.FirstOrAdd("status").SetText("error")
				answer.FirstOrAdd("result").SetText("%v has been down for %v.", servername[siserver], downtime[siserver])
			}

			answer.Rename("answer" + strconv.FormatUint(uint64(count), 10))
			jobdb_xml.AddWithOwnership(answer)
		}
	}

	jobdb_xml.Add("header", "query_jobdb")
	jobdb_xml.Add("source", config.ServerSourceAddress)
	jobdb_xml.Add("target", xmlmsg.Text("source"))
	jobdb_xml.Add("session_id", "1")
	jobdb_xml.Rename("xml")
	return jobdb_xml
}
예제 #7
0
// the listener of the test server
var listener net.Listener

// port the test client listens on
var client_listen_port = "18341"

// host:port address of the test client.
var client_listen_address string

// the listener of the test client
var client_listener net.Listener

// Elements of type net.Conn for all current active incoming connections
// handled by handleConnection()
var active_connections = deque.New()

// keys[0] is the key of the test server started by listen().
// keys[len(keys)-1] is the key of the test client started by listen()
// The other elements are copies of config.ModuleKeys
// ATTENTION! You must call init_keys() to initialize this.
var keys []string

// returns all messages currently in the queue that were received at time t or later.
func get(t time.Time) []*queueElement {
	queue_mutex.Lock()
	defer queue_mutex.Unlock()

	result := []*queueElement{}
	for _, q := range queue {
		if !q.Time.Before(t) {
예제 #8
0
파일: jobdb.go 프로젝트: chrlutz/limux-gosa
//       be called after delivery of the foreign_job_updates to the peer.
//       <SyncIfNotGoSusi> is only permitted if <target> is a specific peer. It will not
//       be transmitted as part of the foreign_job_updates.
//       A second effect of <SyncIfNotGoSusi> is that if the <target> is not a go-susi,
//       instead of sending the foreign_job_updates just to the target, it will be
//       sent to all known peers. This is done to compensate for the fact that
//       unlike go-susi gosa-si does not rebroadcast changes to its jobdb when those
//       changes are the result of foreign_job_updates.
//       The <SyncIfNotGoSusi> tag is used when forwarding change requests for
//       jobs belonging to other servers to them via foreign_job_updates.
var ForeignJobUpdates = make(chan *xml.Hash, 16384)

// Stores exactly 1 time.Time that indicates when the most recent job modification
// request was forwarded to a peer. A Deque is used only for its synchronization.
// Access is permitted with At() and Put() only.
var MostRecentForwardModifyRequestTime = deque.New([]interface{}{time.Now().Add(-1 * time.Hour)}, deque.DropFarEndIfOverflow)

// Fields that can be updated via Jobs*Modify*()
var updatableFields = []string{"progress", "status", "periodic", "timestamp", "result"}

// A packaged request to perform some action on the jobDB.
// Most db.Job...() functions attach their core code to a jobDBRequest,
// push that into the jobDBRequests channel and then return.
type jobDBRequest struct {
	// The function to execute. It is passed a pointer to its own request.
	Action func(request *jobDBRequest)
	// Selects the jobs to act upon.
	Filter xml.HashFilter
	// Additional job data to be added in whole or part to the database.
	Job *xml.Hash
	// If a reply is necessary, it will be transmitted over this channel.