slab allocator (I, II, III - this article) is the core module of the cache system, which largely determines how efficient the bottleneck resource, memory, can be utilized. The other 3 parts, namely, LRU algorithm (not complete) for entry expiration; and an event driven model (not complete) based on libevent; and the consistent harsh (not complete) for data distribution, are built around it. Last time we saw the memory allocationg process, which further fomulates slabs and the derivative “free lists” (a.k.a., slots). This time we will examine how to take advantage of the established data structures to “slab allocate / release” memory chunks which will be used to store items.
slab allocator (I, II - this article , III) is the core module of the cache system, which largely determines how efficient the bottleneck resource, memory, can be utilized. The other 3 parts, namely, LRU algorithm (not complete) for entry expiration; and an event driven model (not complete) based on libevent; and the consistent harsh (not complete) for data distribution, are built around it. This time we continue examining how slabs memory is allocated. Firstly we look at the two arguments for slabs_init, which were passed over in the previous article. The first one is settings.maxbytes. It limits the overall memory that can be used by the memcached instance. In slabs_init, the value of settings.maxbytes is assigned to the global variable mem_limit which will be used very soon.
slab allocator (I - this article , II , III) is the core module of the cache system, which largely determines how efficient the bottleneck resource, memory, can be utilized. The other 3 parts, namely, LRU algorithm (not complete) for entry expiration; and an event driven model (not complete) based on libevent; and the consistent harsh (not complete) for data distribution, are built around it. Variants of slab allocator is implemented in other systems, such as nginx and Linux kernel, to fight an common problem called memory fragmentation. And this article will, of course, focuses on memcached’s implementation of the algorithm. memcached version: 1.4.28 Firstly, let’s answer some questions.
Latency, instead of throughput, is found as the system bottleneck more often than not. However, the TCP socket enables a so-called nagle algorithm by default, which delays an egress packet in order to coalesces it with one that could be sent in the future, into a single TCP segment. This effectively reduces the number of TCP segments and the bandwidth overhead used by the TCP headers, whilst potentially imposes latency for every network request (response) being sent. Lock, and his temperamental brother, Block, are the two notorious villains in the world of programming. In the beginning, they always show up to assist. But sooner or later, they will kick your back-end like really hard. When I consider about nagle algorithem, it seems to me another scenario involving block operations which are meant to be helpful. So I decide to put hands on a keyboard to test if I am wrong. Software setupClient OS: Debian 4.9.88Server OS (LAN & WAN): Unbutu 16.04gcc: 6.3.0 Hardware (or VM) setupServer (LAN): Intel® Core™2 Duo CPU E8400 @ 3.00GHz × 2, 4GBServer (WAN): t2.micro, 1GB
There are two end purposes for sending heartbeats through a persistent connection. For a back-end application, heartbeats are generally used to detect an absent client, so as to drop a connection and release the associated resources; for a client, on the contrary, it is to prevent connection resources stored within intermediate nodes being released (such as a NAT router), SO as to KEEP the connection ALIVE. This article will examine how to configure the four socket options, SO_KEEPALIVE, TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT with setsockopt() to send heartbeats; and discuss the practice of keep-alive heartbeats in general. Experiment setting:OS: Unbutu 16.04gcc: 5.4.0
Last time we went through the process from setState() to the updating of a single DOM. We also analyzed the diffing algorithm, which is far from complete as the algorithm is designed for tasks that are much more complex than updating a single DOM node. This time we are going to use two examples to examine the diffing algorithm more in depth. More specific, we look at how the algorithm deals with a mutating DOM tree. N.b., the examples used in this article are derived from the official document which also provides a high level description of the diffing algorithm. You might want to read it first if the topic does not seem very familiar.
UI updating, in its essential, is data change. React offers a straightforward and intuitive way to program front-end Apps as most moving parts are converged in the form of states, and most UI tasks can be done with a single …, I mean, a single method, setState(). In this article, we are going unfold the setState() implementation, and peek inside the diffing algorithm by mutating an individual DOM element.
Last time we discussed the core Transaction class and ReactDefaultBatchingStrategyTransaction. The instantiation is not the sole Transaction involved in UI updating but merely the one that leads. In this post, we are going to examine the other Transactions which, together with ReactDefaultBatchingStrategyTransaction, outline the UI updating processing logic.
To some extent, the sophisticated and efficient UI updating is what makes React React. But before we dive into the well-known mechanisms (virtual DOM and diffing algorithm) that empower the UI updating, we need to understand Transaction which transfers the control from the high-level API setState() to those underlying processing logic.
Last time we completed the upper half of the class component rendering logic which is similar to albeit different from simple component rendering in the following respects: 1) it instantiates one additional ReactCompositeComponent to represent the class component (App); and 2) it calls App.render() that triggers cascading React.createElement()s to establish a ReactElement tree. This time we are going to explore more branches in lower half by examining how the ReactElements in the tree is transformed to their respective ReactDOMComponents, and eventually, to real DOM objects.