Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
G
Goshimmer_without_tipselection
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
COLLET Ismael
Goshimmer_without_tipselection
Commits
8565459d
Commit
8565459d
authored
4 years ago
by
Hans Moog
Browse files
Options
Downloads
Patches
Plain Diff
Feat: intermediary commit
parent
eb032da9
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
packages/binary/datastructure/timedqueue.go
+42
-25
42 additions, 25 deletions
packages/binary/datastructure/timedqueue.go
packages/binary/datastructure/timedqueue_test.go
+11
-11
11 additions, 11 deletions
packages/binary/datastructure/timedqueue_test.go
with
53 additions
and
36 deletions
packages/binary/datastructure/timedqueue.go
+
42
−
25
View file @
8565459d
...
@@ -2,7 +2,6 @@ package datastructure
...
@@ -2,7 +2,6 @@ package datastructure
import
(
import
(
"container/heap"
"container/heap"
"fmt"
"sync"
"sync"
"time"
"time"
...
@@ -16,17 +15,19 @@ import (
...
@@ -16,17 +15,19 @@ import (
type
TimedQueue
struct
{
type
TimedQueue
struct
{
heap
timedHeap
heap
timedHeap
heapMutex
sync
.
RWMutex
heapMutex
sync
.
RWMutex
nonEmpty
sync
.
WaitGroup
waitForNewElementsWG
sync
.
WaitGroup
shutdown
chan
byte
queueEmptyWG
sync
.
WaitGroup
shutdownSignal
chan
byte
shutdownFlag
typeutils
.
AtomicBool
returnPendingElementsAfterShutdown
typeutils
.
AtomicBool
returnPendingElementsAfterShutdown
typeutils
.
AtomicBool
}
}
// NewTimedQueue is the constructor for the TimedQueue.
// NewTimedQueue is the constructor for the TimedQueue.
func
NewTimedQueue
()
(
queue
*
TimedQueue
)
{
func
NewTimedQueue
()
(
queue
*
TimedQueue
)
{
queue
=
&
TimedQueue
{
queue
=
&
TimedQueue
{
shutdown
:
make
(
chan
byte
),
shutdown
Signal
:
make
(
chan
byte
),
}
}
queue
.
nonEmpty
.
Add
(
1
)
queue
.
waitForNewElementsWG
.
Add
(
1
)
return
return
}
}
...
@@ -44,7 +45,7 @@ func (t *TimedQueue) Add(value interface{}, scheduledTime time.Time) (addedEleme
...
@@ -44,7 +45,7 @@ func (t *TimedQueue) Add(value interface{}, scheduledTime time.Time) (addedEleme
// mark queue as non-empty
// mark queue as non-empty
if
len
(
t
.
heap
)
==
0
{
if
len
(
t
.
heap
)
==
0
{
t
.
nonEmpty
.
Done
()
t
.
waitForNewElementsWG
.
Done
()
}
}
// add new element
// add new element
...
@@ -76,14 +77,14 @@ func (t *TimedQueue) Poll() interface{} {
...
@@ -76,14 +77,14 @@ func (t *TimedQueue) Poll() interface{} {
// mark the queue as empty if last element was polled
// mark the queue as empty if last element was polled
if
len
(
t
.
heap
)
==
0
{
if
len
(
t
.
heap
)
==
0
{
t
.
nonEmpty
.
Add
(
1
)
t
.
waitForNewElementsWG
.
Add
(
1
)
}
}
t
.
heapMutex
.
Unlock
()
t
.
heapMutex
.
Unlock
()
// wait for the return value to become due
// wait for the return value to become due
select
{
select
{
// abort if the queue was shutdown
// abort if the queue was shutdown
case
<-
t
.
shutdown
:
case
<-
t
.
shutdown
Signal
:
if
!
t
.
returnPendingElementsAfterShutdown
.
IsSet
()
{
if
!
t
.
returnPendingElementsAfterShutdown
.
IsSet
()
{
if
t
.
Size
()
!=
0
{
if
t
.
Size
()
!=
0
{
return
t
.
Poll
()
return
t
.
Poll
()
...
@@ -92,8 +93,6 @@ func (t *TimedQueue) Poll() interface{} {
...
@@ -92,8 +93,6 @@ func (t *TimedQueue) Poll() interface{} {
return
nil
return
nil
}
}
fmt
.
Println
(
"RETURN LAST ELEMENTS"
)
return
polledElement
.
value
return
polledElement
.
value
// abort waiting for this element and wait for the next one instead if it was canceled
// abort waiting for this element and wait for the next one instead if it was canceled
case
<-
polledElement
.
cancel
:
case
<-
polledElement
.
cancel
:
...
@@ -113,13 +112,20 @@ func (t *TimedQueue) Size() int {
...
@@ -113,13 +112,20 @@ func (t *TimedQueue) Size() int {
return
len
(
t
.
heap
)
return
len
(
t
.
heap
)
}
}
// WaitForNewElements waits for the queue to be non-empty. This can be used by i.e. schedulers to continuously iterate
// IsProcessingElements returns true if the queue was not shutdown, yet or still has queued elements to process after a
// over the queue to process its elements. It returns false, if the queue has been shutdown.
// shutdown.
func
(
t
*
TimedQueue
)
WaitForNewElements
()
bool
{
//
t
.
nonEmpty
.
Wait
()
// It will wait for the arrival of new elements if the waitForElements parameter is set to true. This can accordingly be
// used by schedulers that want to continuously iterate over the queue without wasting CPU cycles for checking for new
// elements over and over again.
func
(
t
*
TimedQueue
)
IsProcessingElements
(
waitForElements
bool
)
bool
{
// wait for elements to arrive
if
waitForElements
{
t
.
waitForNewElementsWG
.
Wait
()
}
select
{
select
{
case
<-
t
.
shutdown
:
case
<-
t
.
shutdown
Signal
:
return
t
.
returnPendingElementsAfterShutdown
.
IsSet
()
&&
t
.
Size
()
!=
0
return
t
.
returnPendingElementsAfterShutdown
.
IsSet
()
&&
t
.
Size
()
!=
0
default
:
default
:
return
true
return
true
...
@@ -127,20 +133,31 @@ func (t *TimedQueue) WaitForNewElements() bool {
...
@@ -127,20 +133,31 @@ func (t *TimedQueue) WaitForNewElements() bool {
}
}
// Shutdown terminates the queue and stops the currently waiting Poll requests.
// Shutdown terminates the queue and stops the currently waiting Poll requests.
func
(
t
*
TimedQueue
)
Shutdown
(
returnPendingElements
bool
)
{
func
(
t
*
TimedQueue
)
Shutdown
(
processQueuedElements
bool
)
{
// acquire lock to be thread safe
t
.
heapMutex
.
Lock
()
t
.
heapMutex
.
Lock
()
select
{
// only shutdown once
case
<-
t
.
shutdown
:
// do nothing
default
:
t
.
returnPendingElementsAfterShutdown
.
SetTo
(
returnPendingElements
)
close
(
t
.
shutdown
)
// abort if the queue was shutdown before
if
t
.
shutdownFlag
.
IsSet
()
{
t
.
heapMutex
.
Unlock
()
return
}
}
// set the flag that indicates if the currently queued elements should be executed immediately
t
.
returnPendingElementsAfterShutdown
.
SetTo
(
processQueuedElements
)
// mark the queue as shutdown
t
.
shutdownFlag
.
Set
()
// close the shutdown channel
close
(
t
.
shutdownSignal
)
// release the lock
t
.
heapMutex
.
Unlock
()
t
.
heapMutex
.
Unlock
()
t
.
nonEmpty
.
Wait
()
// wait for the queue to be empty
t
.
queueEmptyWG
.
Wait
()
}
}
// removeElement is an internal utility function that removes the given element from the queue.
// removeElement is an internal utility function that removes the given element from the queue.
...
@@ -155,7 +172,7 @@ func (t *TimedQueue) removeElement(element *TimedQueueElement) {
...
@@ -155,7 +172,7 @@ func (t *TimedQueue) removeElement(element *TimedQueueElement) {
// mark the queue as empty
// mark the queue as empty
if
len
(
t
.
heap
)
==
0
{
if
len
(
t
.
heap
)
==
0
{
t
.
nonEmpty
.
Add
(
1
)
t
.
waitForNewElementsWG
.
Add
(
1
)
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
packages/binary/datastructure/timedqueue_test.go
+
11
−
11
View file @
8565459d
...
@@ -7,28 +7,28 @@ import (
...
@@ -7,28 +7,28 @@ import (
)
)
func
TestTimedQueue_Poll
(
t
*
testing
.
T
)
{
func
TestTimedQueue_Poll
(
t
*
testing
.
T
)
{
t
q
:=
NewTimedQueue
()
t
imedQueue
:=
NewTimedQueue
()
go
func
()
{
go
func
()
{
for
t
q
.
WaitForNew
Elements
()
{
for
t
imedQueue
.
IsProcessing
Elements
(
true
)
{
for
currentEntry
:=
t
q
.
Poll
();
currentEntry
!=
nil
;
currentEntry
=
t
q
.
Poll
()
{
for
currentEntry
:=
t
imedQueue
.
Poll
();
currentEntry
!=
nil
;
currentEntry
=
t
imedQueue
.
Poll
()
{
fmt
.
Println
(
currentEntry
)
fmt
.
Println
(
currentEntry
)
}
}
}
}
}()
}()
t
q
.
Add
(
2
,
time
.
Now
()
.
Add
(
1
*
time
.
Second
))
t
imedQueue
.
Add
(
2
,
time
.
Now
()
.
Add
(
1
*
time
.
Second
))
elem
:=
t
q
.
Add
(
4
,
time
.
Now
()
.
Add
(
2
*
time
.
Second
))
elem
:=
t
imedQueue
.
Add
(
4
,
time
.
Now
()
.
Add
(
2
*
time
.
Second
))
t
q
.
Add
(
6
,
time
.
Now
()
.
Add
(
3
*
time
.
Second
))
t
imedQueue
.
Add
(
6
,
time
.
Now
()
.
Add
(
3
*
time
.
Second
))
elem
.
Cancel
(
)
time
.
Sleep
(
4
*
time
.
Second
)
time
.
Sleep
(
3
*
time
.
Second
)
elem
.
Cancel
(
)
t
q
.
Add
(
6
,
time
.
Now
()
.
Add
(
time
.
Second
))
t
imedQueue
.
Add
(
6
,
time
.
Now
()
.
Add
(
time
.
Second
))
t
q
.
Add
(
68
,
time
.
Now
()
.
Add
(
4
*
time
.
Second
))
t
imedQueue
.
Add
(
68
,
time
.
Now
()
.
Add
(
4
*
time
.
Second
))
t
q
.
Shutdown
(
fals
e
)
t
imedQueue
.
Shutdown
(
tru
e
)
time
.
Sleep
(
500
*
time
.
Millisecond
)
time
.
Sleep
(
500
*
time
.
Millisecond
)
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment