# Inclusive transformation consistency control algorithm in distributed system

- Santosh Kumawat
^{1}Email author and - Ajay Khunteta
^{2}

**2**:9

**DOI: **10.1186/s40660-016-0015-3

© The Author(s) 2016

**Received: **4 January 2016

**Accepted: **13 May 2016

**Published: **10 June 2016

## Abstract

Operational transformation (OT) is the most effective method for consistency and concurrency control in multi-user groupware applications. This study proposes a new string-based OT algorithm to address the challenge of swapping and transposing two deletions. It has removed the faults of previous existing algorithm swapDD (ABTS: a transformation-based consistency control algorithm for wide-area collaborative applications, collaborative computing: networking, applications and worksharing 1–10, 2009). Existing algorithm swapDD fails totally in transposing two deletions if the first operation region is included in the second operation region or the second operation string is covered by the first operation string. In addition, swapDD has not considered partial overlapping between two deletions in swapping and fails at boundary conditions. New proposed algorithm works well in all possible cases of transposing two deletions. It handles overlapping and splitting of operations.

### Keywords

Inclusive transformation algorithm Distributed systems Concurrency control Consistency control Groupware system## Background

Real-time groupware systems, such as multi-player game, and real-time computer conferencing in the area of computer-supported cooperative work have multiple users where the actions of all users must be propagated to all other users.

Groupware systems are multi-user systems that provide an interface to a multi-user shared environment, which require sharing of data, fine-granularity, concurrency control, and fast response times. Concurrency control protocols are needed to repair inconsistencies in the multi-user transactions and areas of computing systems, such as database systems, distributed systems, and groupware systems. Therefore, there are specific requirements (Sun et al. 1998): high local responsiveness, unconstrained interaction, real-time communication, and consistency.

### Theorem 1

*In a consistent shared environment which has replicated data after execution of all operations, all have the same data.*

Traditional concurrency control methods, such as locking, transactions, single active participant, dependency detection, and reversible execution, may cause the loss of interaction results and were not suitable for distributed interactive applications that demand fast local response satisfying user intentions, intention consistency, and convergence.

Over the past decade, operational transformation (OT) has become an established acceptable method for consistency maintenance in group editors. Compared with alternative concurrency control methods, OT has been found uniquely promising in better way achieving convergence, causality, and intention preservation without killing responsiveness and concurrent work (Shao et al. 2009). OT allows users to edit any part of the shared data at any time. Local operations are always executed as soon as they are generated by the user. Remote operations are transformed before execution to repair inconsistencies. Most of the existing OT algorithms only support primitive character operations like insert and delete. Only a few OT algorithms support string primitive operations like insert and delete.

## Review of OT algorithms

Operational transformation algorithms have been studied over the past 25 years. OT algorithms correctness cannot be formally proved due to informal condition called “intention preservation.” OT algorithms only consider two primitive character-based operations like insert and delete.

We have reviewed a number of major OT algorithms for consistency maintenance in real-time group editors, including the distributed operation transformation (dOPT) algorithm (Ellis and Gibbs 1989), the generic operational transformation (GOT) algorithm (Sun and 1998), GOT optimized (GOTO) algorithm (Sun et al. 1998), state difference transformation (SDT) algorithm (Li and Li 2006), SCOT2 (Suleiman et al. 1998), SCOT 3/4 algorithm (Vidot et al. 2000), adopted (adOPTed) algorithm (Ressel et al. 1996), admissibility-based transformation (ABT) algorithm (Li and Li 2010), ABT-undo (ABTU) algorithm (Shao et al. 2010), admissibility-based sequence transformation (ABST) (Sun and 1998), and admissibility-based transformation with strings (ABTS) algorithm (Shao et al. 2009).

## System model and notations

Standard notations

Notations | Description |
---|---|

o.id | Id of site that generate operation o |

o.type | Type of operation o, i.e., either insert or delete |

o.pos | Position of operation o |

o.str | String insert/delete by o |

o1 → o2 | o1 occurs before o2 |

o1||o2 | o1 and o2 are concurrent |

o1Uo2 | o1 and o2 are contextually equivalent |

o1 → o2 | o1 and o2 are contextually serialized |

[o1,o2] | An ordered list of two operations o1 and o2 |

<o1,o2> | Two operations in sequence |

|L| | Number of objects in list L |

L1.L2 | Concatenation of two lists L1 and L2 |

s [i:len] | Substring of string s start from position i of length len |

sq | A sequence is a special list in which all elements are operations that are contextually serialized |

sq = <o1, o2,…, on> | sq = <o1, o2,…, on > , where o1 - > o2- > …- > on |

< > | An empty sequence |

L = [a, b, c], it has L = [a]· [b, c] = [a, b]· c | A sequence is a special list in which all elements are operations that are contextually serialized |

|sq| = n | The number of elements in sequence sq = n |

sq = < o1 > . < o2,… on > | All elements of sequence are contextually serialized |

R1 = [o1.start, o1.end] | Operation region of operation o1 s R1 which start from o1.start & end at o1.end |

o.Substring (i,len) | Substring of o start from i of length len |

o.Substring (i) | Substring of o start from i position in o |

###
**Definition 1**

o1 and o2 are contextually equivalent o1||o2, o1Uo2 and if input is o1 and output then output should be o2 → o1′.

###
**Definition 2**

If we have exec(o_{i}), then all exec(o_{i−1}) must be completed then only o_{i} satisfy causality.

###
**Definition 3**

If o1Uo2, then IT(o1,o2) satisfy admissibility. It does not have inconsistent order at shared environment.

## Algorithms

The basic swap functions for swapping two primitive operations insert and delete exist in (Shao et al. 2009). Given two operations o1 and o2, where o1 → o2, function swap(o1, o2) transposes them into o1′ and o2′, such that o2′ → o1′. Depending on their types, insert (I) and delete (D), we call different swapping functions. The basic swap function for swapping primitive operations two deletions is swapDD (Shao et al. 2009). Here, swapDD and MGswapDD take two string operations o1 and o2 as parameters. Here, o1.type = o2.type = delete. Before swapping, we have o1 → o2 and after swapping, we get o1′ and o2′, so that we can have o2′ → o1′.

### Algorithm swapDD

Algorithm swapDD (o1, o2) transposes two deletions o1 and o2. There are three cases considered by (Shao et al. 2009). First, if o2.pos ≥o1.pos, it means that o2 is to delete a substring on the right side of the substring o1.str deleted by o1. Hence, if we execute o2 before o1 instead, then o2.pos should consider o1.str, because it has not been deleted yet. Therefore, o2 position shifted right by length of o1.str.

Second, if o2.pos + |o2.str| ≤o1.pos, it means that o2.str is completely on the left side of o1.pos. Hence, if o2 get executed before o1 instead, o1.pos should be shifted to the left, because o2.str has already been deleted.

Third, as in lines 6–12, o1.str is completely covered by o2.str. Then, if o2 get executed before o1 instead, o2.str is divided into three parts, among which the middle overlapping part is to be deleted by o1. The remaining left and right parts, as divided by position o1.pos, are deleted by two suboperations o2L and o2R, respectively. At last, finally, o1.pos should be set to o2.pos due to the deletion of o2L.str.

_{1}, o

_{2}): (o

_{2}′, o

_{1}′)

- 1.
o

_{1}′ ← o_{1}; o_{2}′ ← o_{2}; - 2.
if o

_{2}.pos > = o_{1}.pos then - 3.
o

_{2}′.pos ← o_{2}.pos + | o_{1}.str| - 4.
else if o

_{2}.pos + | o_{2}.str| ≤ o_{1}.pos then - 5.
o

_{1}′.pos ← o_{1}′.pos−| o_{2}.str| - 6.
else

- 7.
o

_{2L}← o_{2R}← o_{2} - 8.
o

_{2L}.str ← o_{2}.str[0: o_{1}.pos−o_{2}.pos] - 9.
o

_{2R}.pos ← o_{1}.pos + | o_{1}.str| - 10.
o

_{2R}.str ← o_{2}.str[o_{1}.pos−o_{2}.pos:] - 11.
o

_{2}′.sol ← [o_{2L}, o_{2R}] - 12.
o

_{1}′.pos ← o_{2}.pos - 13.
endif

- 14.
return(o

_{2}′, o_{1}′)

### Failure of algorithm swapDD

Algorithm swapDD fails in most of cases in swapping two deletions. Failure of algorithm swapDD in various conditions is highlighted in the following cases:

###
**Case 1:**
*If o2.pos* ≥*o1.pos*

In this case, swapDD fails at boundary condition means that if o_{2}.pos = o_{1}.pos, it fails totally (lines 2–3 of algorithm swapDD).

###
**Case 2:**
*If there exist partial overlapping between deletion operations o1 and o2 regions*

Here, partial overlapping between o_{1} and o_{2} means region of o_{1} and o_{2} overlaps to each other. In addition, we can say that o_{1}.str partially overlaps by o_{2}.str. There can be either overlapping along the left border of o_{1} with o_{2} or overlapping along the right border of o_{1} with o_{2}. In this case, lines 2–3 of algorithm swapDD execute for the right overlapping of o_{1}.str with o_{2}.str, and lines 6–13 of algorithm swapDD execute for the left overlapping of o_{1}.str with o_{2}.str and it totally fails. As per the details of this algorithm given in (Shao et al. 2009), it has not discussed partial overlapping between two deletion operations o_{1} and o_{2} but in algorithm not put required conditions to avoid partial overlapping of o_{1} and o_{2}. Therefore, either it has not considered the partial overlapping of o_{1} and o_{2} in swapDD just by assumption or it totally fails in this case.

###
**Case 3:**
*If o*
_{
1.
}
*str completely overlaps by o*
_{
2
}
*.str*

In this case, swapDD lines 6–13 get executed, and it gives total wrong output in all cases. Ideally as per algorithm swapDD theory specified in (Shao et al. 2009), it should divide o_{2}.str into three parts, among which the middle overlapping part is to be deleted by o1. However, it fails in splitting o_{2}.str in the remaining left and right parts which are to be deleted by two suboperations o_{2L} and o_{2R}, respectively.

###
**Case 4:**
*If o2.str completely overlaps by o1.str*

This case is not discussed in theory of swapDD given in (Shao et al. 2009), but if we have this case, lines 2–3 of swapDD get executed and give total faulty result.

Therefore, it is concluded that swapDD fails totally in swapping two deletions if there exist partial or total overlapping of o_{1}.str by o_{2}.str. In addition, in a few cases, it fails totally at boundary conditions.

### Algorithm MGswapDD

The new proposed algorithm MGswapDD has removed all faults of the existing algorithm swapDD and is working well in all possible cases of swapping two deletions. It works well at all boundary conditions. It has also considered the partial overlapping of operations o1.str and o2.str. Also if o1.str completely overlaps by o2.str or o2.str completely overlaps by o1.str, then also it works well totally. Thus, it considers well overlapping and splitting of operations. The MGswapDD is practically implemented in lab and works well on partial or total overlapping of operations. In addition, it works well on not overlapping operations and boundary conditions.

- 1.
*From Line 3*if(o2.pos > (o1.pos + |o1.str|)), means if o2 lies completely on the right side of o1 then, if we execute o2 before o1 instead, then o2.pos should consider o1.str, because it has not been deleted yet. Therefore, o2 position shifted right by length of o1.str. - 2.
*From Line 5*if ((o2.pos + |o2.str|) < o1.pos), means o2.str is completely on the left side of o1.pos. Hence, if o2 get executed before o1 instead, o1.pos should be shifted to the left, because o2.str has already been deleted. Therefore, o1 shift left equal to length of o2.str. - 3.
*From Line 7*if (o2.pos > o1.pos&&o2.pos ≤ (o1.pos + |o1.str|)&&(o2.pos + |o2.str|) > (o1.pos + |o1.str|)), means o1.str overlaps partially with o2.str along its right boundary, then o1.str and o1 position will remain unchanged and o2′ position will shift right by the length of overlapping region of o1.str and o2.str. In addition, o2′.str will be set to not overlapping part of o2 string. Here, the overlapped region gets deleted by o1′, and o2′ deletes the remaining not overlapping region of o2.str. - 4.
*From Line10*if(o2.pos < o1.pos&&(o2.pos + |o2.str|) ≥o1.pos && o1.pos + |o1.str| > (o2.pos + |o2.str|), means o1.str overlaps partially with o2.str along its left boundary then the overlapped region gets deleted by o1, and o2 deletes the remaining not overlapping region. Here, o2′ string will reduced to not overlapping part of o2 string by deducting the overlapped region from the existing o2 string. In addition, o1′ position is shifted right by length of o2′ string, since o2′ is already deleted since after swapping, we have o_{2}′ → o_{1}′. - 5.
*From lines 13*–25 get executed if none of the above conditions are true. Line 14 check if o2.str completely covered by string o1.str. If o1 and o2 delete the same substring of given string sequence ‘s’ which lie at the same position, then also condition at line 14 is true. In this case, o2 initialized to null, and o1 deletes the o1.str from o1 position. Lines 16–25 are executed if o1.str is completely covered by o2.str. Then, if o2 get executed before o1 instead, o2.str is divided into three parts, among which the middle overlapping part is to be deleted by o1. The remaining left and right parts are deleted by two suboperations o2L and o2R of o2′, respectively. At last, o1′.pos should be set to o2.pos due to the deletion of o2L.str. Therefore, if o1 is totally overlapped by o2 string, then the overlapping region gets deleted by o1, and o2 deletes its remaining regions left and right called o2Lpart and o2Rpart, respectively, which are separated by o1 region.

## Correctness proof

In multi-user environment, practically, we have implemented ABTS and MGswapDD in lab using Qualnet and ASP.Net software.

### Algorithm swapDD

###
**Case 1:**
*If o*
_{
2
}
*pos* = *o*
_{
1
}
*.pos*

In this case, swapDD fails at boundary condition means that if o_{2}.pos = o_{1}.pos, it fails totally (lines 2–3 of algorithm swapDD).

_{1}= delete(3, “GodHelp”) and o

_{2}= delete(3, “God”). Therefore, condition at line 2

*if(o*

_{2}

*.pos*≥

*o*

_{1}

*.pos)*is true, since o

_{2}.pos = o

_{1}.pos, so by line 3, we get o

_{2}′.pos = o

_{2}.pos + |o

_{1}.str| so we get o

_{2}′.pos = 3+7 = 10. Here, in given string definition s, we apply o

_{2}′ = delete(10, “God”); the operation fails since at starting position ‘10’ substring “God” not found (see Fig. 2). Therefore, swapDD fails totally.

###
**Case 2:**
*If there exist partial overlapping between deletion operations o1 and o2 regions*

Here, partial overlapping between o1 and o2 means region of o1 and o2 overlaps to each other.

For example, let s = “TheBirdsAreFlyingInTheSky”

Let o_{1}.str = “BirdsAreFlying” and o_{1}.pos = 3,|o_{1}.str| = 14

o_{2}.str = “FlyingInTheSky” and o_{2}.pos = 11.

_{1}overlaps with o

_{2}along its right boundary. And if we execute swapDD; condition at line 2 is correct that is (o

_{2}.pos ≥o

_{1}.pos), since 11 > 3, so enter in if block and execute the code at line 3 that are o

_{2}′.pos = o

_{2}.pos + |o

_{1}.str|, so here, we get o

_{2}′.pos = 11 + 14 = 25, so we get o

_{2}′ = delete (25, “FlyingInTheSky”). The operation o

_{2}′ fails since at starting position ‘25’ substring “FlyingInTheSky” not found. Even position ‘25’ not exist in given ‘s’. Thus, swapDD fails totally (see Fig. 4).

_{2}′.pos = 17 and o2′.str=‘‘InTheSky” which give right output, because there exist no overlapping in o1′ and o2′ and both lie at given position in string ‘s’ (see Fig. 5).

###
**Case 3:**
*If o*
_{
1.
}
*str completely overlaps by o*
_{
2
}
*.str*

In this case, swapDD lines 6–13 get executed and it gives total wrong output in all cases.

For example, s = “WorkNotO nlyHardButGoodAlso”.

Let o_{1} = delete(7, “Only”); o_{2} = delete(4, “NotOnlyHard”)

Here, on executing swapDD lines 6–13, it will get executed, and we get from line7: o_{2L} ← o_{2} and o_{2R} ← o_{2}. From line 8: o_{2L}.str ← o_{2}.str [0:o_{1}.pos−o_{2}.pos], so we get o_{2L}.str ← o_{2}.str [0:7−4] = “Not”;

_{2R}.pos ← o

_{1}.pos + |o

_{1}.str|; so we get o

_{2R}.pos ← 7 + 4 = 11. And from Line 10 we get o

_{2R}.str ← o

_{2}.str [o

_{1}.pos−o

_{2}.pos:]; so we get o

_{2R}.str ← o

_{2}.str[7 − 4:]; so we get o

_{2R}.str ← “OnlyHard”. Therefore, we get o

_{2R}= delete (11, “OnlyHard”) but in given ‘s’ at position 11 “OnlyHard” not exist so o

_{2}′.sol ← [o

_{2L}, o

_{2R}] also fails totally (see Fig. 6).

###
**Case 4:**
*If o2.str completely overlaps by o1.str*

If o_{2}.str completely overlaps by o_{1}.str, then in this case, swapDD lines 2–3 get executed and it gives total wrong output in all cases.

For example:

Let s = “GodHelpThoseWhoHelpThemselves”

o_{2} = delete (12, “Who”);

o_{1} = delete (3, “HelpThoseWhoHelp”);

Here on executing swapDD lines 2–3 will get executed and we get wrong output.

o1’ = “HelpThoseWhoHelp” o1’ position = 3 o2’ = “Who” o2’ position = 28

### Algorithm MGswapDD

###
**Case 1:**
*If o2.pos* = *o1.pos*

Here, in this case on executing MGswapDD lines 13–25, it will get executed and will give right result.

For example, let s = “TheBirdsAreFlyingInTheSky”

o_{1} = delete(3, “BirdsAreFlying”); o_{2} = delete(3, “Birds”)

_{1}.pos + |o

_{1}.str|) ≥(o

_{2}.pos + |o

_{2}.str|))&& (o

_{1}.pos ≤ o

_{2}.pos)). Here, we get if((3 + 14) ≥ (3 + 5)&&3 ≤3) returns true so code at line 15 that is o

_{2}′ ← null get executed means o

_{2}′ will not execute any operation both its string and position are null. And o

_{1}′ ← o

_{1}from line 1, so we get desired output “TheInTheSky” after execution of o

_{1}′ and o

_{2}′ where o

_{2}′ is null. It satisfies user intentions also (see Fig. 10).

###
**Case 2:**
*If there exist partial overlapping between deletion operations o1 and o2 regions*

Here, two cases are possible either o_{1}.str overlaps with o_{2}.str along its right border or left border.

First, we consider the case when o_{1}.str overlaps with o_{2}.str along its rightboundary. For example, let s = “GodPleaseHelpMeToTakeCareMyChild”.

o_{1} = (3, “PleaseHelpMe”); |o_{1}.str| = 12 and |o_{2}.str| = 12; o_{2} = delete(13, “MeToTakeCare”); o_{1}.pos = 3 and o_{2}.pos = 13.

Since on executing MGswapDD condition at line 7 is true that is if (o_{2}.pos > o_{1}.pos&&o_{2}.pos ≤(o_{1}.pos +|o_{1}.str|) && (o_{2}.pos + |o_{2}.str|) > (o_{1}.pos + |o_{1}.str|)) returns true, so lines 8 and 9 will get executed.

Step 8: o_{2}′.pos = o_{2}.pos + ((o_{1}.pos + |o_{1}.str|)−o_{2}.pos);

Step 9: o_{2}′.str = o_{2}.Substring ((o_{1}.pos + |o_{1}.str|)−o_{2}.pos);

From step 8, o_{2}′.pos = 13 + (3 + 12)−13; o_{2}′ = 15;

_{2}′.str = o

_{2}.Substring (3 + 12−13) = o

_{2}.Substring(2), so o

_{2}′.str = “ToTakeCare”. We get o

_{2}′ = delete (15, “ToTakeCare”) and it runs well since at position 15 “ToTakeCare” exist in given ‘s’. Therefore, the overlapped substring “Me” get deleted by o

_{1}′ and o

_{2}′ has deleted just unoverlapped part of o

_{2}. Here, o

_{1}′ ← o1 from line 1. So again, we get totally right output satisfying user intentions (see Fig. 11).

Second, we consider the case when o_{1}.str overlaps with o_{2}.str along its left boundary.

For example, let s = “GodPleaseHelpMeToTakeCareMyChild”.

o_{2} = (3, “PleaseHelpMe”); |o_{2}.str| = 12 and |o_{1}.str| = 12; o_{1} = delete(13, “MeToTakeCare”); o_{2}.pos = 3 and o_{1}.pos = 13. Since on executing MGswapDD condition at line 10 is true that is so the given code will get executed. Therefore, condition at line 10 is as follows: if(o_{2}.pos < o_{1}.pos&&(o_{2}.pos + |o_{2}.str|) ≥ o_{1}.pos && o_{1}.pos + |o_{1}.str| > (o_{2}.pos + |o_{2}.str|)) returns true so from Step 11: o_{2}′.str = o_{2}.Substring (0, (o_{1}.pos−o_{2}.pos)); so we get o_{2}′.str = o_{2}.Substring (0,(13−3)) = “PleaseHelp”; here |o_{2}′.str| = 10; and from step Step 12: o_{1}′.pos = o_{1}.pos−|o_{2}′.str|; we get o_{1}′.pos = 13−10 = 3. Since after deletion by o_{2}′ the o_{1}′. pos should left by the length of o_{2}′.str as o_{2}′ lies left of o_{1}′ and is already deleted. Here, we get finally o_{1}′ = delete(3, “PleaseHelpMe”) and o_{2}′ = delete(15, “ToTakeCare”) and o_{2}′ → o_{1}′ work well after swapping of o_{1} → o_{2}.

In this case, also we get right output.

###
**Case 3:**
*If o*
_{
1.
}
*str completely overlaps by o*
_{
2
}
*.str*

In this case, all the above conditions before line 13 are false so enter in else block at line 13. Here, condition at Step 14: if(((o_{1}.pos + |o_{1}.str|) ≥ (o_{2}.pos + |o_{2}.str|))&& (o_{1}.pos ≤ o_{2}.pos)) is false so enter in its else part. So lines 16 to 25 get executed.

For example, let s = “The Sun give us Heat and Light”; o_{1} = delete(13, “us”) and o_{2} = delete(4, “Sun give us Heat”). From Step 17: o_{2Lpart} ← o_{2}; o_{2Lpart}.str = o_{2}.str; here, we have o_{2Lpart}.str = “Sun give us Heat”. From Step 18: o_{2Lpart}.pos = o_{2}.pos; Here we have o_{2Lpart}.pos = 4. From Step 19: o_{2Rpart} ← o_{2}; o_{2Rpart}.str = o_{2}.str; here, we have o_{2Rpart}.str = “Sun give us Heat”. From Step 20: o_{2Rpart}.pos = o_{2}.pos; here, we have o_{2Rpart}.pos = 4.

_{2Lpart}.str = o

_{2}.Substring (0, o

_{1}.pos−o

_{2}.pos); here, we have o

_{2Lpart}.str = o

_{2}.Substring (0,13−4) ≥ o

_{2Lpart}.str = o

_{2}.Substring (0,9) = “Sun give”. From Step 22: o

_{2Rpart}.pos = o1.pos + |o1.str|; here, we have o

_{2Rpart}.pos = 13 + 2=15. From Step 23: o

_{2Rpart}.str = o

_{2}.Substring (o

_{1}.pos−o

_{2}.pos + |o

_{1}.str|); here, we have o

_{2Rpart}.str = o

_{2}.Substring (13−4 + 2) = o

_{2}.Substring (11) = “Heat”. From Step 24: o

_{2}′.sol ← [o

_{2Lpart}, o

_{2Rpart}]; so the left part “Sun give”. get deleted by operation o

_{2Lpart};right part “Heat” get deleted by o

_{2Rpart}and the middle overlapping región “us” get deleted by o

_{1}and by

*Step*

*25:*o

_{1}′.pos = o

_{2}.pos;so we get o

_{1}′.pos = 4 since at first o

_{2}′ get executed and since o

_{2Lpart}is already executed the position of o

_{1}′ shift left to o

_{2}.pos. So o

_{2}′ → o

_{1}′ works correctly here (see Fig. 12).

###
**Case 4:**
*If o*
_{
2.
}
*str completely overlaps by o*
_{
1
}
*.str*

In this case, all the above conditions before line 13 are false so enter in else block at line 13. Here, condition at Step 14: if (((o_{1}.pos + |o_{1}.str|) ≥ (o_{2}.pos + |o_{2}.str|))&& (o_{1}.pos ≤ o_{2}.pos)) is true so enter in its if part. So step 15 will get executed.

_{1}= delete (4, “God will help me”) and o

_{2}= delete (8, “will”). Here, condition at Step 14: if(((o

_{1}.pos + |o

_{1}.str|) ≥ (o

_{2}.pos + |o

_{2}.str|))&&(o

_{1}.pos ≤o

_{2}.pos)) that is if((4 + 15) ≥ (8 + 4)&&4 ≤8) is true so condition at line 15 get executed where o

_{2}′ is set to null means will not perform any operation and o

_{1}will remain as it is. If o

_{1}will execute the region of o

_{2}which is covered by o

_{1}will automatically deleted giving right output. Here, o

_{2}′ → o

_{1}′ is equal to execution of o

_{1}′ only, since o

_{2}′ is null and also o

_{1}′ ← o

_{1}from line 1 (see Fig. 13).

## Conclusion

Operational transformation is the most optimistic method for concurrency and consistency control in muti-user groupware systems.

ABTS is the best string handling OT algorithm. The swapDD function of ABTS is proposed to swap two deletions, but swapDD fails totally if there exist partial overlapping between two deletions. In addition, it fails if one deletion operation string is totally covered by other deletion operation string. In few other cases, also swapDD fails at boundary conditions.

We propose a new algorithm MGswapDD to swap two deletions. It is also based on ABT framework and support string handling. It considers and works well in splitting and overlapping of operations. It works well on all boundary conditions also. It is practically implemented in lab also covering all possible cases of swapping two deletions. It gives totally right result if either there exist partial overlapping between two deletions or if one deletion operation string is totally covered by other deletion operation string. Therefore, in brief, it has removed all faults of the existing swapDD and work well in all possible cases of swapping two deletions.

## Future work

Still there is scope to extend the support to other composite operations of string handling and char handling. Also there is need to support better data structures. A lot of work is done to reduce time complexity and space complexity. Still there is a scope to reduce time complexity and space complexity.

## Declarations

### Authors’ contributions

SK made substantial contributions to conception and design, acquisition of data, and analysis and interpretation of data; has been involved in drafting the manuscript or revising it critically for important intellectual content; has given final approval of the version to be published, and agrees to be accountable for all aspects of the work in ensuring that questions related to the accuracy or integrity of any part of the work are appropriately investigated and resolved. AK provided full guidance and support in all of the above works. Both authors read and approved the final manuscript.

### Acknowledgements

The paper is dedicated to my mother Meera Devi and daughter Harshita Kumawat.

### Competing interests

The authors declare that they have no competing interests.

**Open Access**This article is distributed under the terms of the Creative Commons Attribution 4.0 International License (http://creativecommons.org/licenses/by/4.0/), which permits unrestricted use, distribution, and reproduction in any medium, provided you give appropriate credit to the original author(s) and the source, provide a link to the Creative Commons license, and indicate if changes were made.

## Authors’ Affiliations

## References

- Ellis CA, Gibbs SJ (1989) Concurrency control in groupware systems. In ACM SIGMOD 1989 Preceedings, p 399–407, Portland Oregon
- Li D, Li R (2006) An approach to ensuring consistency in peer-to-peer real-time group editors. Comput Support Co-op Work (2008) 17:553–611. doi:10.1007/s10606-005-9009 View ArticleGoogle Scholar
- Li R, Li D (2007) A new operational transformation framework for real-time group editors. IEEE Trans Parallel Distrib Syst 18(3):307–319View ArticleGoogle Scholar
- Li D, Li R (2010) An admissibility-based operational transformation framework for collaborative editing systems. Comput Support Co-op Work 19:1–43. doi:10.1007/s10606-009-9103-1 View ArticleGoogle Scholar
- Ressel M, Nitsche-Ruhland D, Gunzenha R (1996) An integrating, transformation-oriented approach to concurrency control and undo in group editors. Proc. ACM conf. computer supported cooperative work (CSCW 1996), p 288–297
- Shao B, Li D, Gu N (2009) ABTS: A transformation-based consistency control algorithm for wide-area collaborative applications, collaborative computing: networking, applications and worksharing. CollaborateCom 2009. 5th International Conference on Nov. 2009 doi: 10.4108/ICST.COLLABORATECOM2009.8271. p1–10, 11–14
- Shao B, Li D, Gu N (2010) An algorithm for selective undo of any operation in collaborative applications, in ACM
- Suleiman M, Cart M, Ferrié J (1998) Concurrent operations in a distributed and mobile collaborative environment. Proceedings of the fourteenth international conference on data engineering, p 23–27
- Sun C, Ellis C (1998) Operational transformation in real-time group editors: issues, algorithms, and achievements In ACM CSCW 1998, p 59–68
- Sun C, Jia X, Zhang Y, Yang Y, Chen D (1998) Achieving convergence, causality-preservation, and intention preservation in real-time cooperative editing systems. ACM Trans Comput Hum Interact 5(1):63–108View ArticleGoogle Scholar
- Vidot N, Cart M, Ferrie J, Suleiman M (2000) Copies convergence in a distributed real-time collaborative environment. Proceedings of the 2000 ACM conference on computer supported cooperative work. ACM Press, New York, pp 171–180View ArticleGoogle Scholar