Open In App

What are Retroactive Data Structures?

Retroactive Data structures are a type of data structure that supports efficient modifications performed on a data structure, in this new data structuring paradigm, the operations performed on the data structure are not only in present but also in the past which means the operations can be altered and modified even in the pastime interval. 

These data structures give us great comfort in terms of flexibility while working on complex applications that need regular updates as adjusting the structure can be adjusted according to the working model of the program, in the real world there are various cases where there is a need to modify a past operation from a sequence of operations.



Need For Retroactive Data Structures:

Comparison With Persistent Data Structures:

Even though the notion of persistent data structures and retroactive data structures may look similar as they take the dimension of time into account, still the way they handle the element of time makes them stand different from each other. 



Types of Retroactivity:

1. Partially Retroactive: Any data structure can be made partially retroactive by general transformations. For example, the following inserts a partially retroactive list with an initial state [1,2,3,4,5]. We can then add or remove the operation in present.

Below is the Python pseudo-code for the above concept:

# Python program to implement  
# the above approach  
x = PartiallyRetroactive([1, 2, 3, 4, 5])  
def appendOne(lst):
 return lst + [1]

# Three appendOnes by applying  
# insertAgo()
x.insertAgo(appendOne, tminus = 0)
x.insertAgo(appendOne, tminus = 0)
x.insertAgo(appendOne, tminus = 0)
x.query()

# Three appendOnes by applying insertAgo()
[1, 2, 3, 4, 5, 1, 1, 1]   

Output:

>>x.query() :
[1, 2, 3, 4, 5, 1, 1, 1]

We can also add or remove operations from the past:

def MethodForAppendNum(lst):
       return lst + [6]
       
 ## For Inserting into  *two* operations ago
 a.insertAgo(appendSix, tminus=2)   
 a.query()
 [1, 2, 3, 4, 5, 1, 6, 1, 1]
 
 ## For Deleting the first appendOne
 a.deleteAgo(tminus=3)   
 a.query()
 [1, 2, 3, 4, 5, 6, 1, 1]

Output:

>>a.query() :
[1, 2, 3, 4, 5, 1, 6, 1, 1]

2. General Full Retroactivity: Full Retroactive data structures are similar to their siblings Partial Retroactive Data Structures, in that they permit retroactive insertion and deletion of operations. However, fully-retroactive data structures also permit querying into the past instead of just the present.

Below is the Python pseudo-code for the above approach:

b = MethodForFullyRetroactive([1,2,3])
b.insertAgo(appendOne, tminus = 0)
 
## This one should come last
b.insertAgo(appendSix, tminus = 0) 

## This one should come first
b.insertAgo(appendTen, tminus =2)
 
b.query()

## The current state of the data structure
[1, 2, 3, 10, 1, 6]   
b.query(1)
[1, 2, 3, 10, 1]
b.query(2)
[1, 2, 3, 10]
b.query(3)

## The state of the data structure way back
## in the past
[1, 2, 3]   

Output:

>>b.query(1) :
[1, 2, 3, 10, 1, 6]
>>b.query(2) :
[1, 2, 3, 10]
>>b.query(3) :
[1, 2, 3]

Applications: Some applications of retroactive data structures are listed below

Advantages Of Retroactive Data Structures:

Disadvantages of Retroactive Data Structures:

Automatic Retroactivity: There comes a natural doubt in our minds about the possibility of converting data structures automatically into retroactive form by using a general technique for example like converting a pointer-machine model into an effective partially retroactive data structure? Such a general technique would nicely complement existing persistence data structures but in the case of retroactive data structures, the retroactivity is fundamentally different from persistence, and generally known techniques do not apply.

One simple approach to this general problem is the rollback method, where auxiliary information is stored as all changes for the data structures are made by each operation in such a way that each change could be reversed dynamically, For example, to enable a rollback for the memory-write operation we store the value that was previously at the address, therefore their performances act differently depending upon the retroactive change.

Retroactive Running Times: Take a number of operations performed by the data structure for determining the running time of retroactive data structures. For example, let m be a number of operations performed on the structure and let r be numbers of operations performed before the retroactive operations, and n be the maximum number of elements present in the structure at any time.


Article Tags :