|
| 1 | +/* |
| 2 | + * Copyright (c) 2023. |
| 3 | + * |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | + * you may not use this file except in compliance with the License. |
| 6 | + * You may obtain a copy of the License at |
| 7 | + * |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | + * |
| 10 | + * Unless required by applicable law or agreed to in writing, software |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | + * See the License for the specific language governing permissions and |
| 14 | + * limitations under the License. |
| 15 | + */ |
| 16 | + |
| 17 | +import org.modelix.model.LinearHistory |
| 18 | +import org.modelix.model.VersionMerger |
| 19 | +import org.modelix.model.lazy.CLTree |
| 20 | +import org.modelix.model.lazy.CLVersion |
| 21 | +import org.modelix.model.lazy.ObjectStoreCache |
| 22 | +import org.modelix.model.operations.IOperation |
| 23 | +import org.modelix.model.persistent.MapBaseStore |
| 24 | +import kotlin.test.Test |
| 25 | +import kotlin.test.assertEquals |
| 26 | + |
| 27 | +class LinearHistoryTest { |
| 28 | + val initialTree = CLTree.builder(ObjectStoreCache(MapBaseStore())).repositoryId("LinearHistoryTest").build() |
| 29 | + |
| 30 | + @Test |
| 31 | + fun noCommonHistory() { |
| 32 | + val v20 = version(20, null) |
| 33 | + val v21 = version(21, null) |
| 34 | + |
| 35 | + assertHistory(v20, v21, listOf(v20, v21)) |
| 36 | + } |
| 37 | + |
| 38 | + @Test |
| 39 | + fun divergedByTwoCommits() { |
| 40 | + val v10 = version(10, null) |
| 41 | + val v20 = version(20, v10) |
| 42 | + val v21 = version(21, v10) |
| 43 | + |
| 44 | + assertHistory(v20, v21, listOf(v20, v21)) |
| 45 | + } |
| 46 | + |
| 47 | + @Test |
| 48 | + fun knownPerformanceIssue() { |
| 49 | + // This test was dumped from actual case discovered during a profiling session. |
| 50 | + |
| 51 | + val v30000003a = version(12884901946, null) |
| 52 | + val v1000004d1 = version(4294968529, v30000003a) |
| 53 | + val v1000004d3 = version(4294968531, v1000004d1) |
| 54 | + val v200000353 = version(8589935443, v1000004d3) |
| 55 | + val v1000004d5 = version(4294968533, v1000004d3) |
| 56 | + val v30000003c = merge(12884901948, v1000004d3, v200000353, v1000004d5) |
| 57 | + val v1000004d6 = merge(4294968534, v1000004d3, v1000004d5, v200000353) |
| 58 | + val v30000003d = merge(12884901949, v1000004d3, v30000003c, v1000004d6) |
| 59 | + val v30000003e = merge(12884901950, v1000004d3, v30000003d, v1000004d6) |
| 60 | + val v200000354 = merge(8589935444, v1000004d3, v200000353, v30000003d) |
| 61 | + val v30000003f = merge(12884901951, v1000004d3, v30000003e, v200000354) |
| 62 | + val v300000040 = merge(12884901952, v1000004d3, v30000003f, v200000354) |
| 63 | + val v200000356 = version(8589935446, v200000354) |
| 64 | + val v300000041 = merge(12884901953, v1000004d3, v300000040, v200000356) |
| 65 | + val v1000004d8 = version(4294968536, v1000004d6) |
| 66 | + val v300000042 = merge(12884901954, v1000004d3, v300000041, v1000004d8) |
| 67 | + val v1000004d9 = merge(4294968537, v1000004d3, v1000004d8, v300000041) |
| 68 | + val v300000043 = merge(12884901955, v1000004d3, v300000042, v1000004d9) |
| 69 | + val v300000044 = merge(12884901956, v1000004d3, v300000043, v1000004d9) |
| 70 | + val v200000357 = merge(8589935447, v1000004d3, v200000356, v300000041) |
| 71 | + val v300000045 = merge(12884901957, v1000004d3, v300000044, v200000357) |
| 72 | + val v300000046 = merge(12884901958, v1000004d3, v300000045, v200000357) |
| 73 | + val v1000004da = merge(4294968538, v1000004d3, v1000004d9, v300000046) |
| 74 | + val v300000047 = merge(12884901959, v1000004d3, v300000046, v1000004da) |
| 75 | + val v300000048 = merge(12884901960, v1000004d3, v300000047, v1000004da) |
| 76 | + val v200000359 = version(8589935449, v200000357) |
| 77 | + val v300000049 = merge(12884901961, v1000004d3, v300000048, v200000359) |
| 78 | + val v1000004dc = version(4294968540, v1000004da) |
| 79 | + val v30000004a = merge(12884901962, v1000004d3, v300000049, v1000004dc) |
| 80 | + val v20000035a = merge(8589935450, v1000004d3, v200000359, v300000046) |
| 81 | + val v30000004b = merge(12884901963, v1000004d3, v30000004a, v20000035a) |
| 82 | + val v30000004c = merge(12884901964, v1000004d3, v30000004b, v20000035a) |
| 83 | + val v1000004dd = merge(4294968541, v1000004d3, v1000004dc, v30000004c) |
| 84 | + val v30000004d = merge(12884901965, v1000004d3, v30000004c, v1000004dd) |
| 85 | + val v30000004e = merge(12884901966, v1000004d3, v30000004d, v1000004dd) |
| 86 | + val v20000035b = merge(8589935451, v1000004d3, v20000035a, v30000004c) |
| 87 | + val v30000004f = merge(12884901967, v1000004d3, v30000004e, v20000035b) |
| 88 | + val v300000050 = merge(12884901968, v1000004d3, v30000004f, v20000035b) |
| 89 | + val v1000004df = version(4294968543, v1000004dd) |
| 90 | + val v300000051 = merge(12884901969, v1000004d3, v300000050, v1000004df) |
| 91 | + val v20000035d = version(8589935453, v20000035b) |
| 92 | + val v300000052 = merge(12884901970, v1000004d3, v300000051, v20000035d) |
| 93 | + val v1000004e0 = merge(4294968544, v1000004d3, v1000004df, v300000051) |
| 94 | + val v300000053 = merge(12884901971, v1000004d3, v300000052, v1000004e0) |
| 95 | + val v300000054 = merge(12884901972, v1000004d3, v300000053, v1000004e0) |
| 96 | + val v20000035f = version(8589935455, v20000035d) |
| 97 | + val v300000055 = merge(12884901973, v1000004d3, v300000054, v20000035f) |
| 98 | + val v200000360 = merge(8589935456, v1000004d3, v20000035f, v300000052) |
| 99 | + val v300000056 = merge(12884901974, v1000004d3, v300000055, v200000360) |
| 100 | + val v300000057 = merge(12884901975, v1000004d3, v300000056, v200000360) |
| 101 | + val v1000004e2 = version(4294968546, v1000004e0) |
| 102 | + val v300000058 = merge(12884901976, v1000004d3, v300000057, v1000004e2) |
| 103 | + val v200000362 = version(8589935458, v200000360) |
| 104 | + val v300000059 = merge(12884901977, v1000004d3, v300000058, v200000362) |
| 105 | + val v1000004e3 = merge(4294968547, v1000004d3, v1000004e2, v300000058) |
| 106 | + val v30000005a = merge(12884901978, v1000004d3, v300000059, v1000004e3) |
| 107 | + val v30000005b = merge(12884901979, v1000004d3, v30000005a, v1000004e3) |
| 108 | + val v1000004e5 = version(4294968549, v1000004e3) |
| 109 | + val v30000005c = merge(12884901980, v1000004d3, v30000005b, v1000004e5) |
| 110 | + val v200000363 = merge(8589935459, v1000004d3, v200000362, v300000058) |
| 111 | + val v30000005d = merge(12884901981, v1000004d3, v30000005c, v200000363) |
| 112 | + val v30000005e = merge(12884901982, v1000004d3, v30000005d, v200000363) |
| 113 | + val v200000365 = version(8589935461, v200000363) |
| 114 | + val v30000005f = merge(12884901983, v1000004d3, v30000005e, v200000365) |
| 115 | + val v1000004e7 = version(4294968551, v1000004e5) |
| 116 | + val v300000060 = merge(12884901984, v1000004d3, v30000005f, v1000004e7) |
| 117 | + val v200000367 = version(8589935463, v200000365) |
| 118 | + val v300000061 = merge(12884901985, v1000004d3, v300000060, v200000367) |
| 119 | + val v1000004e9 = version(4294968553, v1000004e7) |
| 120 | + val v300000062 = merge(12884901986, v1000004d3, v300000061, v1000004e9) |
| 121 | + val v1000004ea = merge(4294968554, v1000004d3, v1000004e9, v300000060) |
| 122 | + val v300000063 = merge(12884901987, v1000004d3, v300000062, v1000004ea) |
| 123 | + val v300000064 = merge(12884901988, v1000004d3, v300000063, v1000004ea) |
| 124 | + val v200000369 = version(8589935465, v200000367) |
| 125 | + val v300000065 = merge(12884901989, v1000004d3, v300000064, v200000369) |
| 126 | + val v20000036a = merge(8589935466, v1000004d3, v200000369, v300000060) |
| 127 | + val v300000066 = merge(12884901990, v1000004d3, v300000065, v20000036a) |
| 128 | + val v1000004eb = merge(4294968555, v1000004d3, v1000004ea, v300000061) |
| 129 | + val v300000067 = merge(12884901991, v1000004d3, v300000066, v1000004eb) |
| 130 | + val v20000036c = version(8589935468, v20000036a) |
| 131 | + val v300000068 = merge(12884901992, v1000004d3, v300000067, v20000036c) |
| 132 | + val v300000069 = merge(12884901993, v1000004d3, v300000068, v20000036a) |
| 133 | + val v30000006b = merge(12884901995, v1000004d3, v300000069, v1000004eb) |
| 134 | + val v20000036d = merge(8589935469, v1000004d3, v20000036c, v300000063) |
| 135 | + val v30000006c = merge(12884901996, v1000004d3, v30000006b, v20000036d) |
| 136 | + val v30000006d = merge(12884901997, v1000004d3, v30000006c, v20000036d) |
| 137 | + val v1000004ec = merge(4294968556, v1000004d3, v1000004eb, v30000006c) |
| 138 | + val v30000006e = merge(12884901998, v1000004d3, v30000006d, v1000004ec) |
| 139 | + val v300000070 = merge(12884902000, v1000004d3, v30000006e, v1000004ec) |
| 140 | + val v20000036e = merge(8589935470, v1000004d3, v20000036d, v30000006e) |
| 141 | + val v300000071 = merge(12884902001, v1000004d3, v300000070, v20000036e) |
| 142 | + val v1000004ed = merge(4294968557, v1000004d3, v1000004ec, v30000006e) |
| 143 | + val v300000072 = merge(12884902002, v1000004d3, v300000071, v1000004ed) |
| 144 | + val v20000036f = merge(8589935471, v1000004d3, v20000036e, v30000006e) |
| 145 | + val v300000073 = merge(12884902003, v1000004d3, v300000072, v20000036f) |
| 146 | + val v300000074 = merge(12884902004, v1000004d3, v300000073, v20000036f) |
| 147 | + val v300000075 = merge(12884902005, v1000004d3, v300000074, v20000036e) |
| 148 | + val v1000004ee = merge(4294968558, v1000004d3, v30000006e, v300000075) |
| 149 | + |
| 150 | + // val expected = SlowLinearHistory(v1000004d3.getContentHash()).load(v300000075, v1000004ee) |
| 151 | + val expected = listOf( |
| 152 | + v1000004d5, |
| 153 | + v200000353, |
| 154 | + v1000004d8, |
| 155 | + v1000004dc, |
| 156 | + v1000004df, |
| 157 | + v1000004e2, |
| 158 | + v1000004e5, |
| 159 | + v1000004e7, |
| 160 | + v1000004e9, |
| 161 | + v200000356, |
| 162 | + v200000359, |
| 163 | + v20000035d, |
| 164 | + v20000035f, |
| 165 | + v200000362, |
| 166 | + v200000365, |
| 167 | + v200000367, |
| 168 | + v200000369, |
| 169 | + v20000036c, |
| 170 | + ) |
| 171 | + assertHistory(v300000075, v1000004ee, expected) |
| 172 | + } |
| 173 | + |
| 174 | + private fun assertHistory(v1: CLVersion, v2: CLVersion, expected: List<CLVersion>) { |
| 175 | + val actual = history(v1, v2) |
| 176 | + assertEquals(expected.map { it.id.toString(16) }, actual.map { it.id.toString(16) }) |
| 177 | + assertEquals(expected, actual) |
| 178 | + } |
| 179 | + |
| 180 | + private fun history(v1: CLVersion, v2: CLVersion): List<CLVersion> { |
| 181 | + val base = VersionMerger.commonBaseVersion(v1, v2) |
| 182 | + return LinearHistory(base?.getContentHash()).load(v1, v2) |
| 183 | + } |
| 184 | + |
| 185 | + private fun version(id: Long, base: CLVersion?): CLVersion { |
| 186 | + return CLVersion.createRegularVersion( |
| 187 | + id, |
| 188 | + null, |
| 189 | + null, |
| 190 | + initialTree, |
| 191 | + base, |
| 192 | + emptyArray(), |
| 193 | + ) |
| 194 | + } |
| 195 | + |
| 196 | + private fun merge(id: Long, v1: CLVersion, v2: CLVersion): CLVersion { |
| 197 | + return merge(id, VersionMerger.Companion.commonBaseVersion(v1, v2)!!, v1, v2) |
| 198 | + } |
| 199 | + |
| 200 | + private fun merge(id: Long, base: CLVersion, v1: CLVersion, v2: CLVersion): CLVersion { |
| 201 | + return CLVersion.createAutoMerge( |
| 202 | + id, |
| 203 | + initialTree, |
| 204 | + base, |
| 205 | + v1, |
| 206 | + v2, |
| 207 | + emptyArray<IOperation>(), |
| 208 | + initialTree.store, |
| 209 | + ) |
| 210 | + } |
| 211 | +} |
0 commit comments