<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Timestamp Scheduler</title>
</head>

<body>



<p align="left"><font size="6" color="#FF0000"><span lang="en-ca"><b>&nbsp; 
 
</b></span><b>&nbsp;&nbsp;&nbsp; </b></font><span lang="en-ca">
<font size="6" color="#FF0000"><b>Scheduler-I</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A. <span lang="en-ca">First </span>Edition</font></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>This is just for fun. You know, in DBMS you can find almost everything in OS. Scheduler is one of them. Actually</b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>I want to implement a small simulation of transaction-control algorithm in DBMS which uses time-stamp of </b></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><b>transactions and database elements. But starting this environment takes me a whole day. </b></span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
  <span lang="en-ca"><b>In DBMS, there is basically two big schemes for 
  transaction control: locking and timestamp. I want </b></span>
  <p><span lang="en-ca"><b>to simulate timestamp first. Then we have first to 
  define what is a transaction. After that you </b></span></p>
  <p><span lang="en-ca"><b>need to define what is a task. </b>. </span></p>
  <b><font color="#ff0000" size="5"><span lang="en-ca"><a name="explain"></a>C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  　</div>
<p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>There is a big common thing 
between task pool and transaction pool---they can both be implemented as a kind 
of</b></font></span></p>
<p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>special queue. Therefore, I 
defined a template queue. </b></font></span></p>
<p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>Then I plan to write 
scheduler whose scheduling scheme would most probably round-robin.&nbsp; </b>
</font></span></p>
<p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>Probably many people would 
find difficult in understanding the purpose of many functions. Actually almost 
every</b></font></span></p>
<p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>time I try to write some 
program, it is like an adventure for me in C++. This time, I found I don't need 
to </b></font></span></p>
<p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>stick to the idea of class. 
Instead, struct and class are basically same thing in defining member functions
</b></font></span></p>
<p ALIGN="LEFT"><span lang="en-ca"><font size="2"><b>except in struct all are 
all public, and in class all are private, by default.</b></font></span></p>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">E</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">F</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>File listing</b></font></span></pre>
</div>
<div align="left">
  <pre><font size="3"><b><span lang="en-ca">1. scheduler.h</span></b></font></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>2</b></font></span><font size="3"><b><span lang="en-ca">. scheduler.</span></b></font><span lang="en-ca"><font size="3"><b>cpp</b></font></span></pre>
</div>
<div align="left">
  <pre><font size="3"><b><span lang="en-ca">1. main.cpp</span></b></font></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3" color="#FF0000"><b>file name: scheduler.h</b></font></span></pre>
</div>
<pre>
const int MaxTaskCount=10;
const int MaxTransCount=10;
const int MaxElementCount=4;
const int MaxTaskItemCount=200;

enum TaskType
{
	Read, Write, Commit, Abort
};

struct Element
{
	int ID;
	int readStamp;
	int writeStamp;
	bool committed;
	void display();
};	

struct Task
{
	int element;
	TaskType taskType;
	void display();
};

struct Transaction
{
	int timeStamp;
	int count;
	int current;
	Task tasks[MaxTaskCount];
	void moveNext(int&amp; index);
	bool haveNext();
	Task* operator[](int index){return tasks+index;}
	void display();
};


	
template&lt;class T, int MaxListLength&gt;
class Queue
{
protected:
	T list[MaxListLength];
	int count;
	int front, back, current;
public:
	Queue();
	inline int getCount(){return count;}
	bool enqueue(T*&amp; outPtr);
	bool dequeue(T*&amp; outPtr);
	T* next();
	void display();
	T* operator[](int index);
	void remove(int index);
};

struct TaskItem
{
	int transID;
	int taskIndex;
	void display();
};

class TransPool
{
private:
	Queue&lt;Transaction, MaxTransCount&gt; list;
public:
	TransPool();
	void createTrans(int timeStamp);
	Transaction* next();
	void destroyTrans();
	void display(){ list.display();}
};
	
class TaskPool
{
private:
	Queue&lt;TaskItem, MaxTaskItemCount&gt; list;
public:
	void addItem(Transaction* transPtr);
	void update(int transID);//put status on
	void display(){ list.display();}
};

class Scheduler
{
private:
	int timeStamp;
	TransPool transPool;
	TaskPool taskPool;

	void createTrans();
	void tickTimer();
	void execTask();
	void addTask();
	void destroyTrans();
	void showStatus();
public:
	void display();
	void doJob(int step);
	Scheduler();
};

template&lt;class T, int MaxListLength&gt;
void Queue&lt;T, MaxListLength&gt;::display()
{
	for (int i=0; i&lt;count; i++)
	{
		list[(back+i)%MaxListLength].display();
	}
}


template&lt;class T, int MaxListLength&gt;
void Queue&lt;T, MaxListLength&gt;::remove(int index)
{	
	if (index&lt;count)
	{
		for (int i=index; i&lt;count-1; i++)
		{
			this-&gt;operator[](i)-&gt;operator=(*(this-&gt;operator[](i+1)));
			count--;
			if (current==front)
			{
				current=(back+count-1)%MaxListLength;
			}
			//else current doesn't matter
			front=(back+count-1)%MaxListLength;//different module
		}
	}
}


template&lt;class T, int MaxListLength&gt;
T* Queue&lt;T, MaxListLength&gt;::operator [](int index)
{
	if (index&lt;count)
	{
		return list+(back+index)%count;
	}
	else
	{
		return NULL;
	}
}

template&lt;class T, int MaxListLength&gt;
Queue&lt;T, MaxListLength&gt;::Queue()
{
	front=back=current=count=0;
}

template&lt;class T, int MaxListLength&gt;
bool Queue&lt;T, MaxListLength&gt;::enqueue(T*&amp; outPtr)
{
	if (count+1&lt;MaxListLength)
	{
		count++;
		outPtr=list+front;//return first
		front=(front+1)%MaxListLength;		
		return true;
	}
	else
	{
		return false;
	}
}

template&lt;class T, int MaxListLength&gt;
bool Queue&lt;T, MaxListLength&gt;::dequeue(T*&amp; outPtr)
{
	if (count&gt;0)
	{
		count--;
		outPtr=list+back;
		if (current==back)
		{
			back=(back+1)%MaxListLength;
		}
		back=(back+1)%MaxListLength;
		return true;
	}
	else
	{
		return false;
	}
}

template&lt;class T, int MaxListLength&gt;
T* Queue&lt;T, MaxListLength&gt;::next()
{	
	if (count==0)
	{
		return NULL;
	}
	if (current==front)
	{
		current=back;
	}
	return list+current;
}



</pre>
<pre><span lang="en-ca"><font size="3" color="#FF0000"><b>file name: scheduler.cpp</b></font></span></pre>
<pre>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &quot;scheduler.h&quot;

const int ScheduleTaskNumber=3;

char* typeString[]=
{
	&quot;Read&quot;, &quot;Write&quot;, &quot;Commit&quot;, &quot;Abort&quot;
};

Scheduler::Scheduler()
{
	timeStamp=0;
}

void Scheduler::doJob(int step)
{
	for (int i=0; i&lt;step; i++)
	{
		tickTimer();
		switch(rand()%ScheduleTaskNumber)
		{
		case 0:
			transPool.createTrans(timeStamp);
			break;
		case 1:
			addTask();
			break;
		case 2:
			execTask();
			break;
		}
		showStatus();
	}
}

void Scheduler::addTask()
{
	Transaction* ptr;
	if ((ptr=transPool.next())!=NULL)
	{
		taskPool.addItem(ptr);
	}
}

void Scheduler::showStatus()
{
	printf(&quot;time is %d;\n*****************************\n&quot;, timeStamp);
	printf(&quot;transaction pool is:\n&quot;);
	transPool.display();
	printf(&quot;task pool is:\n&quot;);
	taskPool.display();
}

void Scheduler::display()
{
	showStatus();
}



void Scheduler::tickTimer()
{
	timeStamp++;
}

void Scheduler::execTask()
{
	taskPool.display();
}

void TaskPool::update(int transID)
{
	TaskItem* ptr;
	for (int i=0; i&lt;list.getCount(); i++)
	{
		ptr=list.next();
		if (ptr!=NULL)
		{
			//if (ptr-&gt;ti
		}
	}
}

void TaskPool::addItem(Transaction* transPtr)
{
	TaskItem* ptr;
	int index;
	if (!transPtr-&gt;haveNext())
	{
		return;
	}
	if (list.enqueue(ptr))
	{
		ptr-&gt;transID=transPtr-&gt;timeStamp;
		transPtr-&gt;moveNext(index);
		ptr-&gt;taskIndex=index;
	}
}

void Element::display()
{
	printf(&quot;Element ID=%d; read stamp=%d; write stamp=%d; committed=%c\n&quot;,
		ID, readStamp, writeStamp, committed?'T':'F');
}

bool Transaction::haveNext()
{
	return current+1&lt;count;
}

void Transaction::moveNext(int&amp; index)
{
	index=current;
	current++;
}



void Task::display()
{
	printf(&quot;Task element=%c, type=%s\n&quot;, element+'A', typeString[taskType]);
}

void Transaction::display()
{
	printf(&quot;Transaction timestamp=%d; count=%d; current=%d;\n&quot;, timeStamp,
		count, current);
	for (int i=0; i&lt;count; i++)
	{
		tasks[i].display();
	}
}

void TaskItem::display()
{
	printf(&quot;Task item: transaction time stamp=%d; task index=%d\n&quot;, transID, taskIndex);
}

TransPool::TransPool()
{

}

void TransPool::createTrans(int timeStamp)
{
	Transaction* ptr;
	if (list.enqueue(ptr))
	{
		ptr-&gt;timeStamp=	timeStamp;
		ptr-&gt;count=rand()%MaxTaskCount+1;
		for (int i=0; i&lt;ptr-&gt;count; i++)
		{
			ptr-&gt;tasks[i].taskType=rand()%2==0?Read:Write;
			ptr-&gt;tasks[i].element=rand()%MaxElementCount;			
		}
		ptr-&gt;current=0;	
		
	}
	//else do nothing
}


void TransPool::destroyTrans()
{
	Transaction* ptr;
	if (list.dequeue(ptr))
	{
		printf(&quot;transaction with timestamp of %d destroyed\n&quot;, ptr-&gt;timeStamp);
	}
}

Transaction* TransPool::next()
{
	return list.next();
}



</pre>
<pre>


</pre>
<pre><span lang="en-ca"><font size="3" color="#FF0000"><b>file name: main.cpp</b></font></span></pre>
<pre>#include &quot;scheduler.h&quot;



int main()
{
	Scheduler S;
	S.doJob(10);
	return 0;
}</pre>
<pre></pre>
<pre></pre>
<pre><span lang="en-ca"><font color="#0000FF"><b>How to run?</b></font></span></pre>
<pre><span lang="en-ca"><font color="#0000FF"><b>1.This is just a startup of environment. So, I just implement the display function for debugging.</b></font></span></pre>
<p>time is 1;<br>
*****************************<br>
transaction pool is:<br>
task pool is:<br>
time is 2;<br>
*****************************<br>
transaction pool is:<br>
task pool is:<br>
time is 3;<br>
*****************************<br>
transaction pool is:<br>
task pool is:<br>
time is 4;<br>
*****************************<br>
transaction pool is:<br>
task pool is:<br>
time is 5;<br>
*****************************<br>
transaction pool is:<br>
task pool is:<br>
time is 6;<br>
*****************************<br>
transaction pool is:<br>
task pool is:<br>
time is 7;<br>
*****************************<br>
transaction pool is:<br>
Transaction timestamp=7; count=9; current=0;<br>
Task element=A, type=Read<br>
Task element=B, type=Write<br>
Task element=D, type=Write<br>
Task element=D, type=Write<br>
Task element=C, type=Write<br>
Task element=A, type=Write<br>
Task element=A, type=Write<br>
Task element=B, type=Read<br>
Task element=C, type=Read<br>
task pool is:<br>
time is 8;<br>
*****************************<br>
transaction pool is:<br>
Transaction timestamp=7; count=9; current=0;<br>
Task element=A, type=Read<br>
Task element=B, type=Write<br>
Task element=D, type=Write<br>
Task element=D, type=Write<br>
Task element=C, type=Write<br>
Task element=A, type=Write<br>
Task element=A, type=Write<br>
Task element=B, type=Read<br>
Task element=C, type=Read<br>
Transaction timestamp=8; count=7; current=0;<br>
Task element=D, type=Read<br>
Task element=C, type=Write<br>
Task element=C, type=Write<br>
Task element=A, type=Write<br>
Task element=D, type=Write<br>
Task element=C, type=Write<br>
Task element=D, type=Write<br>
task pool is:<br>
time is 9;<br>
*****************************<br>
transaction pool is:<br>
Transaction timestamp=7; count=9; current=0;<br>
Task element=A, type=Read<br>
Task element=B, type=Write<br>
Task element=D, type=Write<br>
Task element=D, type=Write<br>
Task element=C, type=Write<br>
Task element=A, type=Write<br>
Task element=A, type=Write<br>
Task element=B, type=Read<br>
Task element=C, type=Read<br>
Transaction timestamp=8; count=7; current=0;<br>
Task element=D, type=Read<br>
Task element=C, type=Write<br>
Task element=C, type=Write<br>
Task element=A, type=Write<br>
Task element=D, type=Write<br>
Task element=C, type=Write<br>
Task element=D, type=Write<br>
task pool is:<br>
time is 10;<br>
*****************************<br>
transaction pool is:<br>
Transaction timestamp=7; count=9; current=0;<br>
Task element=A, type=Read<br>
Task element=B, type=Write<br>
Task element=D, type=Write<br>
Task element=D, type=Write<br>
Task element=C, type=Write<br>
Task element=A, type=Write<br>
Task element=A, type=Write<br>
Task element=B, type=Read<br>
Task element=C, type=Read<br>
Transaction timestamp=8; count=7; current=0;<br>
Task element=D, type=Read<br>
Task element=C, type=Write<br>
Task element=C, type=Write<br>
Task element=A, type=Write<br>
Task element=D, type=Write<br>
Task element=C, type=Write<br>
Task element=D, type=Write<br>
Transaction timestamp=10; count=4; current=0;<br>
Task element=B, type=Read<br>
Task element=B, type=Write<br>
Task element=D, type=Read<br>
Task element=C, type=Read<br>
task pool is:<br>
Press any key to continue</p>

<pre>
</pre>

<pre>　</pre>

<pre></pre>

<pre></pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="PocketRuler.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm">
<img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>