diff -urN ns-standard/common/scheduler.cc ns-HEAP/common/scheduler.cc
--- ns-standard/common/scheduler.cc	2005-01-25 14:38:47.000000000 -0800
+++ ns-HEAP/common/scheduler.cc	2005-09-23 22:16:26.911841136 -0700
@@ -34,6 +34,13 @@
  * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/scheduler.cc,v 1.71 2003/03/04 01:15:42 yuri Exp $
  */
 
+/* Sep 2005: David Wei (weixl@caltech.edu):
+ * change the Calendar Queue to be heap queue -- THIS IS AN AD-HOC HACK.
+ * 1. change insert, dequeue and other related function
+ * 2. The cancel function now takes care of the event deletion. So all callers should assume that its event is 
+ *    deleted after calling cancel.
+ */
+
 #ifndef lint
 static const char rcsid[] =
     "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/scheduler.cc,v 1.71 2003/03/04 01:15:42 yuri Exp $ (LBL)";
@@ -43,6 +50,9 @@
 #include <limits.h>
 #include <math.h>
 
+#include <algorithm>
+#include <functional>
+
 #include "config.h"
 #include "scheduler.h"
 #include "packet.h"
@@ -234,8 +244,8 @@
 			if (p != 0) {
 				/*XXX make sure it really is an atevent*/
 				cancel(p);
-				AtEvent* ae = (AtEvent*)p;
-				delete ae;
+				//AtEvent* ae = (AtEvent*)p;
+				//delete ae;
 			}
 		} else if (strcmp(argv[1], "at-now") == 0) {
 			const char* proc = argv[2];
@@ -569,7 +579,6 @@
  *  Comm. of ACM, 31(10):1220-1227, Oct 1988
  */
 
-#define CALENDAR_HASH(t) ((int)fmod((t)/width_, nbuckets_))
 
 static class CalendarSchedulerClass : public TclClass {
 public:
@@ -579,122 +588,39 @@
 	}
 } class_calendar_sched;
 
-CalendarScheduler::CalendarScheduler() : cal_clock_(clock_) {
-	reinit(4, 1.0, cal_clock_);
+
+struct compareEvent : public binary_function<Event*, Event*, bool> {
+    bool operator() (Event* a, Event* b) {return a->time_ > b->time_; };
+};
+
+CalendarScheduler::CalendarScheduler() {
+        size_ = 1024;
+	delta_size_ = 1024;
+	qsize_ = 0;
+        event_queue_ = new Event*[size_];
 }
 
 CalendarScheduler::~CalendarScheduler() {
 	// XXX free events?
-	delete [] buckets_;
+	delete [] event_queue_;
+	size_ = 0;
 	qsize_ = 0;
-	stat_qsize_ = 0;
 }
 
 void 
 CalendarScheduler::insert(Event* e)
 {
-	int i;
-	if (cal_clock_ > e->time_) {
-		// may happen in RT scheduler
-		cal_clock_ = e->time_;
-		i = lastbucket_ = CALENDAR_HASH(cal_clock_);
-	} else
-		i = CALENDAR_HASH(e->time_);
-
-	Event *head = buckets_[i].list_;
-	Event *before=0;
-
-	if (!head) {
-		buckets_[i].list_ = e;
-		e->next_ = e->prev_ = e;
-		++stat_qsize_; 
-		++buckets_[i].count_;
-	} else {
-		bool newhead;
-		if (e->time_ >= head->prev_->time_) {
-			// insert at the tail
-			before = head;
-			newhead = false;
-		} else {
-			// insert event in time sorted order, FIFO for sim-time events
-			for (before = head; e->time_ >= before->time_; before = before->next_)
-				;
-			newhead = (before == head);
-		}
-
-		e->next_ = before;
-		e->prev_ = before->prev_;
-		before->prev_ = e;
-		e->prev_->next_ = e;
-		if (newhead) {
-			buckets_[i].list_ = e;
-			//assert(e->time_ <= e->next_->time_);
-		}
-		//assert(e->prev_ != e);
-		if (e->prev_->time_ != e->time_) {
-			// unique timing
-			++stat_qsize_; 
-			++buckets_[i].count_;
-		}
-	}
-	++qsize_;
-	//assert(e == buckets_[i].list_ ||  e->prev_->time_ <= e->time_);
-	//assert(e == buckets_[i].list_->prev_ || e->next_->time_ >= e->time_);
-
-  	if (stat_qsize_ > top_threshold_) {
-  		resize(nbuckets_ << 1, cal_clock_);
-		return;
-	}
-}
-
-void 
-CalendarScheduler::insert2(Event* e)
-{
-	// Same as insert, but for inserts e *before* any same-time-events, if
-	//   there should be any.  Since it is used only by CalendarScheduler::newwidth(),
-	//   some important checks present in insert() need not be performed.
-
-	int i = CALENDAR_HASH(e->time_);
-	Event *head = buckets_[i].list_;
-	Event *before=0;
-	if (!head) {
-		buckets_[i].list_ = e;
-		e->next_ = e->prev_ = e;
-		++stat_qsize_; 
-		++buckets_[i].count_;
-	} else {
-		bool newhead;
-		if (e->time_ > head->prev_->time_) { //strict LIFO, so > and not >=
-			// insert at the tail
-			before = head;
-			newhead = false;
-		} else {
-			// insert event in time sorted order, LIFO for sim-time events
-			for (before = head; e->time_ > before->time_; before = before->next_)
-				;
-			newhead = (before == head);
-		}
-
-		e->next_ = before;
-		e->prev_ = before->prev_;
-		before->prev_ = e;
-		e->prev_->next_ = e;
-		if (newhead) {
-			buckets_[i].list_ = e;
-			//assert(e->time_ <= e->next_->time_);
-		}
-
-		if (e != e->next_ && e->next_->time_ != e->time_) {
-			// unique timing
-			++stat_qsize_; 
-			++buckets_[i].count_;
-		}
-	}
-	//assert(e == buckets_[i].list_ ||  e->prev_->time_ <= e->time_);
-	//assert(e == buckets_[i].list_->prev_ || e->next_->time_ >= e->time_);
-
-	++qsize_;
-	// no need to check resizing
+	qsize_++;
+	if (qsize_ >= size_) {
+		//resize here
+		Event** old_queue = event_queue_;
+		size_ += delta_size_;
+		event_queue_ = new Event*[size_];
+		memcpy(event_queue_, old_queue, size_*sizeof(Event*));
+	};
+	event_queue_[qsize_-1] = e;
+	if (qsize_>1)
+		push_heap(event_queue_, event_queue_ + qsize_, compareEvent());
 }
 
 const Event*
@@ -702,184 +628,26 @@
 {
 	if (qsize_ == 0)
 		return NULL;
-
-	int l, i = lastbucket_;
-	int lastbucket_dec = (lastbucket_) ? lastbucket_ - 1 : nbuckets_ - 1;
-	double diff;
-	Event *e, *min_e = NULL;
-#define CAL_DEQUEUE(x) 						\
-do { 								\
-	if ((e = buckets_[i].list_) != NULL) {			\
-		diff = e->time_ - cal_clock_;			\
-		if (diff < diff##x##_)	{			\
-			l = i;					\
-			goto found_l;				\
-		}						\
-		if (min_e == NULL || min_e->time_ > e->time_) {	\
-			min_e = e;				\
-			l = i;					\
-		}						\
-	}							\
-	if (++i == nbuckets_) i = 0;				\
-} while (0)
-		 
-	// CAL_DEQUEUE applied successively will find the event to
-	// dequeue (within one year) and keep track of the
-	// minimum-priority event seen so far; the argument controls
-	// the criteria used to decide whether the event should be
-	// considered `within one year'.  Importantly, the number of
-	// buckets should not be less than 4.
-	CAL_DEQUEUE(0); 
-	CAL_DEQUEUE(1); 
-	for (; i != lastbucket_dec; ) {
-		CAL_DEQUEUE(2);
-	}
-	// one last bucket is left unchecked - take the minimum
-	// [could have done CAL_DEQUEUE(3) with diff3_ = bwidth*(nbuck*3/2-1)]
-	e = buckets_[i].list_;
-	if (min_e != NULL && 
-	    (e == NULL || min_e->time_ < e->time_))
-		e = min_e;
-	else {
-		//assert(e);
-		l = i;
-	}
- found_l:
-	//assert(buckets_[l].count_ >= 0);
-	//assert(buckets_[l].list_ == e);
-
-	/* l is the index of the bucket to dequeue, e is the event */
-	/* 
-	 * still want to advance lastbucket_ and cal_clock_ to save
-	 * time when deque() follows. 
-	 */
-	lastbucket_ = l;
- 	cal_clock_  = e->time_;
-	
-	return e;
+	else
+		return event_queue_[0];
 }
 
 Event* 
 CalendarScheduler::deque()
 {
-	Event *e = const_cast<Event *>(head());
-
-	if (!e)
-		return 0;
-
-	int l = lastbucket_;
-
-	// update stats and unlink
-	if (e->next_ == e || e->next_->time_ != e->time_) {
-		--stat_qsize_;
-		//assert(stat_qsize_ >= 0);
-		--buckets_[l].count_;
-		//assert(buckets_[l].count_ >= 0);
-
-	}
-	--qsize_;
-
-	if (e->next_ == e)
-		buckets_[l].list_ = 0;
-	else {
-		e->next_->prev_ = e->prev_;
-		e->prev_->next_ = e->next_;
-		buckets_[l].list_ = e->next_;
-	}
-
-	e->next_ = e->prev_ = NULL;
-
-
-	//if (buckets_[l].count_ == 0)
-	//	assert(buckets_[l].list_ == 0);
-
- 	if (stat_qsize_ < bot_threshold_) {
-		resize(nbuckets_ >> 1, cal_clock_);
-	}
-
-	return e;
-}
-
-void 
-CalendarScheduler::reinit(int nbuck, double bwidth, double start)
-{
-	buckets_ = new Bucket[nbuck];
-
-	memset(buckets_, 0, sizeof(Bucket)*nbuck); //faster than ctor
-
-	width_ = bwidth;
-	nbuckets_ = nbuck;
-	qsize_ = 0;
-	stat_qsize_ = 0;
-
-	lastbucket_ =  CALENDAR_HASH(start);
-
-	diff0_ = bwidth*nbuck/2;
-	diff1_ = diff0_ + bwidth;
-	diff2_ = bwidth*nbuck;
-	//diff3_ = bwidth*(nbuck*3/2-1);
-
-	bot_threshold_ = (nbuck >> 1) - 2;
-	top_threshold_ = (nbuck << 1);
+    while (1) {
+	    if (qsize_ == 0) 
+		    return NULL;
+	    pop_heap(event_queue_, event_queue_ + qsize_, compareEvent());
+	    qsize_ --;
+	    if (event_queue_[qsize_]->uid_ < 0) {
+		    delete event_queue_[qsize_];
+	    }
+	    else
+	    	    return event_queue_[qsize_];
+    }
 }
 
-void 
-CalendarScheduler::resize(int newsize, double start)
-{
-	double bwidth = newwidth(newsize);
-
-	if (newsize < 4)
-		newsize = 4;
-
-	Bucket *oldb = buckets_;
-	int oldn = nbuckets_;
-
-	reinit(newsize, bwidth, start);
-
-	// copy events to new buckets
-	int i;
-
-	for (i = 0; i < oldn; ++i) {
-		// we can do inserts faster, if we use insert2, but to
-		// preserve FIFO, we have to start from the end of
-		// each bucket and use insert2
-		if  (oldb[i].list_) {
-			Event *tail = oldb[i].list_->prev_;
-			Event *e = tail; 
-			do {
-				Event* ep = e->prev_;
-				e->next_ = e->prev_ = 0;
-				insert2(e);
-				e = ep;
-			} while (e != tail);
-		}
-	}
-	delete [] oldb;
-}
-
-// take samples from the most populated bucket.
-double
-CalendarScheduler::newwidth(int newsize)
-{
-	int i;
-	int max_bucket = 0; // index of the fullest bucket
-	for (i = 1; i < nbuckets_; ++i) {
-		if (buckets_[i].count_ > buckets_[max_bucket].count_)
-			max_bucket = i;
-	}
-	int nsamples = buckets_[max_bucket].count_;
-
-	if (nsamples <= 4) return width_;
-	
-	double nw = buckets_[max_bucket].list_->prev_->time_ 
-		- buckets_[max_bucket].list_->time_;
-	assert(nw > 0);
-	
-	nw /= ((newsize < nsamples) ? newsize : nsamples); // min (newsize, nsamples)
-	nw *= 4.0;
-	
-	return nw;
-}
 
 /*
  * Cancel an event.  It is an error to call this routine
@@ -891,59 +659,35 @@
 void 
 CalendarScheduler::cancel(Event* e)
 {
-	if (e->uid_ <= 0)	// event not in queue
-		return;
-
-	int i = CALENDAR_HASH(e->time_);
-
-	assert(e->prev_->next_ == e);
-	assert(e->next_->prev_ == e);
-
-	if (e->next_ == e || 
-	    (e->next_->time_ != e->time_ &&
-	    (e->prev_->time_ != e->time_))) { 
-		--stat_qsize_;
-		assert(stat_qsize_ >= 0);
-		--buckets_[i].count_;
-		assert(buckets_[i].count_ >= 0);
-	}
-
-	if (e->next_ == e) {
-		assert(buckets_[i].list_ == e);
-		buckets_[i].list_ = 0;
-	} else {
-		e->next_->prev_ = e->prev_;
-		e->prev_->next_ = e->next_;
-		if (buckets_[i].list_ == e)
-			buckets_[i].list_ = e->next_;
-	}
-
-	if (buckets_[i].count_ == 0)
-		assert(buckets_[i].list_ == 0);
-
-	e->uid_ = -e->uid_;
-	e->next_ = e->prev_ = NULL;
-
-	--qsize_;
+    if (e == NULL) return;
 
+    if (e->uid_ <= 0)       // event not in queue
 	return;
-}
 
+    e->uid_ = -100;
+    return;
+	
+    for (int i=0; i< qsize_; i++)
+    if (event_queue_[i]==e) {
+            e->uid_ = -e->uid_; //change uid to none
+	    Event* tmp = new Event;
+	    tmp->time_ = e->time_;
+	    tmp->uid_ = -100;
+	    event_queue_[i] = tmp;
+	    //qsize_--;
+	    //event_queue_[i] = event_queue_[qsize_];
+	    //make_heap(event_queue_, event_queue_ + qsize_, compareEvent());
+	    return;
+    }
+}
 Event * 
 CalendarScheduler::lookup(scheduler_uid_t uid)
 {
-	for (int i = 0; i < nbuckets_; i++) {
-		Event* head =  buckets_[i].list_;
-		Event* p = head;
-		if (p) {
-			do {
-				if (p->uid_== uid) 
-					return p;
-				p = p->next_;
-			} while (p != head);
-		}
+    for (int i=0; i< qsize_; i++)
+	if (event_queue_[i]->uid_==uid) {
+	    return event_queue_[i];
 	}
-	return NULL;
+    return NULL;
 }
 
 #ifndef WIN32
diff -urN ns-standard/common/scheduler.h ns-HEAP/common/scheduler.h
--- ns-standard/common/scheduler.h	2005-01-19 10:23:18.000000000 -0800
+++ ns-HEAP/common/scheduler.h	2005-09-23 22:16:16.681396400 -0700
@@ -34,6 +34,15 @@
  * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/scheduler.h,v 1.26 2002/08/02 01:35:20 yuri Exp $ (LBL)
  */
 
+/* Sep 2005: David Wei (weixl@caltech.edu):
+ * change the Calendar Queue to be heap queue -- THIS IS AN AD-HOC HACK.
+ * See scheduler.cc for details
+ */
+
+#ifndef CALENDAR_NEW_WIDTH
+#define CALENDAR_NEW_WIDTH 1
+#endif
+
 #ifndef ns_scheduler_h
 #define ns_scheduler_h
 
@@ -152,31 +161,11 @@
 	Event* deque();
 	const Event* head();
 
-protected:
-	double width_;
-	double diff0_, diff1_, diff2_; /* wrap-around checks */
-
-	int stat_qsize_;		/* # of distinct priorities in queue*/
-	int nbuckets_;
-	int lastbucket_;
-	int top_threshold_;
-	int bot_threshold_;
-
-	struct Bucket {
-		Event *list_;
-		int    count_;
-	} *buckets_;
-		
-	int qsize_;
-
-	virtual void reinit(int nbuck, double bwidth, double start);
-	virtual void resize(int newsize, double start);
-	virtual double newwidth(int newsize);
-
 private:
-	virtual void insert2(Event*);
-	double cal_clock_;  // same as clock in sims, may be different in RT-scheduling.
-
+	int size_;
+	int qsize_;
+	int delta_size_;
+	Event** event_queue_;
 };
 
 class SplayScheduler : public Scheduler 
diff -urN ns-standard/common/timer-handler.h ns-HEAP/common/timer-handler.h
--- ns-standard/common/timer-handler.h	2005-01-19 10:23:18.000000000 -0800
+++ ns-HEAP/common/timer-handler.h	2005-09-23 22:18:04.539999400 -0700
@@ -20,6 +20,13 @@
  * @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/common/timer-handler.h,v 1.8 2000/11/02 22:46:37 johnh Exp $ (USC/ISI)
  */
 
+/* Sep 2005: David Wei (weixl@caltech.edu):
+ * change the Calendar Queue to be heap queue -- THIS IS AN AD-HOC HACK.
+ * See scheduler.cc for details
+ * The effect on the TimeHandler class: in additional to the statically allocated event, we need to clone a new event
+ * every time an event is inserted into the scheduling queue, since the event will be deleted if we cancel it.
+ */
+
 #ifndef timer_handler_h
 #define timer_handler_h
 
@@ -50,7 +57,7 @@
 
 class TimerHandler : public Handler {
 public:
-	TimerHandler() : status_(TIMER_IDLE) { }
+	TimerHandler() : status_(TIMER_IDLE),shadow_(NULL) { }
 
 	void sched(double delay);	// cannot be pending
 	void resched(double delay);	// may or may not be pending
@@ -73,13 +80,19 @@
 	virtual void handle(Event *);
 	int status_;
 	Event event_;
+	Event* shadow_;
 
 private:
 	inline void _sched(double delay) {
-		(void)Scheduler::instance().schedule(this, &event_, delay);
+		if (shadow_ == NULL) shadow_ = new Event;
+		(*shadow_) = event_;
+		(void)Scheduler::instance().schedule(this, shadow_, delay);
 	}
 	inline void _cancel() {
-		(void)Scheduler::instance().cancel(&event_);
+		if (shadow_ == NULL) return;
+		(void)Scheduler::instance().cancel(shadow_);
+		event_ = (*shadow_);
+		shadow_ = NULL;
 		// no need to free event_ since it's statically allocated
 	}
 };
