Sequential Table (C++)

Keywords: C++ data structure

Sequence table

Sequential table is a simple linear structure. Logically adjacent data is stored adjacent to each other in the computer. It can quickly locate the number of elements, allow null values in the middle, and move a large number of elements when inserting or deleting.

Three elements of a sequence table

  • Use elems to record the base address of the storage location.
  • Allocate a continuous storage space size (the number of elements that can be stored).
  • Use length to record the actual number of elements, that is, the length of the sequence table (the number of elements actually stored now).

Diagram

code implementation

#define MAX_SIZE 100

typedef int ElemsType;

typedef struct _SqList
{
	ElemsType* elems;
	int length;//length
	int size;//capacity
}SqList;

//Initialization
bool initSqList(SqList &sqlist)
{
	sqlist.elems = new int[MAX_SIZE];
	if (!sqlist.elems)//Discovery failure returns directly
	{
		return false;
	}
	sqlist.length = 0;
	sqlist.size = MAX_SIZE;
	return true;
}
//Print the entire list
void printSqList(SqList &sqlist)
{
	for (int i = 0; i < sqlist.length; i++)
	{
		cout << sqlist.elems[i] << " ";
	}
	cout << endl;
}
//Order Table Add Elements
bool addSqList(SqList& sqlist,int e)
{
	if (sqlist.length == sqlist.size)
	{
		return false;
	}
	sqlist.elems[sqlist.length] = e;
	sqlist.length++;
	return true;
}

//Insert element at specified location
bool insertSqList(SqList& sqlist,int index,int e)
{
	//Judgment of Legality
	if (index < 0 || index >= sqlist.length)
	{
		return false;
	}
	if (sqlist.length == sqlist.size)
	{
		return false;
	}
	for (int j= sqlist.length-1; j >= index; j--)
	{
		sqlist.elems[j + 1] = sqlist.elems[j];
	}
	sqlist.elems[index] = e;
	sqlist.length++;
	return true;
}
//Delete the specified location element
bool deleteSqList(SqList& sqlist, int index)
{
	if (index < 0 || index >= sqlist.length)
	{
		return false;
	}
	if (index == sqlist.length)
	{
		sqlist.length--;
		return true;
	}
	for (int j = index; j < sqlist.length; j++)
	{
		sqlist.elems[j] = sqlist.elems[j + 1];
	}
	sqlist.length--;
	return true;
}
//Destroy entire table
void destorySqList(SqList& sqlist)
{
	if (sqlist.elems)
	{
		delete[]sqlist.elems;
	}
	sqlist.length = 0;
	sqlist.size = 0; 
}

practical application

Application of Sequential Table in High Concurrent WEB Server

Squid, a high-performance web server, handles tens of thousands of concurrent requests per second. Clients connecting to the server from the network interact with the server while maintaining a session (similar to a phone call scenario). To manage all client connections, the server assigns a unique integer number to each connection, called a file handle, or fd for short.

To prevent some malicious connections from consuming system resources, the server needs to close the connections of clients when a client connection times out (no data is sent for a set period of time).

Specific implementation:

1. When a new request connects to the server, if it appears to be a malicious connection, as judged by the server frequency restriction module, the timeout data for this connection is stored in a sequential table. The timeout value is expressed by a timestamp, which is 00:00 minutes and 00 seconds Greenwich Time on January 01, 1970 (equivalent to 08:00 minutes and 00 seconds on January 01, 1970 in Beijing Time)The total number of seconds from now on.

supplement:
	Find the current timestamp
    time_t now;
    time(&now);
    cout << "Current timestamp:" << now << endl;

Its structure is defined as follows:

typedef struct { 
	int fd; 
	time_t timeout; // Use timestamp representation of timeout time-out time
}ConnTimeout;

2. The server program scans all connections every second to check if they have timed out. If there are timed out connections, close them, end the service, and clear the records in the sequence table!

Rough implementation process (related interfaces not implemented)

static void checkTimeOut(TimeOutSqList& list,time_t now)
{
   int fd,i;
    cout<<"Check timeout"<<endl;
    for(int i = 0 ; i  < list.length;i++)
    {
        if(list.emels[i].timeout > now)
        {
            continue;
        }
        //Timeout Cleanup
        fd = list.emels[i].fd;
        //Close Link - Simulation
        cout<<"Close Link"<<ednl;
		listDelete(list,i);//Note that the order table moves, notice omissions
        i--;
    }
}
int main(void)
{
    time_t now,end;
    time_t last_timeout;//Perform timeout detection once per second
    TimeOutSqList list;
    
    time(&now);
    end  = now+60;//Just process for one minute and exit the loop after 60s
    
    initList(list);
    //Increase malicious connections to sequential tables by judgment analysis through frequency limit module
    for(int i = 0;i< 10;i++)
    {
        ConnectTimeOut e;
        e.df = i;
        e.timeout = now + i *2;
		listAdd(list,e);
    }
    listPrint(list);
    
    do
    {
        //Control 1 (a few) seconds to do something once
        if(last_timeout + 0.999 < now)
        {
            checkTimeOut(list,now);	
            last_timeout = now;
		}
        Sleep(10);
        time(&now);//Read Present Time
	}while(end > now);
    
    
    return 0;
}

(Understanding the role of sequence tables in this is enough.)

Posted by MadDawgX on Sun, 03 Oct 2021 09:31:32 -0700