| 2068 | } |
| 2069 | |
| 2070 | RangeResult ReadYourWritesTransaction::getWriteConflictRangeIntersecting(KeyRangeRef kr) { |
| 2071 | CODE_PROBE(true, "Special keys write conflict range"); |
| 2072 | ASSERT(writeConflictRangeKeysRange.contains(kr)); |
| 2073 | RangeResult result; |
| 2074 | |
| 2075 | // Memory owned by result |
| 2076 | CoalescedKeyRefRangeMap<ValueRef> writeConflicts{ LiteralStringRef("0"), specialKeys.end }; |
| 2077 | |
| 2078 | if (!options.readYourWritesDisabled) { |
| 2079 | KeyRangeRef strippedWriteRangePrefix = kr.removePrefix(writeConflictRangeKeysRange.begin); |
| 2080 | WriteMap::iterator it(&writes); |
| 2081 | it.skip(strippedWriteRangePrefix.begin); |
| 2082 | if (it.beginKey() > allKeys.begin) |
| 2083 | --it; |
| 2084 | for (; it.beginKey() < strippedWriteRangePrefix.end; ++it) { |
| 2085 | if (it.is_conflict_range()) |
| 2086 | writeConflicts.insert( |
| 2087 | KeyRangeRef(it.beginKey().toArena(result.arena()), it.endKey().toArena(result.arena())) |
| 2088 | .withPrefix(writeConflictRangeKeysRange.begin, result.arena()), |
| 2089 | LiteralStringRef("1")); |
| 2090 | } |
| 2091 | } else { |
| 2092 | for (const auto& range : tr.writeConflictRanges()) |
| 2093 | writeConflicts.insert(range.withPrefix(writeConflictRangeKeysRange.begin, result.arena()), |
| 2094 | LiteralStringRef("1")); |
| 2095 | for (const auto& range : nativeWriteRanges) |
| 2096 | writeConflicts.insert(range.withPrefix(writeConflictRangeKeysRange.begin, result.arena()), |
| 2097 | LiteralStringRef("1")); |
| 2098 | } |
| 2099 | |
| 2100 | for (const auto& k : versionStampKeys) { |
| 2101 | KeyRange range; |
| 2102 | if (versionStampFuture.isValid() && versionStampFuture.isReady() && !versionStampFuture.isError()) { |
| 2103 | const auto& stamp = versionStampFuture.get(); |
| 2104 | StringRef key(range.arena(), k); // Copy |
| 2105 | ASSERT(k.size() >= 4); |
| 2106 | int32_t pos; |
| 2107 | memcpy(&pos, k.end() - sizeof(int32_t), sizeof(int32_t)); |
| 2108 | pos = littleEndian32(pos); |
| 2109 | ASSERT(pos >= 0 && pos + stamp.size() <= key.size()); |
| 2110 | memcpy(mutateString(key) + pos, stamp.begin(), stamp.size()); |
| 2111 | *(mutateString(key) + key.size() - 4) = '\x00'; |
| 2112 | // singleKeyRange, but share begin and end's memory |
| 2113 | range = KeyRangeRef(key.substr(0, key.size() - 4), key.substr(0, key.size() - 3)); |
| 2114 | } else { |
| 2115 | range = getVersionstampKeyRange(result.arena(), k, tr.getCachedReadVersion().orDefault(0), getMaxReadKey()); |
| 2116 | } |
| 2117 | writeConflicts.insert(range.withPrefix(writeConflictRangeKeysRange.begin, result.arena()), |
| 2118 | LiteralStringRef("1")); |
| 2119 | } |
| 2120 | |
| 2121 | auto beginIter = writeConflicts.rangeContaining(kr.begin); |
| 2122 | if (beginIter->begin() != kr.begin) |
| 2123 | ++beginIter; |
| 2124 | for (auto it = beginIter; it->begin() < kr.end; ++it) { |
| 2125 | result.push_back(result.arena(), KeyValueRef(it->begin(), it->value())); |
| 2126 | } |
| 2127 | |