mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			60 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			60 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
How the timeout heap works
 | 
						|
 | 
						|
As of version 1.5, the State Threads Library represents the queue of
 | 
						|
sleeping threads using a heap data structure rather than a sorted
 | 
						|
linked list.  This improves performance when there is a large number
 | 
						|
of sleeping threads, since insertion into a heap takes O(log N) time
 | 
						|
while insertion into a sorted list takes O(N) time.  For example, in
 | 
						|
one test 1000 threads were created, each thread called st_usleep()
 | 
						|
with a random time interval, and then all the threads where
 | 
						|
immediately interrupted and joined before the sleeps had a chance to
 | 
						|
finish.  The whole process was repeated 1000 times, for a total of a
 | 
						|
million sleep queue insertions and removals.  With the old list-based
 | 
						|
sleep queue, this test took 100 seconds; now it takes only 12 seconds.
 | 
						|
 | 
						|
Heap data structures are typically based on dynamically resized
 | 
						|
arrays.  However, since the existing ST code base was very nicely
 | 
						|
structured around linking the thread objects into pointer-based lists
 | 
						|
without the need for any auxiliary data structures, implementing the
 | 
						|
heap using a similar nodes-and-pointers based approach seemed more
 | 
						|
appropriate for ST than introducing a separate array.
 | 
						|
 | 
						|
Thus, the new ST timeout heap works by organizing the existing
 | 
						|
_st_thread_t objects in a balanced binary tree, just as they were
 | 
						|
previously organized into a doubly-linked, sorted list.  The global
 | 
						|
_ST_SLEEPQ variable, formerly a linked list head, is now simply a
 | 
						|
pointer to the root of this tree, and the root node of the tree is the
 | 
						|
thread with the earliest timeout.  Each thread object has two child
 | 
						|
pointers, "left" and "right", pointing to threads with later timeouts.
 | 
						|
 | 
						|
Each node in the tree is numbered with an integer index, corresponding
 | 
						|
to the array index in an array-based heap, and the tree is kept fully
 | 
						|
balanced and left-adjusted at all times.  In other words, the tree
 | 
						|
consists of any number of fully populated top levels, followed by a
 | 
						|
single bottom level which may be partially populated, such that any
 | 
						|
existing nodes form a contiguous block to the left and the spaces for
 | 
						|
missing nodes form a contiguous block to the right.  For example, if
 | 
						|
there are nine threads waiting for a timeout, they are numbered and
 | 
						|
arranged in a tree exactly as follows:
 | 
						|
 | 
						|
              1
 | 
						|
           /     \
 | 
						|
          2       3
 | 
						|
         / \     / \
 | 
						|
        4   5   6   7
 | 
						|
       / \
 | 
						|
      8   9
 | 
						|
 | 
						|
Each node has either no children, only a left child, or both a left
 | 
						|
and a right child.  Children always time out later than their parents
 | 
						|
(this is called the "heap invariant"), but when a node has two
 | 
						|
children, their mutual order is unspecified - the left child may time
 | 
						|
out before or after the right child.  If a node is numbered N, its
 | 
						|
left child is numbered 2N, and its right child is numbered 2N+1.
 | 
						|
 | 
						|
There is no pointer from a child to its parent; all pointers point
 | 
						|
downward.  Additions and deletions both work by starting at the root
 | 
						|
and traversing the tree towards the leaves, going left or right
 | 
						|
according to the binary digits forming the index of the destination
 | 
						|
node.  As nodes are added or deleted, existing nodes are rearranged to
 | 
						|
maintain the heap invariant.
 |