How to implement queue and priority queue in Tcl? - data-structures

I have to implement either queue or priority queue in Tcl without use of any library.
I have tried to write below code. Kindly help me to implement queue in better way in Tcl/Tk.
create node
// crearting node element of queue
proc createNode {name cost} {
namespace eval $name [subst {
variable cost $cost
variable this $name
}]
functions
proc ${name}::getCost {} {
variable cost
return $cost
}
return $name
}
delete queue
proc deQueue name {
#upvar 1 $name queue
set queue $name
set res [lindex $queue 0]
set queue [lrange $queue 1 end]; # remove the first element
set res; # return the value
}
queue insertion
proc enQueue {newNode name} {
#upvar 1 $name queue
set queue $name
set queue [concat $newNode $queue]
}
create queue
proc makeQueue {n g } {
set queue [list [createNode $n $g ]]
return $queue
}

A simple queue implementation:
proc enqueue {name item} {
upvar 1 $name queue
lappend queue $item
}
proc dequeue name {
upvar 1 $name queue
set queue [lassign $queue item]
return $item
}
% enqueue a foo
% set item [dequeue a]
A simple priority queue:
proc enpqueue {name prio item} {
upvar 1 $name queue
lappend queue [list $prio $item]
set queue [lsort -decreasing -integer -index 0 $queue]
}
proc depqueue name {
upvar 1 $name queue
set queue [lassign $queue prioitem]
return [lindex $prioitem 1]
}
% enpqueue a 10 foo
% enpqueue a 40 bar
% set item [depqueue a]
bar
The only thing you need for a queue or priority queue is a list and an add/remove interface.
If you want to store structured data in the queue, make the item either a tuple of data:
set item [list "Smith, John" 42 1500]
or a dictionary:
set item [list name "Smith, John" age 42 foo 1500]
Documentation:
lappend,
lassign,
lindex,
list,
lsort,
proc,
return,
set,
upvar

Queues are abstract data structures with two (key) operations: add and get (and an empty test is pretty common too). They're sufficiently complex internally that it's probably best to think in terms of using a TclOO object as their implementation:
oo::class create Queue {
variable q
constructor {} {
set q {}
}
method add {item} {
lappend q $item
return
}
method empty {} {
expr {[llength $q] == 0}
}
method get {} {
if {[my empty]} {
return -code error "queue is empty"
}
set q [lassign $q item]
return $item
}
}
Priority queues are like queues, except that they have a priority as well and sort by that priority. The trick to implementing them efficiently is not to sort on each add or get, but rather to only sort when necessary. (Or you can use an appropriate balanced tree, but they're quite complicated.)
oo::class create PriorityQueue {
variable q sorted
constructor {} {
set q {}
set sorted 1
}
method add {item priority} {
lappend q $item $priority
set sorted 0
return
}
method empty {} {
expr {[llength $q] == 0}
}
method get {} {
if {[my empty]} {
return -code error "queue is empty"
}
if {!$sorted} {
# You might want other options here, depending on what "priority" means
set q [lsort -stride 2 -index 1 -integer $q]
set sorted 1
}
set q [lassign $q item priority]
return $item
}
}
Using these data structures is fairly simple:
# Instantiate
set myq [PriorityQueue new]
# Add some values
$myq add "The quick brown fox" 12
$myq add "The lazy dog" 34
# Drain the queue
while {![$myq empty]} {
puts [$myq get]
}
# Get rid of it now we're done
$myq destroy

Related

How to exit a promise from within a promise?

How do I exit a promise from within a promise? The perl6 docs do not provide an easy method. For example:
my $x = start {
loop { # loop forever until "quit" is seen
my $y = prompt("Say something: ");
if $y ~~ / quit / {
# I want to exit the promise from here;
# "break" and "this.break" are not defined;
# "return" does not break the promise;
# I do NOT want an error exception when exiting a promise;
# I want to return a value as the result of this promise;
}
else { say $y; }
}
}
I do not want to be in the promise loop forever. break() and this.break() are not recognized, and return does not break the promise.
Use the last keyword to quit the loop.
The kept value of a start block is the value returned by its last statement.
So:
my $x = start {
loop { # loop forever until "quit" is seen
my $y = prompt("Say something: ");
if $y ~~ / quit / {
last
}
else { say $y; }
}
42 # <-- The promise will be kept with value `42`
}

Efficiently storing and iterating over Lua multi-level queue

This is the add format:
AddToQueue( String identifier, function callfunc, int priority )
priority is guaranteed to be 0 to 4, with 0 being the highest priority. My current setup is this:
local tQueue = {
[0] = {},
[1] = {},
[2] = {},
[3] = {},
[4] = {}
}
function AddToQueue( sName, funcCallback, iPriority )
queue[iPriority or 0][sName] = funcCallback
end
function CallQueue()
for i = 0, 4 do
for _, func in pairs( queue[i] ) do
local retval = func()
if ( retval ~= nil ) then
return retval
end
end
end
end
This works, but I want to know if there's a better way to store and iterate the functions to prevent doing 5 pair loops every call. Thanks!
If you iterate your queue frequently, and new callbacks additions is infrequent, then you can just store everything in single table, sorting it each time you've added new callback.

Viewing enum names in vcs ucli

I am working in VCS UCLI (ie, the command line interface) and am having trouble getting VCS to display various state variables, of a typedef'd enum type, value as the name rather than the number. For example, I have some SystemVerilog like this:
typedef enum logic [1:0] {A, B, C} state_t;
state_t s;
...
Now in ucli, I want to see the value of s (say its in state A) so I type something like:
ucli% get s
0
ucli% get s -radix symbolic
0
ucli% show s -value
s 0
ucli% show s -value -radix symbolic
s 0
ucli% show s -value -type
s 0 { ENUM state_t { {A 0} {B 1} {C 2} } }
(Or something like that). I have read the ucli user guide, and it seems like symbolic radix, the only one I know of that might possibly be close, just uses the raw value from the enum, not the enum name. I have tried calling the .name() method for variable s using the call command in ucli (ucli% call {$display("%s", s.name())}), but it doesnt seem to be supported. I know VCS has the capacity to print the enum name, it certainly can in DVE, but I am having trouble coming up with ways to get to show me in the ucli.
Does anyone know how to get the ucli to print the enum name instead of the number when queried? Is enum-type radix somehow (user-defined like in DVE?), use some SystemVerilog system call to get the name, anything like that?
(Note, I understand I could just use the DVE, but I am trying to use the ucli to simply the interface for potential users, this is for educational purposes and I want to mask alot of the ucli interface (and VCS interface in general) to not overwhelm students and get some variables easily; Im turning the vcs ucli into a simple processor simulator)
++++++++++++ UPDATE ++++++++++++
I came up with a very hacky solution but I would really like a better approach. I quickly wrote my own wrapper for show (called eshow) whish ill replace any -value with the enum name if -radix enum is set:
#
# An extension of show to include "-radix enum"
#
# Borrowed from http://wiki.tcl.tk/17342
# Credit to Richard Suchenwirth (12-8-2006)
proc getopt {_argv name {_var ""} {default ""}} {
upvar 1 $_argv argv $_var var
set pos [lsearch -regexp $argv ^$name]
if {$pos>=0} {
set to $pos
if {$_var ne ""} {
set var [lindex $argv [incr to]]
}
set argv [lreplace $argv $pos $to]
return 1
} else {
if {[llength [info level 0]] == 5} {set var $default}
return 0
}
}
proc eshow {args} {
set argv $args
# If radix is not specified or value is not specified, then dont bother doing anything but regular show
if { 0 == [getopt argv -radix radix] } {
return [eval show $args]
}
if { 0 == [getopt argv -value] } {
return [eval show $args]
}
# If radix isnt enum, just pass off to regular show
if { 0 == [string equal -nocase $radix "enum"] } {
return [eval show $args]
}
# Now get the signal, its value and its type
set var [lindex [eval show $argv] 0]
set val [lindex [show $var -value] 1]
set typ [lindex [show $var -type] 1]
# If the type isnt an enum, error
if { 0 == [string equal -nocase [lindex $typ 0] "ENUM"] } {
return "The type of variable $var is not an enumerated type"
}
# Process the enumerations
set enuml [lindex $typ 2]
# Find the value name
foreach v $enuml {
if { $val == [lindex $v 1] } {
set enumname [lindex $v 0]
break
}
}
# If could not be found....
if { 0 == [info exists enumname] } {
return "The variabel $var has a value which does not map"
}
# Get rid of radix from args
getopt args -radix trashcan
# Replace all values with the name
set retval [eval show $args]
set retshow $retval
foreach v [lsearch -all $retval $val] {
set retshow [lreplace $retshow $v $v $enumname]
}
return $retshow
}
Thus, if I type any other non-radix enum eshow commands, it will pass to show, but otherwise, it will replace all values with thier names and return the same thing show would with the replacement. As I said, I REALLY want a better solution, but in case anyone wants to use my function, here it is.

Akka :: Using messages with different priorities over event stream in ActorSystem

I need to publish messages of different types to event stream, and those
messages should have different priorities for example, if 10 messages of type
A have been posted, and one message of type B is posted after all, and
priority of B is higher than the priority of A - message B should be picked up
by next actor even if there are 10 messages of type A in queue.
I have read about prioritized messages here and created my simple implementation of that mailbox:
class PrioritizedMailbox(settings: Settings, cfg: Config) extends UnboundedPriorityMailbox(
PriorityGenerator {
case ServerPermanentlyDead => println("Priority:0"); 0
case ServerDead => println("Priority:1"); 1
case _ => println("Default priority"); 10
}
)
then I configured it in application.conf
akka {
actor {
prio-dispatcher {
type = "Dispatcher"
mailbox-type = "mailbox.PrioritizedMailbox"
}
}
}
and wired into my actor:
private val myActor = actors.actorOf(
Props[MyEventHandler[T]].
withRouter(RoundRobinRouter(HIVE)).
withDispatcher("akka.actor.prio-dispatcher").
withCreator(
new Creator[Actor] {
def create() = new MyEventHandler(storage)
}), name = "eventHandler")
I'm using ActorSystem.eventStream.publish in order to send messages, and my actor
is subscribed to it (I can see in logs that messages are processed, but in
FIFO order).
However looks like it is not enough, because in logs/console I've never seen the
messages like "Default priority". Am I missing something here? Does the
described approach work with event streams or just with direct invocations of
sending a message on actor? And how do I get prioritized messages with
eventStream?
Your problem is that your actors are insanely fast so messages get processed before they have time to queue up, so there cannot be any priorization done by the mailbox. The example below proves the point:
trait Foo
case object X extends Foo
case object Y extends Foo
case object Z extends Foo
class PrioritizedMailbox(settings: ActorSystem.Settings, cfg: Config)
extends UnboundedPriorityMailbox(
PriorityGenerator {
case X ⇒ 0
case Y ⇒ 1
case Z ⇒ 2
case _ ⇒ 10
})
val s = ActorSystem("prio", com.typesafe.config.ConfigFactory.parseString(
""" prio-dispatcher {
type = "Dispatcher"
mailbox-type = "%s"
}""".format(classOf[PrioritizedMailbox].getName)))
val latch = new java.util.concurrent.CountDownLatch(1)
val a = s.actorOf(Props(new akka.actor.Actor {
latch.await // Just wait here so that the messages are queued up
inside the mailbox
def receive = {
case any ⇒ /*println("Processing: " + any);*/ sender ! any
}
}).withDispatcher("prio-dispatcher"))
implicit val sender = testActor
a ! "pig"
a ! Y
a ! Z
a ! Y
a ! X
a ! Z
a ! X
a ! "dog"
latch.countDown()
Seq(X, X, Y, Y, Z, Z, "pig", "dog") foreach { x => expectMsg(x) }
s.shutdown()
This test passes with flying colors

How can this perl sub be optimised for speed?

The following perl sub is used to store arrays of hashes.
Each hash to be stored is first checked for uniqueness using a given key, if a hash exists on the array with the same key value then it's not stored.
How can this perl sub be optimised for speed?
Example use:
my #members;
...
$member= {};
$hash->{'name'}='James';
hpush('name', \#members,$member);
The sub:
sub hpush {
# push a set of key value pairs onto an array as a hash, if the key doesn't already exist
if (#_ != 3) {
print STDERR "hpush requires 3 args, ".#_." given\n";
return;
}
my $uniq = shift;
my $rarray = shift;
my $rhash = shift;
my $hash = ();
#print "\nHash:\n";
for my $key ( keys %{$rhash} ) {
my $valuea = $rhash->{$key};
#print "key: $key\n";
#print "key=>value: $key => $valuea\n";
$hash->{ $key} = $valuea;
}
#print "\nCurrent Array:\n";
for my $node (#{$rarray}) {
#print "node: $node \n";
for my $key ( keys %{$node} ) {
my $valueb = $node->{$key};
#print "key=>value: $key => $valueb\n";
if ($key eq $uniq) {
#print "key=>value: $key => $valueb\n";
if (($valueb =~ m/^[0-9]+$/) && ($hash->{$key} == $valueb)) {
#print "Not pushing i $key -> $valueb\n";
return;
} elsif ($hash->{$key} eq $valueb) {
#print "Not pushing s $key -> $valueb\n";
return;
}
}
}
}
push #{$rarray}, $hash;
#print "Pushed\n";
}
Note that the perl isn't mine and I'm a perl beginner
This code is rather... not very efficient. First, it copies $rhash to $hash, with a for loop... for some reason. Then it loops through the hash keys, instead of simply using the hash key that it's looking for. Then it does two equivalent checks, apparently some attempt to distinguish numbers from non-numbers and selecting the appropriate check (== or eq). This is all unnecessary.
This code below should be roughly equivalent. I've trimmed it down hard. This should be as fast as it is possible to get it.
use strict;
use warnings;
hpush('name', \#members,$member);
sub hpush {
my ($uniq, $rarray, $rhash) = #_;
for my $node (#{$rarray}) {
if (exists $node->{$uniq}) {
return if ($node->{$uniq} eq $rhash->{$uniq});
}
}
push #{$rarray}, $rhash;
}

Resources