The class Circular presents a circular buffer as a memory area with a fixed size. If the buffer is full, the oldest elements in the buffer are only overwritten with new elements if the Circular. Overwrite = True property has been set. All elements of a circular object are of type Variant.
A circular has a constant memory requirement because it is an internal array with a fixed number of elements. A circular with e. g. eight elements will never consume more memory than 8 * SizeOf (gb. Variant).
In addition, a circular has a reading and writing pointer. These two properties (. reader and. writer) are separated to distinguish between data producer (the Write () method) and data consumer (Read () method) who can manipulate the same object asynchronously.
If the read pointer reaches the write pointer, there are no further unread elements and the circular is called “empty”. If, on the other hand, the read pointer reaches the read pointer, there is no more space in the circular for new elements and it is declared “full”.
The characteristics of the Circular:
Property | Data type | Description |
---|---|---|
.Size | Integer | Read or set the number of elements (–> method Resize ()) |
.IsEmpty | Boolean (ReadOnly) | True, if there are no elements in the circular, otherwise false |
.IsFull | Boolean (ReadOnly) | True, if all seats in the circular are occupied, otherwise false |
.Overwrite | Boolean | If true, the oldest element will be overwritten when the circular is full, otherwise any further attempts to write to a full circular will fail (without producing an error) |
.Reader | Integer | Index of the read pointer |
.Writer | Integer | Index of the Write pointer |
Table 7.3.6.6.1.1: Properties of the Circular class
Method | Description |
---|---|
Clear () | Remove all elements from buffer |
Read () | Read the oldest element or zero, if the circular is empty |
Peek () | Read () without moving the read pointer further |
Write (vElement) | Write a new element. When the circular is full, the effect of the method depends on the value of the Overwrite property. |
Reset () | Reset read and write pointer to index 0 |
Resize (iSize) | Change the size of the circular |
Table 7.3.6.2.1: Methods of the class Circular
Attention: The method Circular. Resize () leaves the relation of the properties Reader and Writer in an undefined state.
Therefore, it is strongly recommended to let each Resize () be followed by a Reset () to avoid accidental crashes due to false assumptions. Alternatively, both pointers can have the same value when Resize () is called. In this case, both hands also have the same value after resizing the circular.
By using a circular buffer, the maximum memory usage of an application can be reduced to a constant size, since old data is automatically overwritten with new data. This mechanism is used for program logs, as they are of particular interest when a program produces errors. The log information written immediately before the program crash can refer to the part of the program that generated the error. This typical application program log with circular buffers is demonstrated in the offered project.
To keep the solution open, a client-server system is used, which implements a network-compatible system log service that maintains its own log for each connected program (client).
The following description assumes that 2 (client) programs are connected to the server:
Figure 7.3.6.3.1: Two active (client) programs are logged on to the server
The server assigns an ID to the first (client) program and creates a (temporary) log file:
Figure 7.3.6.3.3.2: (client) program 0
You can now work with program 0 by selecting different expressions from the combo box or by entering your own expressions there. You can catch an error or provoke a program crash. In this case the program 0 is terminated.
In the next figure 7.3.6.3.3.3, you can see that a corresponding message has been generated in the client overview. It also indicates that you cannot access the log of the 2nd active (client) program - access is denied!
Figure 7.3.6.3.3.3: Server with entries and warnings
Figure 7.3.6.3.4: Viewing the contents of the Client 0 log
The contents of a log are only displayed if you click on the entry “Terminated Client #…”.
Since each log exists only at runtime of the server, you can save the log for each (client) program and store it freely.
Supplement:
The new component gb. logging from Sebastian Kulesz provides a flexible API for logging and tracing events while the program is running.