Here, data is sharded across the different nodes for load balancing, but it doesn't provide high availability because none of the shards is replicated.

In more complex cases (shown in Figure A-2), there's one primary replica and one or more secondary replica nodes.

*Figure A-2. Replicating data to several nodes, with a single primary and multiple secondary replicas*

Here, one node writes data, which then can be propagated to other read-only nodes. This approach provides some level of high availability since a replica can take over the cluster if the primary goes offline. However, it does not properly balance your workload. All writes must be handled by the primary—which means that the primary becomes a bottleneck. As a result, this method of data replication may be impractical for writeintensive workloads. Spreading out the primary replicas for different portions of data across different nodes in the cluster is one potential way to address this.

In a more extreme form, there are no secondary replicas (like in Figure A-3).

*Figure A-3. Full active-active-style replication*

Here, all data is replicated in an active-active leaderless topology. Every node can accept read and write operations, so all are peers in managing the workload. When this strategy is applied, any loss to part of the cluster will not result in lost data.

This active-active leaderless topology leads to what is called *eventual consistency*: The guarantee that when an update is made in a distributed database, that update will *eventually* be reflected in all nodes that store the data—resulting in the same response every time the data is queried. In an eventually consistent system, the replication strategy defines a number called the "replication factor" (RF), which is the number of nodes on which the portion of data can be found. Writing the data to (and reading the data from) such a system also conforms to different consistency requirements, which is referred to as *consistency level* (CL).

The most restrictive consistency level is often called "all." Writing in this mode means that the data must be written on disk on all replica nodes in the cluster. Reading returns the data after all replicas have responded, and the read operation fails if at least one replica does not respond.

Some less restrictive, but more performant, consistency levels may specify the exact number of nodes that must confirm the operation. Usually, this number is selected in the range of one through three, depending on how many replicas the cluster operator expects to crash.

"Quorum" consistency level provides much stronger consistency for the data. Writing or reading the data at this level means that the majority of nodes from the replica set should confirm the operation. In multi-datacenter setups, quorum consistency often has sub-levels depending on which datacenters the nodes from the replica set belong to.

Note that read and write consistency levels are independent of each other. Even if data was written with one consistency level (e.g. quorum), reading can use a different consistency level depending on the intention. For example, a CL of ONE can be used for data that doesn't need to be consistent, QUORUM CL can be used for a regular (or "unsure") case, and the most restrictive level of ALL can be used to effectively force full data repair.

### Learning More

*Designing Data-Intensive Applications*, by Martin Kleppman (Chapters 5 and 6) *Database Internals: A Deep Dive Into How Distributed Data Systems Work*, by Alex Petrov (Chapters 11, 12, and 13)

*NoSQL Distilled: A Brief Guide to the Emerging World of Polyglot Persistence*, by Pramod J. Sadalage and Martin Fowler (Chapters 4 and 5)

### Consensus Algorithms

Even though quorum consistency level works extremely well and provides data persistence, data consistency, and low latency access, it still does not guarantee the linearizability, isolation, and atomicity required by transactions: queries that heavily rely on ACID properties. One of the simplest and most obvious examples of a transaction can be any CAS (compare-and-set) operation (e.g., increment a counter provided its value is below 42). When transactions come into play, simple eventually consistent models stop working and call for stronger means. One option can be a consensus algorithm on a distributed system.

Consensus algorithms provide strong consistency guarantees about the underlying data and allow a set of replicas to work together as a coherent unit. Provided the nodes conform to the protocol, algorithms tolerate failures of less than half of replicas even in the presence of message loss and reordering. They guarantee the following properties:

Consensus algorithms fall into two large classes—those that need a leader to make a decision and those that don't. The latter are called leaderless. Algorithms from the former class can suffer from periods of silence if the leader fails, so the new leader election process is started and the cluster cannot service requests while it's happening.

### Raft

Raft is an example of a consensus algorithm with a leader. Raft was invented to be simple. It replicates a log of commands from a leader to follower nodes; that log of commands is called a "replicated state machine." And, of course, it has the leaderelection algorithm on board too.

Each replica participating in Raft replication can be in one of three states: follower, candidate, or leader (see Figure A-4). Any attempt to make a decision over the cluster must be described in terms of a state change in the replicated state machine. Since the client may not know who the leader is, it sends its decision requests to whatever node it selects first. Thus, if the decision request is not sent to the leader, followers would re-route it to one, and then the leader would replicate the decision across its followers. In the case of leader failure, the followers turn into candidates. The election process ultimately converts one of those candidates into a leader after it obtains votes from a majority of replicas.

*Figure A-4. Each replica participating in Raft replication can be a follower, leader, or candidate; upon leader failure, followers can turn into candidates, and a candidate is elected leader*

### Paxos

Paxos appeared earlier than Raft. It's an example of a leaderless algorithm, and it was one of the first algorithms that proved the quorum-based way of making distributed decisions.

According to the algorithm, each replica can play one or more of three roles—the proposer, the acceptor, and the learner (see Figure A-5). The decision is made through a two-step process in which the roles are involved, but from a practical perspective, nodes usually combine those roles. The first step, or, as it's usually called—the phase—is in proposing some value. In order to be proposed, the value must be accompanied with the sequence number. After the proposal is confirmed by the majority of acceptors, the proposer may proceed to the confirmation phase. After the confirmation phase is confirmed (again) by the majority of acceptors, the decision is made.

*Figure A-5. Each replica participating in Paxos can be the proposer, accepter, or learner*

Once the decision is made, none of the participants may fall back to the first phase. If the next decision should be made, a new run of the algorithm should be taken. Due to this, Paxos is never used alone. It's always part of a larger algorithm that implements all the necessary "paperwork" needed to instantiate, execute, and wrap up algorithm runs for individual decisions. One example of such a larger algorithm might be "distributed log replication."

Note It's worth mentioning that Paxos was one of the first consensus algorithms that appeared and its goal was to prove how the distributed consensus is made. It's not used in its pure form; it's commonly extended with something else. One such extension was Raft, which (pretty successfully) tried to reduce Paxos' complexity at the cost of a potential imbalance in nodes' roles.

### Comparing Leaderless and "Leader-Based" Classes

Although both leaderless and leader-based algorithm classes solve similar problems, the approach that involves a leader in the decision is considered to be simpler to implement and maintain. It also requires less time to converge upon a decision.

Even though "new leader selection" is just as complex as leaderless algorithms, it happens rarely and is considered to be a necessary evil. On the other hand, the singleleader approach often becomes a limitation to scaling consensus on large clusters then, leader-less algorithms come to the rescue. Another option to overcome the leadership bottleneck is to apply some sharding on the decisions themselves. However, even when this is feasible, the added complexity might not be worth it.

### Learning More

*Designing Data-Intensive Applications*, by Martin Kleppman (Chapter 9) *Database Internals: A Deep Dive Into How Distributed Data Systems Work*, by Alex Petrov (Chapter 14)

*NoSQL Distilled: A Brief Guide to the Emerging World of Polyglot Persistence*, by Pramod J. Sadalage and Martin Fowler (Chapter 4)

### B-Tree vs LSM Tree

As mentioned when talking about read-write ratios back in Chapter 2, LSM trees, illustrated in Figure A-6, are optimized for heavy write workloads and B-trees are optimized for heavy read workloads. LSM-based databases are append-only. They never update values; they just add new ones. This means that when the database is servicing

#### Appendix A A Brief Look at Fundamental Database Design Decisions

reads, it might have to search quite a while to find the appropriate value. However, compaction can help to avoid this read amplification. Choosing an effective compaction strategy for your workload, as well as optimizing when compactions are performed, can significantly impact the read penalty sometimes associated with LSM trees. Also, mechanisms like built-in caching can enable an LSM-based database to achieve fast reads as well as writes.

*Figure A-6. With LSM trees, compaction creates fewer (and larger) files*

On the other hand, B-tree based databases (as in Figure A-7) are optimized for reads. B-trees offer fast reads since their structure—and lack of duplication—makes them much more efficient to search than LSM trees. Traversing the tree is a straightforward path down a tree (as opposed to searching through potentially many files, as is the case with LSM trees).

#### *Figure A-7. B-trees are updated in place (vs LSM trees, which are append only*

The B-tree write path is not optimized for speed, though. Each time there's a write, the database must traverse the tree to find the appropriate location. If a value already exists there, it's updated. If not, a new leaf is added. This is quite disk-intensive, even for small records. In some cases, moving to faster disks can improve performance.

The database creates a snapshot of the tree each time, which enables you to perform rollback (including point-in-time restore). B-trees are also well suited to transactions. When you are going to perform a transaction, you typically want to read the data and then start snapshotting everything. If the conflict resolution doesn't go as planned, you can simply roll it all back. B-trees make this feasible.

### Learning More

*Designing Data-Intensive Applications*, by Martin Kleppman (Chapter 3) *Database Internals: A Deep Dive Into How Distributed Data Systems Work*, by Alex Petrov (Chapters 2, 4, 6, and 7)

*The B-Tree, LSM-Tree, and the Bw-Tree in Between*, by PhotonDB

### Record Storage Approach

One of the fundamental properties of the database is the way to store the data records in persistent storage. A wrong choice at this stage may force end-users into one of two alternatives—exabytes of data migrations vs extremely inefficient disk usage on user queries. To explore the impact, let's look at two fundamentally different approaches row-oriented and column-oriented, each of which is suitable for different use cases.

Data stored on a hard disk is always split into blocks of a fixed size, which is the smallest I/O unit the application can use (see Figure A-8). Databases looking for the data will need to load all the information from the blocks that contain it. Respectively, the fewer blocks the target data is stored in, the faster the database operates. For spinning disks, this requirement always comes next to the data locality one—it's better for the blocks the database reads to get data that's adjacent rather than dispersed across the disk.

There are many algorithms to group data in a logical way, each trying to improve search efficiency (for example, partition and clustering).

When data is organized in the form of a table, the cells can be stored in at least two ways: row-oriented (e.g., wide column) and column-oriented. It's not feasible to shift from one approach to the other because of the amount of I/O required to convert data between versions. At the same time, this decision has a major impact on the database's performance. The choice between row-oriented or column-oriented usually aligns with different access patterns (i.e. whether it's optimized for analytical or transactional workloads).

### Row-Oriented Databases

Let's look at a sample table for a better understanding of how different storage approaches work. Figure A-9 shows a table containing information about a person in each row (the person's name, age, address, etc.).

#### *Figure A-9. Row-based storage*

With row-oriented storage, data is put on disk row-by-row, and each chunk of data from a block consists of the cells from one table row. This design is perfect for so-called OLTP (Online Transaction Processing) applications, since such workloads can often modify the data by adding—or deleting—entities in the table. Writing a new row is optimal because it involves just appending an entire row to the existing blocks or putting it into new blocks. Another reason that row-oriented storage is good for OLTP workloads is because these workloads are typically loaded with requests retrieving every attribute from a single entity. Some examples of row-oriented databases are Cassandra, ScyllaDB, Postgres, and MySQL.

In other words, row-oriented storage is beneficial when all or most of the record needs to be accessed in the same query or transaction. In this case, it's better to have narrow tables. The more columns there are in a given table, the less likely it is that your query will need all of them. In the extreme case when the query requires only a few

columns (or even a single column), the row-store becomes too expensive. It needs to read the whole block, but the whole block will likely contain redundant data that would just be thrown away after being read.

### Column-Oriented Databases

On the other hand, column-oriented databases store data on disk column-by-column. Let's take the same table, but consider each data chunk to be its column, not the row. As shown in Figure A-10, the "names" will be grouped together on the disk, the "ages" will be grouped together on the disk, the "addresses" will be grouped together on the disk, and so on and so forth.

*Figure A-10. Column-based storage*

This approach is a good choice for OLAP (Online Analytical Processing) workloads because those workloads generally aggregate specific data over a very large number of records. OLAP queries are mainly interested in a small subset of columns; for example, calculating the average age of the people from the table. Also, these workloads rarely modify data, and even when they do, the modification is appending new records. Some examples of column-oriented databases are Google BigQuery and Amazon Redshift.

It's also worth mentioning that the compression rate is often much higher in columnstore rather than in row-store. That's because in column-store, all cells from the column have the same data type, and that makes it quite compression-friendly.

Table A-1 breaks down the impact of these different approaches to storing records on the disk.

*Table A-1. Row-Oriented and Column-Oriented Approaches at a Glance*

These are just two representative examples. Data can also be stored using document, graph, and other models. See the following resources for a comprehensive discussion of how the various models store data, and the best and worst use cases for each.

### Learning More

*Designing Data-Intensive Applications*, by Martin Kleppman (Chapter 3) *Database Internals: A Deep Dive Into How Distributed Data Systems Work*, by Alex Petrov (Chapter 1)

*NoSQL Distilled: A Brief Guide to the Emerging World of Polyglot Persistence*, by Pramod J. Sadalage and Martin Fowler (Chapters 8-11)

## **Index**

### **A**

Active-active leaderless topology, 237 Administration backups definition, 224 impacts, 225 optimization, 226 compaction impacts, 227–229 optimization, 229, 231 strategies, 230 operation/performance, 221–224, 232 AdTech use case, 40, 207 Advanced Vector Extensions (AVX), 69 Algorithmic optimization B-trees, 66, 67 cache implementations, 65 database, 74 linear search, steroids, 68, 69 optimizing collections, 66 scanning tree, 69, 70 separation key, 72, 73 tree size, 71 Amazon DynamoDB, 16, 24, 36, 77, 86, 158, 223 Apache Cassandra-compatible database, 20, 21, 25, 36, 85, 111, 114, 115, 129, 145 Asynchronous Direct I/O (AIO/DIO), 53, 54 Atomic, consistent, isolated, and durable (ACID), 1, 34–36, 238

### **B**

B+-tree, 69, 70, 72 B-tree *vs*.


**3. Results**

#### *3.1. The First Test: The Bridge at University of Calabria*

The first test was performed on a double deck bridge at the University of Calabria, Italy. The bridge materializes the South-North central axis, that characterizes the campus layout. All the buildings are lined up on the sides of the bridge. The lower deck is intended for pedestrians. The upper one is used occasionally for vehicular traffic. The main structure is a simply supported truss beam, characterized by three longitudinal tubular elements; the lower deck is hung from the upper ones (Figure 3).

**Figure3.**ThebridgeattheUniversityof Calabria:(**a**)thepedestriandeck;(**b**)the

In Figure 4 the cross sections of the simply supported truss beam at the bearings are shown. The red line represents the path followed by the laser scanner during the acquisitions in line-scan mode.

 upper deck.

**Figure 4.** The bridge's Cross Sections at the bearings: (**a**) transversal; (**b**) longitudinal.

Figure 5 shows the test layout. The test was performed during the parking of a truck elevator, which weight was about 260 kN (Figure 6). The TLS position was chosen below the deck. In this way it was possible to acquire the points of the upper element of the deck structure, realized with a 3D truss. To minimize the oscillations of the rotation axis, the minimum sampling rate was chosen, equal to 70,000 points per second. The distance between the bearings of the bridge is 40.30 m. Measuring the position of the wheel axles, the center of gravity of the truck was obtained, located 11.07 m from the south support.

*Appl. Sci.* **2020**, *10*, 1182

**Figure 5.** The Layout of the first Test.

**Figure 6.** The truck elevator, used as static load.

RiSCAN PRO®, the software provided with the TLS, was used for the first processing of data. The coordinates of the scanned points were obtained, with reference to the TLS centre and expressed in meters. The software described in Section 2.3 was then used; the following figures show the results.

Figure 7a shows, on an arbitrary scale, a view of the entire span and of the lines obtained with the bridge loaded and without loads. The origin of the reference system is the center of TLS. One can observe that the deck has a vertical displacement, with respect to the horizontal direction, of about 134 mm in the middle of the span, with only the dead load. The circles indicate the enlargements shown in Figure 8. Figure 7b shows the deflections due to the truck load, obtained from raw data and the trend-line. In this case, a cubic polynomial, of the type described in Equations (4) and (5), provides an effective fitting line.

**Figure 7.** (**a**) The elevation of the bridge and the lines obtained from TLS. The circles indicate the zooms shown in Figure 8; (**b**) The deflections obtained from the row data (blue) and the trendline (red).

Figure 8 shows two enlargements of raw data and interpolation lines. It is possible to observe that the lines obtained with the loading and unloading bridge coincide on the bearing (Figure 8a), while in the central part of the beam there is a difference in height of about 2 mm (Figure 8b). Also in this case the coordinates are referred to the intrinsic reference system of the instrument.

Using a FEM program developed at the University of Calabria [31], it was obtained an accurate evaluation of vertical displacements. The computed deflection was 1.95 mm, 2.5% less than the value attained by using the proposed methodology. Furthermore, by means of a total station Leica 1201+, a precise measurement was performed. A prism was placed in the middle of the span and was repeatedly monitored from a distance of about 22 m. The automatic target recognition function (ATR) has been activated, which has an accuracy of 1 s; therefore the vertical displacements are obtained with an accuracy of about 0.1 mm. The variation of the bridge deflection thus obtained was 1.9 mm, 5% less than that obtained using the proposed methodology.

**Figure 8.** Points and trendlines obtained with loading and unloading bridge: (**a**) on the bearing; (**b**) on the midspan.

#### *3.2. The Second Test: The Cannavino Bridge at Celico*

The Cannavino bridge (Figure 9a) has been realized of prestressed concrete. The structural scheme makes use of opposing cantilevers, whose ends recently have been subjected to large deflections (Figure 9 ); for this reason the technicians of ANAS, the Italian National Autonomous Roads Corporation, carry out periodic monitoring with the total station [32].

In 1972, during its construction, the bridge suffered the collapse of two cantilevers. To understand the reasons, some in-depth studies were carried out [33].

In Figure 10, one can see the elevation of the bridge (Figure 10a), a photo of the collapsed cantilevers (Figure 10b) and some details at the breaking points (Figure 10c). Figure 11 shows the south side balanced cantilever with the post-tensioned segments (Figure 11a) and their cross section (Figure 11b); the red dot indicates the line scanned during the test. The height of the segments ranges from 2.00 to 7.80 m. Figures 10 and 11 are taken from [33].

The above described VZ1000 TLS was used, set up as a line scanner. To record the sampling time of each acquired point, the timestamp function has been activated. GPS time was acquired using the receiver of which TLS is provided.

Figure 12a shows the layout of the test. The TLS station point was chosen under a cantilever, close to a pile. A path parallel to the longitudinal axis of the bridge, at the bottom of the sidewalk, was acquired for 60 s, in order to avoid an excessive size of the file to be processed (Figure 12b). The scans were carried out with the bridge open to traffic. It was chosen a 110,000 points per second scanning speed.

**Figure 9.** Views of Cannavino bridge: (**a**) Panorama; (**b**) Zoom of the end of the central cantilevers; (**c**) deck surface.

**Figure 10.** Drawing and photo after the collapse: (**a**) Quoted Elevation; (**b**) Collapsed Cantilevers; (**c**) Details of the broken zones.

**Figure 11.** Draft of the south side balanced cantilever: (**a**) Post-tensioned segments; (**b**) Cross section. The red dot indicates the line scanned during the test.

**Figure 12.** The Test on the Cannavino Bridge: (**a**) The Layout; (**b**) the position of TLS (red circle) and the scanned line (red line).

RiSCAN PRO® software was used to process the acquired data. Point coordinates and timestamps have been recorded in a text file. Subsequently the file was processed with the previously described Matlab® code and the single lines were extracted and corrected, by imposing the structural constraints. The splines were then calculated for each scanned line.

The video of the loads was acquired with the above described digital camera, equipped with a GP-1 unit, an accessory capable of providing Coordinated Universal Time (UTC) (Figure 13).

**Figure 13.** A frame of the video used to obtain position and estimate of the mobile loads.

Figure 14 shows a stretch of the splines obtained for six load combinations; the reference system of the TLS shown in Figure 12 was used for the coordinates in meters.

The green line is obtained for the maximum load visible in the frame of Figure 13. The cyan line refers to the unloading bridge, while the other lines refer to intermediate load conditions. As regards the position of the loads, they were obtained approximately taking into account the posts of the guardrails. Loads were estimated based on the type of vehicles present in each selected frame. A FEM analysis was performed using the aforementioned code [31], the structural data provided by [33] and the six load combinations.

The following remarks can be made: (a) towards the free end of the cantilever, the splines diverge (different colors correspond to different times) when the mobile loads increase; (b) the maximum distance is about 6 mm; (c) The FEM analysis provides 16% lower results, with a maximum displacement of 5 mm. This difference is understandable given the uncertainty in the evaluation of loads, the unavailability of the *as built* and the age of the structure. A comparison was made with the outcomes of the load tests carried out by the technicians of ANAS some years earlier with higher loads. The results obtained, taking into account the ratio between the loads in the two tests, show a difference of about 10%.

**Figure 14.** A stretch of the splines obtained for six load combinations. In the boxes, the enlargement of the splines in correspondence of the two points indicated by dots, near to the free end of the cantilever (left box) and near the fixed end (right box). The scale is arbitrary.

#### *3.3. The Third Test: The Santiago Calatrava's San Francesco Bridge at Cosenza*

Built to allow an access large and of artistic value to the city of Cosenza, the large structure of San Francesco Bridge (Figure 15) crosses the Crati river.

**Figure 15.** The Santiago Calatrava's San Francesco Bridge at Cosenza.

It is a cable-stayed bridge with a cantilever spar. The characterizing structural element is the single inclined pylon, which with its height of 95 m marks the surrounding landscape. The span, 200 m long, is counterbalanced by twenty twin cable lengths. Two large rods contrast the actions of the cables. A special feature of the bridge is the upper part of the pylon, where the cables are anchored so as to give the impression of a sail. The metal structure of the deck rests on artistically sculpted concrete abutments.

To represent work and the surrounding area of the city, a survey was conducted using a TLS [34]. The surveyed area extends to the historic center and covers the riverbed. (Figure 16).

The experiment was performed during the official load test carried out on 17 January 2018, a windy day; a series of trucks of known weight were placed on the deck (Figure 17b).

**Figure 16.** The 3D model of San Francesco Bridge.

Several instruments were used during the test. In addition to a digital level and a total station; some strain sensors were placed both on the pylon and in various positions on the deck. Furthermore, two inclination sensors provided inclination at different pylon heights in real time, thanks to a wireless connection [35].

A station point for VZ1000 TLS was chosen, aligned with the central axis of the bridge. The chosen location is in a stable area and is about 90 m from the anchorage of the rods. This position allows a vertical section of the pylon to be described with the laser beam of the instrument. In particular, the outer part of its cylindrical surface with elliptical section is detected. The rods hidden only a short stretch of the pylon. In this way, we can get the elastic line of the pylon for each line scan, during the runs of the trucks used as mobile loads.

Figure 17a shows the layout of the test. On the left side of the panel, you can see the TLS station. The laser trace is highlighted by a red line. Figure 18a shows a vertical section extracted from a line scan. Figure 18b shows the point cloud obtained for the pylon head. Overlaid you can see the upper part of the laser track, circled in blue in Figure 18a.

The official load test involved the sequential positioning of ten trucks side by side on two adjacent lanes (Figure 17b). The TLS acquisitions were made in two configurations: (a) with unloaded bridge, (b) during the load test.

The unloaded bridge acquisition was carried out from 11.33 am to 11.35 am local time (UTC + 1). The acquisition with mobile loads was carried out from 10:41 UTC (GPS time 1,200,220,888) to 10.51 UTC (GPS time 1,200,221,500). The sampling rate was 120 lines per second. This acquisition began before the first truck left and continued until before the departure of the fourth truck. The scans were then stopped due to the heavy rain, so the runs of the last vehicles were not acquired. The trucks were equipped with Leica GS15 GNSS receivers, mounted on a solid magnetic base that allows them to be fixed to the cab roof.

The recording rate was set to 5 Hz. The data collected by the permanent GNSS station of the University of Calabria were used to perform post processing.

**Figure 17.** The Test on the San Francesco Bridge: (**a**) The Layout with the TLS position (red circle) and the scanned line (red line); (**b**) Trucks used as loads; (**c**) The TLS, positioned after the alignment operation, preliminary to the test.

**Figure 18.** A single line scanned: (**a**) The section of the pylon; (**b**) The upper part of the scanned line superimposed to 3D model of the pylon.

Table 4 shows the GPS time for the actions performed during the load test.

**Table 4.** GPS time for the actions performed during the load test.

A comparison between the results obtained by the total station and the acquisitions of the TLS in line scanner mode showed a substantial agreement between the two techniques. Also the comparison with the acquisitions of inclination sensors confirmed the reliability of the methodology.

Figure 19 shows some test results. The magnifications correspond to the areas circled in blue in the thumbnails. The point cloud of the profile acquired with the unloaded bridge is in blue.

**Figure 19.** Enlargements of the point clouds obtained before the load test (blue points) and during the test (red points): (**a**) Upper zone of the pylon (z = 81 m); (**b**) Constraint device in which the rods can slide (z = 69 m); (**c**) lower part of the pylon (z = 39 m).

First of all we can see that the precision declared for the instrument and reported in Table 1 is confirmed. The cloud of blue points, in fact, is about 8 mm thick. Therefore the precision of the acquisitions is about ten times lower than the displacements we have to measure.

In the panel 19a we can see the displacements of the pylon head. The height, referred to the TLS centre, is about 81 m. The dense red point cloud on the left was obtained during the stop of the first truck. The red dense point clouds on the right were obtained during the short stop of the second truck and during the stop of the third one. At the end of the TLS acquisitions, three trucks were positioned on the bridge. Also this point cloud is 8 mm thick. Scattered points were acquired while the second and third trucks were running. Point clouds acquired during truck slowdown become denser. We observe an overall displacement of 41 mm. The first two mobile loads caused roughly half of the total displacement.

In the panel 19b one can see the points acquired in correspondence with the constraint device in which the rods can slide, 69 m above the TLS. In this case, we can see that the horizontal displacements begin with the run of the second truck. The analysis of this behavior is outside the scope of our study. The maximum displacements are slightly lower with respect to the upper part. Since these zones are close together, this behavior seems reasonable.

The points acquired in the lowest part of the pylon are shown in panel 19c. The height of this zone is 39 m respect to the TLS center. The displacements reach a maximum value of 26 mm.

Using the Matlab code described above, the individual lines from the overall file supplied by the TLS were extracted and a timestamp was associated to each line. The interpolating lines were then determined.

Figure 20 shows a stretch of four splines, obtained for different instants, in the upper zone of the pylon. The coordinates are referred to the center of the instrument, so x is the horizontal distance and z is the difference in height with respect to the center of the TLS. The magenta line (GPS TIME<PHONE_NUMBER>) is related to the unloading bridge. The other lines relate to the parking of the first truck (blue line), the parking of the second truck alongside the first one (green line) and the parking of the first three trucks (yellow line). From the data collected it is possible to extract the movements of the pylon, at each height, as a function of time.

**Figure 20.** Enlargements of the point clouds obtained at a height of 80 m above the TLS. Superimposed are the interpolating lines of the 2D point cloud provided by the TLS in line scanner mode.

Figure 21 shows the horizontal movements of the pylon at three different heights. In panel (a) we observe the movements of a point at a height of 80 m with respect to the instrument, as a function of the GPS time. The displacements due to the moving loads are easily recognizable by analyzing the 10 samples moving average, drawn in red: during the run of the first truck the point moves up to 15 mm towards the midspan. The point does not move during the stop and undergoes a further displacement during the run of the second truck. After a brief pause, the third movement begins, ending with the halt of the third truck. The total displacement is about 41 mm. It is worth remarking that the graph reflects the times of the events reported in Table 4.

The comments made above can be repeated for the point at a height of 50 m, which movements are drawn in the panel (b). Displacements are reduced, as expected.

As regards the point at 20 m height, the various phases are less evident. A final displacement of about 16 mm can be observed.

Measurements were performed with a total station after positioning each of the three trucks. The station pointed targets placed on the pylon at various heights and its measurements were used for the official load test. The results fully agree with those obtained with our method. Also the inclination variations sampled by two sensors, positioned inside the pylon and connected wirelessly, are consistent with the splines extracted using the method described.

Thanks to the acquisitions made by the GNSS receivers positioned on the trucks, the displacements of the points of the pylon can finally be correlated to the position of the mobile loads. Since the TLS position was obtained thanks to its GPS receiver, the coordinates of the each mobile vehicle, for each GPS time, can be converted into local coordinates in the TLS reference frame.

The correlation is shown in Figure 22 in which the horizontal positions of a point of the upper part of pylon are represented as a function of GPS time. The point is 85 m above the TLS centre. The trend-line evidences runs and stops of the trucks. In the thumbnails, the GPS time and the instantaneous local coordinate x of the moving loads, represented by dots, are shown. The red, blue and green dots represent, respectively, the first, second and third trucks.

the horizontal distances from the TLS.

**Figure 21.** Horizontal displacements, as a function of the GPS time, for three points of the pylon during the test: (**a**) at 80 m above the TLS; (**b**) at 50 m above the TLS; (**c**) at 20 m above the TLS. Ordinates are

**Figure 22.** Horizontal displacements for a point of the pylon 85 m above the TLS during the test, correlated to the position of the mobile loads. The trend-line is a 10 sample moving average. In the thumbnails, GPS time and position of mobile loads (local coordinates) are reported.