From 99cfc3e1467ccd85b20304d2de69dddce281da24 Mon Sep 17 00:00:00 2001 From: Nathan VanBenschoten Date: Wed, 4 Mar 2020 08:15:51 -0500 Subject: [PATCH] kv: support unreplicated locks, hook up SELECT FOR UPDATE Closes #40205. Informs #41720. This change teaches the KV client and the KV API about unreplicated locks. It then adds a KeyLocking mode to ScanRequest and ReverseScanRequest, which allows their users to select the locking strength that they would like the scan to use. This locking strength defaults to None, which corresponds to the current behavior. However, some users will want to acquire locks on each row scanned, which is now possible by setting the locking strength to a stronger level. For now, only the Exclusive strength is supported. The change then revisits SQL's row-level locking support, which is supported all the way down to the row fetcher for implicit (e.g. UPDATE) and explicit (e.g. SELECT ... FOR UPDATE) upgrade locking. The change uses the new key-locking functionality in the KV API to hook up row-level locking, completing the integration of SELECT FOR UPDATE with the KV layer and, in particular, the new lock-table structure. https://github.com/cockroachdb/cockroach/pull/43775 described the three main benefits of this change: - higher throughput under contention - lower latency and improved fairness under contention - a reduction in transaction retries under contention I've revisited those results a few times in the last two months and seen that the results continue to hold, and in some cases they have improved. I intend to update this PR with a more complete analysis of its impact on those three areas. Release note (sql change): SELECT FOR UPDATE now hooks into a new leaseholder-only locking mechanism. This allows the feature to be used to improve performance of transactional that read, modify, and write contended to rows. Similarly, UPDATE statements now use this new mechanism by default, meaning that their performance under contention is improved. --- c-deps/libroach/protos/roachpb/api.pb.cc | 88 +- c-deps/libroach/protos/roachpb/api.pb.h | 43 + c-deps/libroach/protos/roachpb/data.pb.h | 2 +- docs/generated/settings/settings.html | 2 +- pkg/ccl/changefeedccl/kvfeed/scanner.go | 2 +- pkg/internal/client/batch.go | 34 +- pkg/internal/client/db.go | 37 +- pkg/internal/client/db_test.go | 50 + pkg/internal/client/txn.go | 40 +- pkg/kv/dist_sender_server_test.go | 4 +- pkg/kv/dist_sender_test.go | 21 +- pkg/kv/kvserver/batch_spanset_test.go | 8 +- pkg/kv/kvserver/batcheval/cmd_reverse_scan.go | 46 +- pkg/kv/kvserver/batcheval/cmd_scan.go | 46 +- pkg/kv/kvserver/batcheval/intent.go | 40 + .../concurrency/concurrency_control.go | 5 +- pkg/kv/kvserver/replica_evaluate_test.go | 109 +- pkg/kv/kvserver/replica_test.go | 80 ++ pkg/kv/kvserver/replica_write.go | 21 +- pkg/kv/txn_coord_sender.go | 2 +- pkg/kv/txn_coord_sender_test.go | 177 +-- pkg/kv/txn_interceptor_heartbeater_test.go | 4 +- pkg/kv/txn_interceptor_pipeliner.go | 118 +- pkg/kv/txn_interceptor_pipeliner_test.go | 170 ++- pkg/roachpb/api.go | 42 +- pkg/roachpb/api.pb.go | 1254 +++++++++-------- pkg/roachpb/api.proto | 25 + pkg/roachpb/batch_test.go | 8 +- pkg/roachpb/data.pb.go | 332 ++--- pkg/roachpb/data.proto | 2 +- pkg/server/server_test.go | 11 +- pkg/sql/logictest/testdata/logic_test/fk | 6 +- pkg/sql/logictest/testdata/logic_test/fk_opt | 6 +- pkg/sql/row/kv_batch_fetcher.go | 39 +- pkg/storage/mvcc.go | 67 +- 35 files changed, 1810 insertions(+), 1131 deletions(-) diff --git a/c-deps/libroach/protos/roachpb/api.pb.cc b/c-deps/libroach/protos/roachpb/api.pb.cc index b609f27e34de..c6b9e90e1358 100644 --- a/c-deps/libroach/protos/roachpb/api.pb.cc +++ b/c-deps/libroach/protos/roachpb/api.pb.cc @@ -7964,6 +7964,7 @@ void ScanRequest::InitAsDefaultInstance() { #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int ScanRequest::kHeaderFieldNumber; const int ScanRequest::kScanFormatFieldNumber; +const int ScanRequest::kKeyLockingFieldNumber; #endif // !defined(_MSC_VER) || _MSC_VER >= 1900 ScanRequest::ScanRequest() @@ -7982,14 +7983,16 @@ ScanRequest::ScanRequest(const ScanRequest& from) } else { header_ = NULL; } - scan_format_ = from.scan_format_; + ::memcpy(&scan_format_, &from.scan_format_, + static_cast(reinterpret_cast(&key_locking_) - + reinterpret_cast(&scan_format_)) + sizeof(key_locking_)); // @@protoc_insertion_point(copy_constructor:cockroach.roachpb.ScanRequest) } void ScanRequest::SharedCtor() { ::memset(&header_, 0, static_cast( - reinterpret_cast(&scan_format_) - - reinterpret_cast(&header_)) + sizeof(scan_format_)); + reinterpret_cast(&key_locking_) - + reinterpret_cast(&header_)) + sizeof(key_locking_)); } ScanRequest::~ScanRequest() { @@ -8020,7 +8023,9 @@ void ScanRequest::Clear() { delete header_; } header_ = NULL; - scan_format_ = 0; + ::memset(&scan_format_, 0, static_cast( + reinterpret_cast(&key_locking_) - + reinterpret_cast(&scan_format_)) + sizeof(key_locking_)); _internal_metadata_.Clear(); } @@ -8066,6 +8071,21 @@ bool ScanRequest::MergePartialFromCodedStream( break; } + // .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; + case 5: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + set_key_locking(static_cast< ::cockroach::kv::kvserver::concurrency::lock::Strength >(value)); + } else { + goto handle_unusual; + } + break; + } + default: { handle_unusual: if (tag == 0) { @@ -8103,6 +8123,12 @@ void ScanRequest::SerializeWithCachedSizes( 4, this->scan_format(), output); } + // .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; + if (this->key_locking() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 5, this->key_locking(), output); + } + output->WriteRaw((::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()).data(), static_cast((::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()).size())); // @@protoc_insertion_point(serialize_end:cockroach.roachpb.ScanRequest) @@ -8126,6 +8152,12 @@ size_t ScanRequest::ByteSizeLong() const { ::google::protobuf::internal::WireFormatLite::EnumSize(this->scan_format()); } + // .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; + if (this->key_locking() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->key_locking()); + } + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); SetCachedSize(cached_size); return total_size; @@ -8149,6 +8181,9 @@ void ScanRequest::MergeFrom(const ScanRequest& from) { if (from.scan_format() != 0) { set_scan_format(from.scan_format()); } + if (from.key_locking() != 0) { + set_key_locking(from.key_locking()); + } } void ScanRequest::CopyFrom(const ScanRequest& from) { @@ -8170,6 +8205,7 @@ void ScanRequest::InternalSwap(ScanRequest* other) { using std::swap; swap(header_, other->header_); swap(scan_format_, other->scan_format_); + swap(key_locking_, other->key_locking_); _internal_metadata_.Swap(&other->_internal_metadata_); } @@ -8479,6 +8515,7 @@ void ReverseScanRequest::InitAsDefaultInstance() { #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int ReverseScanRequest::kHeaderFieldNumber; const int ReverseScanRequest::kScanFormatFieldNumber; +const int ReverseScanRequest::kKeyLockingFieldNumber; #endif // !defined(_MSC_VER) || _MSC_VER >= 1900 ReverseScanRequest::ReverseScanRequest() @@ -8497,14 +8534,16 @@ ReverseScanRequest::ReverseScanRequest(const ReverseScanRequest& from) } else { header_ = NULL; } - scan_format_ = from.scan_format_; + ::memcpy(&scan_format_, &from.scan_format_, + static_cast(reinterpret_cast(&key_locking_) - + reinterpret_cast(&scan_format_)) + sizeof(key_locking_)); // @@protoc_insertion_point(copy_constructor:cockroach.roachpb.ReverseScanRequest) } void ReverseScanRequest::SharedCtor() { ::memset(&header_, 0, static_cast( - reinterpret_cast(&scan_format_) - - reinterpret_cast(&header_)) + sizeof(scan_format_)); + reinterpret_cast(&key_locking_) - + reinterpret_cast(&header_)) + sizeof(key_locking_)); } ReverseScanRequest::~ReverseScanRequest() { @@ -8535,7 +8574,9 @@ void ReverseScanRequest::Clear() { delete header_; } header_ = NULL; - scan_format_ = 0; + ::memset(&scan_format_, 0, static_cast( + reinterpret_cast(&key_locking_) - + reinterpret_cast(&scan_format_)) + sizeof(key_locking_)); _internal_metadata_.Clear(); } @@ -8581,6 +8622,21 @@ bool ReverseScanRequest::MergePartialFromCodedStream( break; } + // .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; + case 5: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + set_key_locking(static_cast< ::cockroach::kv::kvserver::concurrency::lock::Strength >(value)); + } else { + goto handle_unusual; + } + break; + } + default: { handle_unusual: if (tag == 0) { @@ -8618,6 +8674,12 @@ void ReverseScanRequest::SerializeWithCachedSizes( 4, this->scan_format(), output); } + // .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; + if (this->key_locking() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 5, this->key_locking(), output); + } + output->WriteRaw((::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()).data(), static_cast((::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()).size())); // @@protoc_insertion_point(serialize_end:cockroach.roachpb.ReverseScanRequest) @@ -8641,6 +8703,12 @@ size_t ReverseScanRequest::ByteSizeLong() const { ::google::protobuf::internal::WireFormatLite::EnumSize(this->scan_format()); } + // .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; + if (this->key_locking() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->key_locking()); + } + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); SetCachedSize(cached_size); return total_size; @@ -8664,6 +8732,9 @@ void ReverseScanRequest::MergeFrom(const ReverseScanRequest& from) { if (from.scan_format() != 0) { set_scan_format(from.scan_format()); } + if (from.key_locking() != 0) { + set_key_locking(from.key_locking()); + } } void ReverseScanRequest::CopyFrom(const ReverseScanRequest& from) { @@ -8685,6 +8756,7 @@ void ReverseScanRequest::InternalSwap(ReverseScanRequest* other) { using std::swap; swap(header_, other->header_); swap(scan_format_, other->scan_format_); + swap(key_locking_, other->key_locking_); _internal_metadata_.Swap(&other->_internal_metadata_); } diff --git a/c-deps/libroach/protos/roachpb/api.pb.h b/c-deps/libroach/protos/roachpb/api.pb.h index 81672a19353d..dc302ba43733 100644 --- a/c-deps/libroach/protos/roachpb/api.pb.h +++ b/c-deps/libroach/protos/roachpb/api.pb.h @@ -33,6 +33,7 @@ #include #include #include +#include "kv/kvserver/concurrency/lock/locking.pb.h" #include "roachpb/data.pb.h" #include "roachpb/errors.pb.h" #include "roachpb/metadata.pb.h" @@ -3245,12 +3246,19 @@ class ScanRequest : public ::google::protobuf::MessageLite /* @@protoc_insertion ::cockroach::roachpb::ScanFormat scan_format() const; void set_scan_format(::cockroach::roachpb::ScanFormat value); + // .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; + void clear_key_locking(); + static const int kKeyLockingFieldNumber = 5; + ::cockroach::kv::kvserver::concurrency::lock::Strength key_locking() const; + void set_key_locking(::cockroach::kv::kvserver::concurrency::lock::Strength value); + // @@protoc_insertion_point(class_scope:cockroach.roachpb.ScanRequest) private: ::google::protobuf::internal::InternalMetadataWithArenaLite _internal_metadata_; ::cockroach::roachpb::RequestHeader* header_; int scan_format_; + int key_locking_; mutable ::google::protobuf::internal::CachedSize _cached_size_; friend struct ::protobuf_roachpb_2fapi_2eproto::TableStruct; }; @@ -3511,12 +3519,19 @@ class ReverseScanRequest : public ::google::protobuf::MessageLite /* @@protoc_in ::cockroach::roachpb::ScanFormat scan_format() const; void set_scan_format(::cockroach::roachpb::ScanFormat value); + // .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; + void clear_key_locking(); + static const int kKeyLockingFieldNumber = 5; + ::cockroach::kv::kvserver::concurrency::lock::Strength key_locking() const; + void set_key_locking(::cockroach::kv::kvserver::concurrency::lock::Strength value); + // @@protoc_insertion_point(class_scope:cockroach.roachpb.ReverseScanRequest) private: ::google::protobuf::internal::InternalMetadataWithArenaLite _internal_metadata_; ::cockroach::roachpb::RequestHeader* header_; int scan_format_; + int key_locking_; mutable ::google::protobuf::internal::CachedSize _cached_size_; friend struct ::protobuf_roachpb_2fapi_2eproto::TableStruct; }; @@ -18818,6 +18833,20 @@ inline void ScanRequest::set_scan_format(::cockroach::roachpb::ScanFormat value) // @@protoc_insertion_point(field_set:cockroach.roachpb.ScanRequest.scan_format) } +// .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; +inline void ScanRequest::clear_key_locking() { + key_locking_ = 0; +} +inline ::cockroach::kv::kvserver::concurrency::lock::Strength ScanRequest::key_locking() const { + // @@protoc_insertion_point(field_get:cockroach.roachpb.ScanRequest.key_locking) + return static_cast< ::cockroach::kv::kvserver::concurrency::lock::Strength >(key_locking_); +} +inline void ScanRequest::set_key_locking(::cockroach::kv::kvserver::concurrency::lock::Strength value) { + + key_locking_ = value; + // @@protoc_insertion_point(field_set:cockroach.roachpb.ScanRequest.key_locking) +} + // ------------------------------------------------------------------- // ScanResponse @@ -19067,6 +19096,20 @@ inline void ReverseScanRequest::set_scan_format(::cockroach::roachpb::ScanFormat // @@protoc_insertion_point(field_set:cockroach.roachpb.ReverseScanRequest.scan_format) } +// .cockroach.kv.kvserver.concurrency.lock.Strength key_locking = 5; +inline void ReverseScanRequest::clear_key_locking() { + key_locking_ = 0; +} +inline ::cockroach::kv::kvserver::concurrency::lock::Strength ReverseScanRequest::key_locking() const { + // @@protoc_insertion_point(field_get:cockroach.roachpb.ReverseScanRequest.key_locking) + return static_cast< ::cockroach::kv::kvserver::concurrency::lock::Strength >(key_locking_); +} +inline void ReverseScanRequest::set_key_locking(::cockroach::kv::kvserver::concurrency::lock::Strength value) { + + key_locking_ = value; + // @@protoc_insertion_point(field_set:cockroach.roachpb.ReverseScanRequest.key_locking) +} + // ------------------------------------------------------------------- // ReverseScanResponse diff --git a/c-deps/libroach/protos/roachpb/data.pb.h b/c-deps/libroach/protos/roachpb/data.pb.h index abdb2c85acf3..868005987ba8 100644 --- a/c-deps/libroach/protos/roachpb/data.pb.h +++ b/c-deps/libroach/protos/roachpb/data.pb.h @@ -30,8 +30,8 @@ #include // IWYU pragma: export #include // IWYU pragma: export #include -#include "roachpb/metadata.pb.h" #include "kv/kvserver/concurrency/lock/locking.pb.h" +#include "roachpb/metadata.pb.h" #include "storage/enginepb/mvcc.pb.h" #include "storage/enginepb/mvcc3.pb.h" #include "util/hlc/timestamp.pb.h" diff --git a/docs/generated/settings/settings.html b/docs/generated/settings/settings.html index a544c9577fca..09fd5edd51cf 100644 --- a/docs/generated/settings/settings.html +++ b/docs/generated/settings/settings.html @@ -24,7 +24,7 @@ kv.replication_reports.intervalduration1m0sthe frequency for generating the replication_constraint_stats, replication_stats_report and replication_critical_localities reports (set to 0 to disable) kv.snapshot_rebalance.max_ratebyte size8.0 MiBthe rate limit (bytes/sec) to use for rebalance and upreplication snapshots kv.snapshot_recovery.max_ratebyte size8.0 MiBthe rate limit (bytes/sec) to use for recovery snapshots -kv.transaction.max_intents_bytesinteger262144maximum number of bytes used to track write intents in transactions +kv.transaction.max_intents_bytesinteger262144maximum number of bytes used to track locks in transactions kv.transaction.max_refresh_spans_bytesinteger256000maximum number of bytes used to track refresh spans in serializable transactions server.clock.forward_jump_check_enabledbooleanfalseif enabled, forward clock jumps > max_offset/2 will cause a panic server.clock.persist_upper_bound_intervalduration0sthe interval between persisting the wall time upper bound of the clock. The clock does not generate a wall time greater than the persisted timestamp and will panic if it sees a wall time greater than this value. When cockroach starts, it waits for the wall time to catch-up till this persisted timestamp. This guarantees monotonic wall time across server restarts. Not setting this or setting a value of 0 disables this feature. diff --git a/pkg/ccl/changefeedccl/kvfeed/scanner.go b/pkg/ccl/changefeedccl/kvfeed/scanner.go index aac870063a73..314a69cdb32c 100644 --- a/pkg/ccl/changefeedccl/kvfeed/scanner.go +++ b/pkg/ccl/changefeedccl/kvfeed/scanner.go @@ -107,7 +107,7 @@ func (p *scanRequestScanner) exportSpan( for remaining := span; ; { start := timeutil.Now() b := txn.NewBatch() - r := roachpb.NewScan(remaining.Key, remaining.EndKey).(*roachpb.ScanRequest) + r := roachpb.NewScan(remaining.Key, remaining.EndKey, false /* forUpdate */).(*roachpb.ScanRequest) r.ScanFormat = roachpb.BATCH_RESPONSE b.Header.TargetBytes = targetBytesPerScan // NB: We use a raw request rather than the Scan() method because we want diff --git a/pkg/internal/client/batch.go b/pkg/internal/client/batch.go index 3817cd13ea2e..0a7727faa16a 100644 --- a/pkg/internal/client/batch.go +++ b/pkg/internal/client/batch.go @@ -520,7 +520,7 @@ func (b *Batch) Inc(key interface{}, value int64) { b.initResult(1, 1, notRaw, nil) } -func (b *Batch) scan(s, e interface{}, isReverse bool) { +func (b *Batch) scan(s, e interface{}, isReverse, forUpdate bool) { begin, err := marshalKey(s) if err != nil { b.initResult(0, 0, notRaw, err) @@ -532,9 +532,9 @@ func (b *Batch) scan(s, e interface{}, isReverse bool) { return } if !isReverse { - b.appendReqs(roachpb.NewScan(begin, end)) + b.appendReqs(roachpb.NewScan(begin, end, forUpdate)) } else { - b.appendReqs(roachpb.NewReverseScan(begin, end)) + b.appendReqs(roachpb.NewReverseScan(begin, end, forUpdate)) } b.initResult(1, 0, notRaw, nil) } @@ -547,7 +547,19 @@ func (b *Batch) scan(s, e interface{}, isReverse bool) { // // key can be either a byte slice or a string. func (b *Batch) Scan(s, e interface{}) { - b.scan(s, e, false) + b.scan(s, e, false /* isReverse */, false /* forUpdate */) +} + +// ScanForUpdate retrieves the key/values between begin (inclusive) and end +// (exclusive) in ascending order. Unreplicated, exclusive locks are acquired on +// each of the returned keys. +// +// A new result will be appended to the batch which will contain "rows" (each +// row is a key/value pair) and Result.Err will indicate success or failure. +// +// key can be either a byte slice or a string. +func (b *Batch) ScanForUpdate(s, e interface{}) { + b.scan(s, e, false /* isReverse */, true /* forUpdate */) } // ReverseScan retrieves the rows between begin (inclusive) and end (exclusive) @@ -558,7 +570,19 @@ func (b *Batch) Scan(s, e interface{}) { // // key can be either a byte slice or a string. func (b *Batch) ReverseScan(s, e interface{}) { - b.scan(s, e, true) + b.scan(s, e, true /* isReverse */, false /* forUpdate */) +} + +// ReverseScanForUpdate retrieves the rows between begin (inclusive) and end +// (exclusive) in descending order. Unreplicated, exclusive locks are acquired +// on each of the returned keys. +// +// A new result will be appended to the batch which will contain "rows" (each +// "row" is a key/value pair) and Result.Err will indicate success or failure. +// +// key can be either a byte slice or a string. +func (b *Batch) ReverseScanForUpdate(s, e interface{}) { + b.scan(s, e, true /* isReverse */, true /* forUpdate */) } // Del deletes one or more keys. diff --git a/pkg/internal/client/db.go b/pkg/internal/client/db.go index 00e8a9007a21..6e1a7f42b0a4 100644 --- a/pkg/internal/client/db.go +++ b/pkg/internal/client/db.go @@ -416,6 +416,7 @@ func (db *DB) scan( begin, end interface{}, maxRows int64, isReverse bool, + forUpdate bool, readConsistency roachpb.ReadConsistencyType, ) ([]KeyValue, error) { b := &Batch{} @@ -423,11 +424,7 @@ func (db *DB) scan( if maxRows > 0 { b.Header.MaxSpanRequestKeys = maxRows } - if !isReverse { - b.Scan(begin, end) - } else { - b.ReverseScan(begin, end) - } + b.scan(begin, end, isReverse, forUpdate) r, err := getOneResult(db.Run(ctx, b), b) return r.Rows, err } @@ -439,7 +436,20 @@ func (db *DB) scan( // // key can be either a byte slice or a string. func (db *DB) Scan(ctx context.Context, begin, end interface{}, maxRows int64) ([]KeyValue, error) { - return db.scan(ctx, begin, end, maxRows, false, roachpb.CONSISTENT) + return db.scan(ctx, begin, end, maxRows, false /* isReverse */, false /* forUpdate */, roachpb.CONSISTENT) +} + +// ScanForUpdate retrieves the rows between begin (inclusive) and end +// (exclusive) in ascending order. Unreplicated, exclusive locks are +// acquired on each of the returned keys. +// +// The returned []KeyValue will contain up to maxRows elements. +// +// key can be either a byte slice or a string. +func (db *DB) ScanForUpdate( + ctx context.Context, begin, end interface{}, maxRows int64, +) ([]KeyValue, error) { + return db.scan(ctx, begin, end, maxRows, false /* isReverse */, true /* forUpdate */, roachpb.CONSISTENT) } // ReverseScan retrieves the rows between begin (inclusive) and end (exclusive) @@ -451,7 +461,20 @@ func (db *DB) Scan(ctx context.Context, begin, end interface{}, maxRows int64) ( func (db *DB) ReverseScan( ctx context.Context, begin, end interface{}, maxRows int64, ) ([]KeyValue, error) { - return db.scan(ctx, begin, end, maxRows, true, roachpb.CONSISTENT) + return db.scan(ctx, begin, end, maxRows, true /* isReverse */, false /* forUpdate */, roachpb.CONSISTENT) +} + +// ReverseScanForUpdate retrieves the rows between begin (inclusive) and end +// (exclusive) in descending order. Unreplicated, exclusive locks are acquired +// on each of the returned keys. +// +// The returned []KeyValue will contain up to maxRows elements. +// +// key can be either a byte slice or a string. +func (db *DB) ReverseScanForUpdate( + ctx context.Context, begin, end interface{}, maxRows int64, +) ([]KeyValue, error) { + return db.scan(ctx, begin, end, maxRows, true /* isReverse */, true /* forUpdate */, roachpb.CONSISTENT) } // Del deletes one or more keys. diff --git a/pkg/internal/client/db_test.go b/pkg/internal/client/db_test.go index 21556eb17bd9..03a60d69148e 100644 --- a/pkg/internal/client/db_test.go +++ b/pkg/internal/client/db_test.go @@ -237,6 +237,31 @@ func TestDB_Scan(t *testing.T) { checkLen(t, len(expected), len(rows)) } +func TestDB_ScanForUpdate(t *testing.T) { + defer leaktest.AfterTest(t)() + s, db := setup(t) + defer s.Stopper().Stop(context.TODO()) + + b := &client.Batch{} + b.Put("aa", "1") + b.Put("ab", "2") + b.Put("bb", "3") + if err := db.Run(context.TODO(), b); err != nil { + t.Fatal(err) + } + rows, err := db.ScanForUpdate(context.TODO(), "a", "b", 100) + if err != nil { + t.Fatal(err) + } + expected := map[string][]byte{ + "aa": []byte("1"), + "ab": []byte("2"), + } + + checkRows(t, expected, rows) + checkLen(t, len(expected), len(rows)) +} + func TestDB_ReverseScan(t *testing.T) { defer leaktest.AfterTest(t)() s, db := setup(t) @@ -262,6 +287,31 @@ func TestDB_ReverseScan(t *testing.T) { checkLen(t, len(expected), len(rows)) } +func TestDB_ReverseScanForUpdate(t *testing.T) { + defer leaktest.AfterTest(t)() + s, db := setup(t) + defer s.Stopper().Stop(context.TODO()) + + b := &client.Batch{} + b.Put("aa", "1") + b.Put("ab", "2") + b.Put("bb", "3") + if err := db.Run(context.TODO(), b); err != nil { + t.Fatal(err) + } + rows, err := db.ReverseScanForUpdate(context.TODO(), "ab", "c", 100) + if err != nil { + t.Fatal(err) + } + expected := map[string][]byte{ + "bb": []byte("3"), + "ab": []byte("2"), + } + + checkRows(t, expected, rows) + checkLen(t, len(expected), len(rows)) +} + func TestDB_TxnIterate(t *testing.T) { defer leaktest.AfterTest(t)() s, db := setup(t) diff --git a/pkg/internal/client/txn.go b/pkg/internal/client/txn.go index f62a229e6e5c..488092ee58be 100644 --- a/pkg/internal/client/txn.go +++ b/pkg/internal/client/txn.go @@ -431,17 +431,13 @@ func (txn *Txn) Inc(ctx context.Context, key interface{}, value int64) (KeyValue } func (txn *Txn) scan( - ctx context.Context, begin, end interface{}, maxRows int64, isReverse bool, + ctx context.Context, begin, end interface{}, maxRows int64, isReverse, forUpdate bool, ) ([]KeyValue, error) { b := txn.NewBatch() if maxRows > 0 { b.Header.MaxSpanRequestKeys = maxRows } - if !isReverse { - b.Scan(begin, end) - } else { - b.ReverseScan(begin, end) - } + b.scan(begin, end, isReverse, forUpdate) r, err := getOneResult(txn.Run(ctx, b), b) return r.Rows, err } @@ -456,7 +452,21 @@ func (txn *Txn) scan( func (txn *Txn) Scan( ctx context.Context, begin, end interface{}, maxRows int64, ) ([]KeyValue, error) { - return txn.scan(ctx, begin, end, maxRows, false) + return txn.scan(ctx, begin, end, maxRows, false /* isReverse */, false /* forUpdate */) +} + +// ScanForUpdate retrieves the rows between begin (inclusive) and end +// (exclusive) in ascending order. Unreplicated, exclusive locks are acquired on +// each of the returned keys. +// +// The returned []KeyValue will contain up to maxRows elements (or all results +// when zero is supplied). +// +// key can be either a byte slice or a string. +func (txn *Txn) ScanForUpdate( + ctx context.Context, begin, end interface{}, maxRows int64, +) ([]KeyValue, error) { + return txn.scan(ctx, begin, end, maxRows, false /* isReverse */, true /* forUpdate */) } // ReverseScan retrieves the rows between begin (inclusive) and end (exclusive) @@ -469,7 +479,21 @@ func (txn *Txn) Scan( func (txn *Txn) ReverseScan( ctx context.Context, begin, end interface{}, maxRows int64, ) ([]KeyValue, error) { - return txn.scan(ctx, begin, end, maxRows, true) + return txn.scan(ctx, begin, end, maxRows, true /* isReverse */, false /* forUpdate */) +} + +// ReverseScanForUpdate retrieves the rows between begin (inclusive) and end +// (exclusive) in descending order. Unreplicated, exclusive locks are acquired +// on each of the returned keys. +// +// The returned []KeyValue will contain up to maxRows elements (or all results +// when zero is supplied). +// +// key can be either a byte slice or a string. +func (txn *Txn) ReverseScanForUpdate( + ctx context.Context, begin, end interface{}, maxRows int64, +) ([]KeyValue, error) { + return txn.scan(ctx, begin, end, maxRows, true /* isReverse */, true /* forUpdate */) } // Iterate performs a paginated scan and applying the function f to every page. diff --git a/pkg/kv/dist_sender_server_test.go b/pkg/kv/dist_sender_server_test.go index 3a036f6fdc0a..71602ea78d72 100644 --- a/pkg/kv/dist_sender_server_test.go +++ b/pkg/kv/dist_sender_server_test.go @@ -952,8 +952,8 @@ func TestMultiRangeScanReverseScanInconsistent(t *testing.T) { // OpRequiresTxnError. We set the local clock to the timestamp of // just above the first key to verify it's used to read only key "a". for i, request := range []roachpb.Request{ - roachpb.NewScan(roachpb.Key("a"), roachpb.Key("c")), - roachpb.NewReverseScan(roachpb.Key("a"), roachpb.Key("c")), + roachpb.NewScan(roachpb.Key("a"), roachpb.Key("c"), false), + roachpb.NewReverseScan(roachpb.Key("a"), roachpb.Key("c"), false), } { manual := hlc.NewManualClock(ts[0].WallTime + 1) clock := hlc.NewClock(manual.UnixNano, time.Nanosecond) diff --git a/pkg/kv/dist_sender_test.go b/pkg/kv/dist_sender_test.go index 9ca659f610d5..f9af053fc309 100644 --- a/pkg/kv/dist_sender_test.go +++ b/pkg/kv/dist_sender_test.go @@ -1184,7 +1184,7 @@ func TestRetryOnWrongReplicaError(t *testing.T) { Settings: cluster.MakeTestingClusterSettings(), } ds := NewDistSender(cfg, g) - scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("d")) + scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("d"), false) if _, err := client.SendWrapped(context.Background(), ds, scan); err != nil { t.Errorf("scan encountered error: %s", err) } @@ -1280,7 +1280,7 @@ func TestRetryOnWrongReplicaErrorWithSuggestion(t *testing.T) { Settings: cluster.MakeTestingClusterSettings(), } ds := NewDistSender(cfg, g) - scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("d")) + scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("d"), false) if _, err := client.SendWrapped(context.Background(), ds, scan); err != nil { t.Errorf("scan encountered error: %s", err) } @@ -1398,7 +1398,7 @@ func TestSendRPCRetry(t *testing.T) { Settings: cluster.MakeTestingClusterSettings(), } ds := NewDistSender(cfg, g) - scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("d")) + scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("d"), false) sr, err := client.SendWrappedWith(context.Background(), ds, roachpb.Header{MaxSpanRequestKeys: 1}, scan) if err != nil { t.Fatal(err) @@ -1601,8 +1601,8 @@ func TestMultiRangeGapReverse(t *testing.T) { var ba roachpb.BatchRequest ba.Txn = &txn - ba.Add(roachpb.NewReverseScan(splits[0], splits[1])) - ba.Add(roachpb.NewReverseScan(splits[2], splits[3])) + ba.Add(roachpb.NewReverseScan(splits[0], splits[1], false)) + ba.Add(roachpb.NewReverseScan(splits[2], splits[3], false)) // Before fixing https://github.com/cockroachdb/cockroach/issues/18174, this // would error with: @@ -1705,7 +1705,7 @@ func TestMultiRangeMergeStaleDescriptor(t *testing.T) { Settings: cluster.MakeTestingClusterSettings(), } ds := NewDistSender(cfg, g) - scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("d")) + scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("d"), false) // Set the Txn info to avoid an OpRequiresTxnError. reply, err := client.SendWrappedWith(context.Background(), ds, roachpb.Header{ MaxSpanRequestKeys: 10, @@ -2050,7 +2050,10 @@ func TestTruncateWithLocalSpanAndDescriptor(t *testing.T) { // only the scan on local keys that address from "b" to "d". ba := roachpb.BatchRequest{} ba.Txn = &roachpb.Transaction{Name: "test"} - ba.Add(roachpb.NewScan(keys.RangeDescriptorKey(roachpb.RKey("a")), keys.RangeDescriptorKey(roachpb.RKey("c")))) + ba.Add(roachpb.NewScan( + keys.RangeDescriptorKey(roachpb.RKey("a")), + keys.RangeDescriptorKey(roachpb.RKey("c")), + false /* forUpdate */)) if _, pErr := ds.Send(context.Background(), ba); pErr != nil { t.Fatal(pErr) @@ -3219,7 +3222,7 @@ func TestEvictMetaRange(t *testing.T) { } ds := NewDistSender(cfg, g) - scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("b")) + scan := roachpb.NewScan(roachpb.Key("a"), roachpb.Key("b"), false) if _, pErr := client.SendWrapped(context.Background(), ds, scan); pErr != nil { t.Fatalf("scan encountered error: %s", pErr) } @@ -3235,7 +3238,7 @@ func TestEvictMetaRange(t *testing.T) { // Simulate a split on the meta2 range and mark it as stale. isStale = true - scan = roachpb.NewScan(roachpb.Key("b"), roachpb.Key("c")) + scan = roachpb.NewScan(roachpb.Key("b"), roachpb.Key("c"), false) if _, pErr := client.SendWrapped(context.Background(), ds, scan); pErr != nil { t.Fatalf("scan encountered error: %s", pErr) } diff --git a/pkg/kv/kvserver/batch_spanset_test.go b/pkg/kv/kvserver/batch_spanset_test.go index ce3dd59121a5..5c254bd14346 100644 --- a/pkg/kv/kvserver/batch_spanset_test.go +++ b/pkg/kv/kvserver/batch_spanset_test.go @@ -16,7 +16,6 @@ import ( "reflect" "testing" - "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" "github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage" @@ -545,10 +544,9 @@ func TestSpanSetMVCCResolveWriteIntentRangeUsingIter(t *testing.T) { defer batch.Close() intent := roachpb.LockUpdate{ - Span: roachpb.Span{Key: roachpb.Key("a"), EndKey: roachpb.Key("b\x00")}, - Txn: enginepb.TxnMeta{}, // unused - Status: roachpb.PENDING, - Durability: lock.Replicated, + Span: roachpb.Span{Key: roachpb.Key("a"), EndKey: roachpb.Key("b\x00")}, + Txn: enginepb.TxnMeta{}, // unused + Status: roachpb.PENDING, } iterAndBuf := storage.GetIterAndBuf(batch, storage.IterOptions{UpperBound: intent.Span.EndKey}) diff --git a/pkg/kv/kvserver/batcheval/cmd_reverse_scan.go b/pkg/kv/kvserver/batcheval/cmd_reverse_scan.go index 23712144dea3..5edc2b2c698b 100644 --- a/pkg/kv/kvserver/batcheval/cmd_reverse_scan.go +++ b/pkg/kv/kvserver/batcheval/cmd_reverse_scan.go @@ -15,6 +15,7 @@ import ( "fmt" "github.com/cockroachdb/cockroach/pkg/kv/kvserver/batcheval/result" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage" ) @@ -34,46 +35,59 @@ func ReverseScan( h := cArgs.Header reply := resp.(*roachpb.ReverseScanResponse) - var res storage.MVCCScanResult + var res result.Result + var scanRes storage.MVCCScanResult var err error opts := storage.MVCCScanOptions{ - Inconsistent: h.ReadConsistency != roachpb.CONSISTENT, - Txn: h.Txn, - MaxKeys: h.MaxSpanRequestKeys, - TargetBytes: h.TargetBytes, - Reverse: true, + Inconsistent: h.ReadConsistency != roachpb.CONSISTENT, + Txn: h.Txn, + MaxKeys: h.MaxSpanRequestKeys, + TargetBytes: h.TargetBytes, + FailOnMoreRecent: args.KeyLocking != lock.None, + Reverse: true, } switch args.ScanFormat { case roachpb.BATCH_RESPONSE: - res, err = storage.MVCCScanToBytes( + scanRes, err = storage.MVCCScanToBytes( ctx, reader, args.Key, args.EndKey, h.Timestamp, opts) if err != nil { return result.Result{}, err } - reply.BatchResponses = res.KVData + reply.BatchResponses = scanRes.KVData case roachpb.KEY_VALUES: - res, err = storage.MVCCScan( + scanRes, err = storage.MVCCScan( ctx, reader, args.Key, args.EndKey, h.Timestamp, opts) if err != nil { return result.Result{}, err } - reply.Rows = res.KVs + reply.Rows = scanRes.KVs default: panic(fmt.Sprintf("Unknown scanFormat %d", args.ScanFormat)) } - reply.NumKeys = res.NumKeys - reply.NumBytes = res.NumBytes + reply.NumKeys = scanRes.NumKeys + reply.NumBytes = scanRes.NumBytes - if res.ResumeSpan != nil { - reply.ResumeSpan = res.ResumeSpan + if scanRes.ResumeSpan != nil { + reply.ResumeSpan = scanRes.ResumeSpan reply.ResumeReason = roachpb.RESUME_KEY_LIMIT } if h.ReadConsistency == roachpb.READ_UNCOMMITTED { - reply.IntentRows, err = CollectIntentRows(ctx, reader, cArgs, res.Intents) + reply.IntentRows, err = CollectIntentRows(ctx, reader, cArgs, scanRes.Intents) + if err != nil { + return result.Result{}, err + } + } + + if args.KeyLocking != lock.None && h.Txn != nil { + err = acquireUnreplicatedLocksOnKeys(&res, h.Txn, args.ScanFormat, &scanRes) + if err != nil { + return result.Result{}, err + } } - return result.FromEncounteredIntents(res.Intents), err + res.Local.EncounteredIntents = scanRes.Intents + return res, nil } diff --git a/pkg/kv/kvserver/batcheval/cmd_scan.go b/pkg/kv/kvserver/batcheval/cmd_scan.go index 17b6e45b0193..fd10986f6d07 100644 --- a/pkg/kv/kvserver/batcheval/cmd_scan.go +++ b/pkg/kv/kvserver/batcheval/cmd_scan.go @@ -15,6 +15,7 @@ import ( "fmt" "github.com/cockroachdb/cockroach/pkg/kv/kvserver/batcheval/result" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage" ) @@ -34,46 +35,59 @@ func Scan( h := cArgs.Header reply := resp.(*roachpb.ScanResponse) - var res storage.MVCCScanResult + var res result.Result + var scanRes storage.MVCCScanResult var err error opts := storage.MVCCScanOptions{ - Inconsistent: h.ReadConsistency != roachpb.CONSISTENT, - Txn: h.Txn, - MaxKeys: h.MaxSpanRequestKeys, - TargetBytes: h.TargetBytes, - Reverse: false, + Inconsistent: h.ReadConsistency != roachpb.CONSISTENT, + Txn: h.Txn, + MaxKeys: h.MaxSpanRequestKeys, + TargetBytes: h.TargetBytes, + FailOnMoreRecent: args.KeyLocking != lock.None, + Reverse: false, } switch args.ScanFormat { case roachpb.BATCH_RESPONSE: - res, err = storage.MVCCScanToBytes( + scanRes, err = storage.MVCCScanToBytes( ctx, reader, args.Key, args.EndKey, h.Timestamp, opts) if err != nil { return result.Result{}, err } - reply.BatchResponses = res.KVData + reply.BatchResponses = scanRes.KVData case roachpb.KEY_VALUES: - res, err = storage.MVCCScan( + scanRes, err = storage.MVCCScan( ctx, reader, args.Key, args.EndKey, h.Timestamp, opts) if err != nil { return result.Result{}, err } - reply.Rows = res.KVs + reply.Rows = scanRes.KVs default: panic(fmt.Sprintf("Unknown scanFormat %d", args.ScanFormat)) } - reply.NumKeys = res.NumKeys - reply.NumBytes = res.NumBytes + reply.NumKeys = scanRes.NumKeys + reply.NumBytes = scanRes.NumBytes - if res.ResumeSpan != nil { - reply.ResumeSpan = res.ResumeSpan + if scanRes.ResumeSpan != nil { + reply.ResumeSpan = scanRes.ResumeSpan reply.ResumeReason = roachpb.RESUME_KEY_LIMIT } if h.ReadConsistency == roachpb.READ_UNCOMMITTED { - reply.IntentRows, err = CollectIntentRows(ctx, reader, cArgs, res.Intents) + reply.IntentRows, err = CollectIntentRows(ctx, reader, cArgs, scanRes.Intents) + if err != nil { + return result.Result{}, err + } + } + + if args.KeyLocking != lock.None && h.Txn != nil { + err = acquireUnreplicatedLocksOnKeys(&res, h.Txn, args.ScanFormat, &scanRes) + if err != nil { + return result.Result{}, err + } } - return result.FromEncounteredIntents(res.Intents), err + res.Local.EncounteredIntents = scanRes.Intents + return res, nil } diff --git a/pkg/kv/kvserver/batcheval/intent.go b/pkg/kv/kvserver/batcheval/intent.go index 34508bbe81ad..418ac41f444e 100644 --- a/pkg/kv/kvserver/batcheval/intent.go +++ b/pkg/kv/kvserver/batcheval/intent.go @@ -13,6 +13,8 @@ package batcheval import ( "context" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/batcheval/result" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage" ) @@ -49,3 +51,41 @@ func CollectIntentRows( } return res, nil } + +// acquireUnreplicatedLocksOnKeys adds an unreplicated lock acquisition by the +// transaction to the provided result.Result for each key in the scan result. +func acquireUnreplicatedLocksOnKeys( + res *result.Result, + txn *roachpb.Transaction, + scanFmt roachpb.ScanFormat, + scanRes *storage.MVCCScanResult, +) error { + switch scanFmt { + case roachpb.BATCH_RESPONSE: + res.Local.AcquiredLocks = make([]roachpb.LockUpdate, scanRes.NumKeys) + var i int + return storage.MVCCScanDecodeKeyValues(scanRes.KVData, func(key storage.MVCCKey, _ []byte) error { + res.Local.AcquiredLocks[i] = roachpb.LockUpdate{ + Span: roachpb.Span{Key: key.Key}, + Txn: txn.TxnMeta, + Status: roachpb.PENDING, + Durability: lock.Unreplicated, + } + i++ + return nil + }) + case roachpb.KEY_VALUES: + res.Local.AcquiredLocks = make([]roachpb.LockUpdate, scanRes.NumKeys) + for i, row := range scanRes.KVs { + res.Local.AcquiredLocks[i] = roachpb.LockUpdate{ + Span: roachpb.Span{Key: row.Key}, + Txn: txn.TxnMeta, + Status: roachpb.PENDING, + Durability: lock.Unreplicated, + } + } + return nil + default: + panic("unexpected scanFormat") + } +} diff --git a/pkg/kv/kvserver/concurrency/concurrency_control.go b/pkg/kv/kvserver/concurrency/concurrency_control.go index 9b50a7d53782..e836288ffc22 100644 --- a/pkg/kv/kvserver/concurrency/concurrency_control.go +++ b/pkg/kv/kvserver/concurrency/concurrency_control.go @@ -234,6 +234,7 @@ type LockManager interface { // OnLockUpdated informs the concurrency manager that a transaction has // updated or released a lock or range of locks that it previously held. + // The Durability field of the lock update struct is ignored. OnLockUpdated(context.Context, *roachpb.LockUpdate) } @@ -495,7 +496,9 @@ type lockTable interface { // // The method is called during intent resolution. For spans containing // Replicated locks, this must be called after intent resolution has been - // applied to the replicated state machine. + // applied to the replicated state machine. The method itself, however, + // ignores the Durability field in the LockUpdate. It can therefore be + // used to update locks for a given transaction for all durability levels. // // A latch with SpanReadWrite must be held on span with the lowest timestamp // at which any of the locks could be held. This is explained below. diff --git a/pkg/kv/kvserver/replica_evaluate_test.go b/pkg/kv/kvserver/replica_evaluate_test.go index de898403c3a2..eae653c00e9c 100644 --- a/pkg/kv/kvserver/replica_evaluate_test.go +++ b/pkg/kv/kvserver/replica_evaluate_test.go @@ -15,8 +15,10 @@ import ( "fmt" "testing" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/abortspan" "github.com/cockroachdb/cockroach/pkg/kv/kvserver/batcheval" "github.com/cockroachdb/cockroach/pkg/kv/kvserver/batcheval/result" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" "github.com/cockroachdb/cockroach/pkg/kv/kvserver/storagebase" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage" @@ -29,6 +31,9 @@ import ( func TestEvaluateBatch(t *testing.T) { defer leaktest.AfterTest(t)() + ts := hlc.Timestamp{WallTime: 1} + txn := roachpb.MakeTransaction("test", roachpb.Key("a"), 0, ts, 0) + tcs := []testCase{ // // Test suite for MaxRequestSpans. @@ -244,6 +249,97 @@ func TestEvaluateBatch(t *testing.T) { require.Equal(t, "value-e", string(b)) }, }, + // + // Test suite for KeyLocking. + // + { + // Three scans that observe 3, 1, and 0 keys, respectively. An + // unreplicated lock should be acquired on each key that is scanned. + name: "scan with key locking", + setup: func(t *testing.T, d *data) { + writeABCDEF(t, d) + d.ba.Txn = &txn + scanAD := scanArgsString("a", "d") + scanAD.KeyLocking = lock.Exclusive + d.ba.Add(scanAD) + scanEF := scanArgsString("e", "f") + scanEF.KeyLocking = lock.Exclusive + d.ba.Add(scanEF) + scanHJ := scanArgsString("h", "j") + scanHJ.KeyLocking = lock.Exclusive + d.ba.Add(scanHJ) + }, + check: func(t *testing.T, r resp) { + verifyScanResult(t, r, []string{"a", "b", "c"}, []string{"e"}, nil) + verifyAcquiredLocks(t, r, lock.Unreplicated, "a", "b", "c", "e") + verifyAcquiredLocks(t, r, lock.Replicated, []string(nil)...) + }, + }, + { + // Ditto in reverse. + name: "reverse scan with key locking", + setup: func(t *testing.T, d *data) { + writeABCDEF(t, d) + d.ba.Txn = &txn + scanAD := revScanArgsString("a", "d") + scanAD.KeyLocking = lock.Exclusive + d.ba.Add(scanAD) + scanEF := revScanArgsString("e", "f") + scanEF.KeyLocking = lock.Exclusive + d.ba.Add(scanEF) + scanHJ := revScanArgsString("h", "j") + scanHJ.KeyLocking = lock.Exclusive + d.ba.Add(scanHJ) + }, + check: func(t *testing.T, r resp) { + verifyScanResult(t, r, []string{"c", "b", "a"}, []string{"e"}, nil) + verifyAcquiredLocks(t, r, lock.Unreplicated, "c", "b", "a", "e") + verifyAcquiredLocks(t, r, lock.Replicated, []string(nil)...) + }, + }, + { + // Three scans that observe 3, 1, and 0 keys, respectively. No + // transaction set, so no locks should be acquired. + name: "scan with key locking without txn", + setup: func(t *testing.T, d *data) { + writeABCDEF(t, d) + scanAD := scanArgsString("a", "d") + scanAD.KeyLocking = lock.Exclusive + d.ba.Add(scanAD) + scanEF := scanArgsString("e", "f") + scanEF.KeyLocking = lock.Exclusive + d.ba.Add(scanEF) + scanHJ := scanArgsString("h", "j") + scanHJ.KeyLocking = lock.Exclusive + d.ba.Add(scanHJ) + }, + check: func(t *testing.T, r resp) { + verifyScanResult(t, r, []string{"a", "b", "c"}, []string{"e"}, nil) + verifyAcquiredLocks(t, r, lock.Unreplicated, []string(nil)...) + verifyAcquiredLocks(t, r, lock.Replicated, []string(nil)...) + }, + }, + { + // Ditto in reverse. + name: "reverse scan with key locking without txn", + setup: func(t *testing.T, d *data) { + writeABCDEF(t, d) + scanAD := revScanArgsString("a", "d") + scanAD.KeyLocking = lock.Exclusive + d.ba.Add(scanAD) + scanEF := revScanArgsString("e", "f") + scanEF.KeyLocking = lock.Exclusive + d.ba.Add(scanEF) + scanHJ := revScanArgsString("h", "j") + scanHJ.KeyLocking = lock.Exclusive + d.ba.Add(scanHJ) + }, + check: func(t *testing.T, r resp) { + verifyScanResult(t, r, []string{"c", "b", "a"}, []string{"e"}, nil) + verifyAcquiredLocks(t, r, lock.Unreplicated, []string(nil)...) + verifyAcquiredLocks(t, r, lock.Replicated, []string(nil)...) + }, + }, } for _, tc := range tcs { @@ -256,7 +352,8 @@ func TestEvaluateBatch(t *testing.T) { idKey: storagebase.CmdIDKey("testing"), eng: eng, } - d.ba.Header.Timestamp = hlc.Timestamp{WallTime: 1} + d.AbortSpan = abortspan.New(1) + d.ba.Header.Timestamp = ts tc.setup(t, d) @@ -355,3 +452,13 @@ func verifyResumeSpans(t *testing.T, r resp, resumeSpans ...string) { require.Equal(t, span, act, "#%d", i+1) } } + +func verifyAcquiredLocks(t *testing.T, r resp, dur lock.Durability, lockedKeys ...string) { + var foundLocked []string + for _, l := range r.res.Local.AcquiredLocks { + if l.Durability == dur { + foundLocked = append(foundLocked, string(l.Key)) + } + } + require.Equal(t, lockedKeys, foundLocked) +} diff --git a/pkg/kv/kvserver/replica_test.go b/pkg/kv/kvserver/replica_test.go index c640360f9c86..fddcb8aac7da 100644 --- a/pkg/kv/kvserver/replica_test.go +++ b/pkg/kv/kvserver/replica_test.go @@ -10034,6 +10034,86 @@ func TestReplicaPushed1PC(t *testing.T) { } } +// TestReplicaNotifyLockTableOn1PC verifies that a 1-phase commit transaction +// notifies the concurrency manager's lock-table that the transaction has been +// committed. This is necessary even though the transaction, by virtue of +// performing a 1PC commit, could not have written any intents. It still could +// have acquired read locks. +func TestReplicaNotifyLockTableOn1PC(t *testing.T) { + defer leaktest.AfterTest(t)() + + ctx := context.Background() + tc := testContext{} + stopper := stop.NewStopper() + defer stopper.Stop(ctx) + tc.Start(t, stopper) + + // Disable txn liveness pushes. See below for why. + st := tc.store.cfg.Settings + st.Manual.Store(true) + concurrency.LockTableLivenessPushDelay.Override(&st.SV, 24*time.Hour) + + // Write a value to a key A. + key := roachpb.Key("a") + initVal := incrementArgs(key, 1) + if _, pErr := tc.SendWrapped(initVal); pErr != nil { + t.Fatalf("unexpected error: %s", pErr) + } + + // Create a new transaction and perform a "for update" scan. This should + // acquire unreplicated, exclusive locks on the key. + txn := newTransaction("test", key, 1, tc.Clock()) + var ba roachpb.BatchRequest + ba.Header = roachpb.Header{Txn: txn} + ba.Add(roachpb.NewScan(key, key.Next(), true /* forUpdate */)) + if _, pErr := tc.Sender().Send(ctx, ba); pErr != nil { + t.Fatalf("unexpected error: %s", pErr) + } + + // Try to write to the key outside of this transaction. Should wait on the + // "for update" lock in a lock wait-queue in the concurrency manager until + // the lock is released. If we don't notify the lock-table when the first + // txn eventually commits, this will wait for much longer than it needs to. + // It will eventually push the first txn and notice that it has committed. + // However, we've disabled liveness pushes in this test, so the test will + // block forever without the lock-table notification. We didn't need to + // disable deadlock detection pushes because this is a non-transactional + // write, so it never performs them. + pErrC := make(chan *roachpb.Error, 1) + go func() { + otherWrite := incrementArgs(key, 1) + _, pErr := tc.SendWrapped(otherWrite) + pErrC <- pErr + }() + + // The second write should not complete. + select { + case pErr := <-pErrC: + t.Fatalf("write unexpectedly finished with error: %v", pErr) + case <-time.After(5 * time.Millisecond): + } + + // Update the locked value and commit in a single batch. This should release + // the "for update" lock. + ba = roachpb.BatchRequest{} + incArgs := incrementArgs(key, 1) + et, etH := endTxnArgs(txn, true /* commit */) + et.Require1PC = true + et.LockSpans = []roachpb.Span{{Key: key, EndKey: key.Next()}} + ba.Header = etH + ba.Add(incArgs, &et) + assignSeqNumsForReqs(txn, incArgs, &et) + if _, pErr := tc.Sender().Send(ctx, ba); pErr != nil { + t.Fatalf("unexpected error: %s", pErr) + } + + // The second write should complete. + pErr := <-pErrC + if pErr != nil { + t.Fatalf("unexpected error: %s", pErr) + } +} + func TestReplicaShouldCampaignOnWake(t *testing.T) { defer leaktest.AfterTest(t)() diff --git a/pkg/kv/kvserver/replica_write.go b/pkg/kv/kvserver/replica_write.go index 1b6e20c2e8cc..ac17be8d1cc8 100644 --- a/pkg/kv/kvserver/replica_write.go +++ b/pkg/kv/kvserver/replica_write.go @@ -461,18 +461,15 @@ func (r *Replica) evaluate1PC( // it is finalized and than any unreplicated locks that it has acquired can // be released. res.Local.UpdatedTxns = []*roachpb.Transaction{clonedTxn} - // TODO(nvanbenschoten): do something like the following once unreplicated - // lock spans are added to EndTxn request. - // res.Local.ResolvedLocks = make([]roachpb.LockUpdate, len(etArg.LockSpans)) - // for i, sp := range etArg.LockSpans { - // res.Local.ResolvedLocks[i] = roachpb.LockUpdate{ - // Span: sp, - // Txn: clonedTxn.TxnMeta, - // Status: clonedTxn.Status, - // IgnoredSeqNums: clonedTxn.IgnoredSeqNums, - // Durability: lock.Unreplicated, - // } - // } + res.Local.ResolvedLocks = make([]roachpb.LockUpdate, len(etArg.LockSpans)) + for i, sp := range etArg.LockSpans { + res.Local.ResolvedLocks[i] = roachpb.LockUpdate{ + Span: sp, + Txn: clonedTxn.TxnMeta, + Status: clonedTxn.Status, + IgnoredSeqNums: clonedTxn.IgnoredSeqNums, + } + } // Add placeholder responses for end transaction requests. br.Add(&roachpb.EndTxnResponse{OnePhaseCommit: true}) diff --git a/pkg/kv/txn_coord_sender.go b/pkg/kv/txn_coord_sender.go index 0e19d99b311e..7f9753fdba62 100644 --- a/pkg/kv/txn_coord_sender.go +++ b/pkg/kv/txn_coord_sender.go @@ -452,7 +452,7 @@ func (tc *TxnCoordSender) Send( return nil, pErr } - if ba.IsSingleEndTxnRequest() && !tc.interceptorAlloc.txnPipeliner.haveWrites() { + if ba.IsSingleEndTxnRequest() && !tc.interceptorAlloc.txnPipeliner.hasAcquiredLocks() { return nil, tc.commitReadOnlyTxnLocked(ctx, ba) } diff --git a/pkg/kv/txn_coord_sender_test.go b/pkg/kv/txn_coord_sender_test.go index 6bdf52ab28aa..cdf64a09af5a 100644 --- a/pkg/kv/txn_coord_sender_test.go +++ b/pkg/kv/txn_coord_sender_test.go @@ -121,7 +121,7 @@ func TestTxnCoordSenderKeyRanges(t *testing.T) { txn := client.NewTxn(ctx, s.DB, 0 /* gatewayNodeID */) // Disable txn pipelining so that all write spans are immediately - // added to the transaction's write footprint. + // added to the transaction's lock footprint. if err := txn.DisablePipelining(); err != nil { t.Fatal(err) } @@ -164,21 +164,21 @@ func TestTxnCoordSenderCondenseLockSpans(t *testing.T) { g0Tog1 := roachpb.Span{Key: roachpb.Key("g0"), EndKey: roachpb.Key("g1")} fTog1Closed := roachpb.Span{Key: roachpb.Key("f"), EndKey: roachpb.Key("g1")} testCases := []struct { - span roachpb.Span - expIntents []roachpb.Span - expIntentsSize int64 + span roachpb.Span + expLocks []roachpb.Span + expLocksSize int64 }{ - {span: a, expIntents: []roachpb.Span{a}, expIntentsSize: 1}, - {span: b, expIntents: []roachpb.Span{a, b}, expIntentsSize: 2}, - {span: c, expIntents: []roachpb.Span{a, b, c}, expIntentsSize: 3}, - {span: d, expIntents: []roachpb.Span{a, b, c, d}, expIntentsSize: 9}, + {span: a, expLocks: []roachpb.Span{a}, expLocksSize: 1}, + {span: b, expLocks: []roachpb.Span{a, b}, expLocksSize: 2}, + {span: c, expLocks: []roachpb.Span{a, b, c}, expLocksSize: 3}, + {span: d, expLocks: []roachpb.Span{a, b, c, d}, expLocksSize: 9}, // Note that c-e condenses and then lists first. - {span: e, expIntents: []roachpb.Span{cToEClosed, a, b}, expIntentsSize: 5}, - {span: fTof0, expIntents: []roachpb.Span{cToEClosed, a, b, fTof0}, expIntentsSize: 8}, - {span: g, expIntents: []roachpb.Span{cToEClosed, a, b, fTof0, g}, expIntentsSize: 9}, - {span: g0Tog1, expIntents: []roachpb.Span{fTog1Closed, cToEClosed, aToBClosed}, expIntentsSize: 9}, + {span: e, expLocks: []roachpb.Span{cToEClosed, a, b}, expLocksSize: 5}, + {span: fTof0, expLocks: []roachpb.Span{cToEClosed, a, b, fTof0}, expLocksSize: 8}, + {span: g, expLocks: []roachpb.Span{cToEClosed, a, b, fTof0, g}, expLocksSize: 9}, + {span: g0Tog1, expLocks: []roachpb.Span{fTog1Closed, cToEClosed, aToBClosed}, expLocksSize: 9}, // Add a key in the middle of a span, which will get merged on commit. - {span: c, expIntents: []roachpb.Span{aToBClosed, cToEClosed, fTog1Closed}, expIntentsSize: 9}, + {span: c, expLocks: []roachpb.Span{aToBClosed, cToEClosed, fTog1Closed}, expLocksSize: 9}, } splits := []roachpb.Span{ {Key: roachpb.Key("a"), EndKey: roachpb.Key("c")}, @@ -200,9 +200,9 @@ func TestTxnCoordSenderCondenseLockSpans(t *testing.T) { trackedWritesMaxSize.Override(&st.SV, 10) /* 10 bytes and it will condense */ defer s.Stop() - // Check end transaction intents, which should be condensed and split + // Check end transaction locks, which should be condensed and split // at range boundaries. - expIntents := []roachpb.Span{aToBClosed, cToEClosed, fTog1Closed} + expLocks := []roachpb.Span{aToBClosed, cToEClosed, fTog1Closed} var sendFn simpleSendFn = func( _ context.Context, _ SendOptions, _ ReplicaSlice, args roachpb.BatchRequest, ) (*roachpb.BatchResponse, error) { @@ -213,8 +213,8 @@ func TestTxnCoordSenderCondenseLockSpans(t *testing.T) { t.Errorf("expected commit to be true") } et := req.(*roachpb.EndTxnRequest) - if a, e := et.LockSpans, expIntents; !reflect.DeepEqual(a, e) { - t.Errorf("expected end transaction to have intents %+v; got %+v", e, a) + if a, e := et.LockSpans, expLocks; !reflect.DeepEqual(a, e) { + t.Errorf("expected end transaction to have locks %+v; got %+v", e, a) } resp.Txn.Status = roachpb.COMMITTED } @@ -248,7 +248,7 @@ func TestTxnCoordSenderCondenseLockSpans(t *testing.T) { txn := client.NewTxn(ctx, db, 0 /* gatewayNodeID */) // Disable txn pipelining so that all write spans are immediately - // added to the transaction's write footprint. + // added to the transaction's lock footprint. if err := txn.DisablePipelining(); err != nil { t.Fatal(err) } @@ -263,15 +263,15 @@ func TestTxnCoordSenderCondenseLockSpans(t *testing.T) { } } tcs := txn.Sender().(*TxnCoordSender) - intents := tcs.interceptorAlloc.txnPipeliner.footprint.asSlice() - if a, e := intents, tc.expIntents; !reflect.DeepEqual(a, e) { + locks := tcs.interceptorAlloc.txnPipeliner.footprint.asSlice() + if a, e := locks, tc.expLocks; !reflect.DeepEqual(a, e) { t.Errorf("%d: expected keys %+v; got %+v", i, e, a) } - intentsSize := int64(0) - for _, i := range intents { - intentsSize += int64(len(i.Key) + len(i.EndKey)) + locksSize := int64(0) + for _, i := range locks { + locksSize += int64(len(i.Key) + len(i.EndKey)) } - if a, e := intentsSize, tc.expIntentsSize; a != e { + if a, e := locksSize, tc.expLocksSize; a != e { t.Errorf("%d: keys size expected %d; got %d", i, e, a) } } @@ -430,8 +430,7 @@ func verifyCleanup(key roachpb.Key, eng storage.Engine, t *testing.T, coords ... } // TestTxnCoordSenderEndTxn verifies that ending a transaction -// sends resolve write intent requests and removes the transaction -// from the txns map. +// sends resolve write intent requests. func TestTxnCoordSenderEndTxn(t *testing.T) { defer leaktest.AfterTest(t)() s := createTestDB(t) @@ -516,9 +515,9 @@ func TestTxnCoordSenderEndTxn(t *testing.T) { } } -// TestTxnCoordSenderAddIntentOnError verifies that intents are tracked if -// the transaction is, even on error. -func TestTxnCoordSenderAddIntentOnError(t *testing.T) { +// TestTxnCoordSenderAddLockOnError verifies that locks are tracked if the +// transaction is, even on error. +func TestTxnCoordSenderAddLockOnError(t *testing.T) { defer leaktest.AfterTest(t)() s := createTestDB(t) defer s.Stop() @@ -548,7 +547,7 @@ func TestTxnCoordSenderAddIntentOnError(t *testing.T) { t.Fatal(err) } if !equal { - t.Fatalf("expected stored intents %v, got %v", expSpans, lockSpans) + t.Fatalf("expected stored locks %v, got %v", expSpans, lockSpans) } } @@ -610,7 +609,7 @@ func TestTxnCoordSenderCleanupOnAborted(t *testing.T) { } // TestTxnCoordSenderCleanupOnCommitAfterRestart verifies that if a txn restarts -// at a higher epoch and then commits before it has written anything in the new +// at a higher epoch and then commits before it has acquired any locks in the new // epoch, the coordinator still cleans up the transaction. In #40466, we saw that // this case could be detected as a 1PC transaction and the cleanup during the // commit could be omitted. @@ -638,7 +637,7 @@ func TestTxnCoordSenderCleanupOnCommitAfterRestart(t *testing.T) { } // TestTxnCoordSenderGCWithAmbiguousResultErr verifies that the coordinator -// cleans up extant transactions and intents after an ambiguous result error is +// cleans up extant transactions and locks after an ambiguous result error is // observed, even if the error is on the first request. func TestTxnCoordSenderGCWithAmbiguousResultErr(t *testing.T) { defer leaktest.AfterTest(t)() @@ -906,7 +905,7 @@ func TestTxnMultipleCoord(t *testing.T) { t.Fatal(err) } - // Verify presence of both intents. + // Verify presence of both locks. tcs := txn.Sender().(*TxnCoordSender) refreshSpans := tcs.interceptorAlloc.txnSpanRefresher.refreshSpans require.Equal(t, []roachpb.Span{{Key: key}, {Key: key2}}, refreshSpans) @@ -918,16 +917,17 @@ func TestTxnMultipleCoord(t *testing.T) { } } -// TestTxnCoordSenderNoDuplicateIntents verifies that TxnCoordSender does not -// generate duplicate intents and that it merges intents for overlapping ranges. -func TestTxnCoordSenderNoDuplicateIntents(t *testing.T) { +// TestTxnCoordSenderNoDuplicateLockSpans verifies that TxnCoordSender does not +// generate duplicate lock spans and that it merges lock spans that have +// overlapping ranges. +func TestTxnCoordSenderNoDuplicateLockSpans(t *testing.T) { defer leaktest.AfterTest(t)() ctx := context.Background() stopper := stop.NewStopper() manual := hlc.NewManualClock(123) clock := hlc.NewClock(manual.UnixNano, time.Nanosecond) - var expectedIntents []roachpb.Span + var expectedLockSpans []roachpb.Span var senderFn client.SenderFunc = func(_ context.Context, ba roachpb.BatchRequest) ( *roachpb.BatchResponse, *roachpb.Error) { @@ -935,8 +935,8 @@ func TestTxnCoordSenderNoDuplicateIntents(t *testing.T) { br.Txn = ba.Txn.Clone() if rArgs, ok := ba.GetArg(roachpb.EndTxn); ok { et := rArgs.(*roachpb.EndTxnRequest) - if !reflect.DeepEqual(et.LockSpans, expectedIntents) { - t.Errorf("Invalid intents: %+v; expected %+v", et.LockSpans, expectedIntents) + if !reflect.DeepEqual(et.LockSpans, expectedLockSpans) { + t.Errorf("Invalid lock spans: %+v; expected %+v", et.LockSpans, expectedLockSpans) } br.Txn.Status = roachpb.COMMITTED } @@ -958,13 +958,12 @@ func TestTxnCoordSenderNoDuplicateIntents(t *testing.T) { db := client.NewDB(ambient, factory, clock) txn := client.NewTxn(ctx, db, 0 /* gatewayNodeID */) - // Write to a, b, u-w before the final batch. - - pErr := txn.Put(ctx, roachpb.Key("a"), []byte("value")) + // Acquire locks on a-b, c, u-w before the final batch. + _, pErr := txn.ReverseScanForUpdate(ctx, roachpb.Key("a"), roachpb.Key("b"), 0) if pErr != nil { t.Fatal(pErr) } - pErr = txn.Put(ctx, roachpb.Key("b"), []byte("value")) + pErr = txn.Put(ctx, roachpb.Key("c"), []byte("value")) if pErr != nil { t.Fatal(pErr) } @@ -973,17 +972,18 @@ func TestTxnCoordSenderNoDuplicateIntents(t *testing.T) { t.Fatal(pErr) } - // The final batch overwrites key a and overlaps part of the u-w range. + // The final batch overwrites key c and overlaps part of the a-b and u-w ranges. b := txn.NewBatch() b.Put(roachpb.Key("b"), []byte("value")) b.Put(roachpb.Key("c"), []byte("value")) - b.DelRange(roachpb.Key("v"), roachpb.Key("z"), false) + b.Put(roachpb.Key("d"), []byte("value")) + b.ReverseScanForUpdate(roachpb.Key("v"), roachpb.Key("z")) - // The expected intents are a, b, c, and u-z. - expectedIntents = []roachpb.Span{ - {Key: roachpb.Key("a"), EndKey: nil}, - {Key: roachpb.Key("b"), EndKey: nil}, + // The expected locks are a-b, c, and u-z. + expectedLockSpans = []roachpb.Span{ + {Key: roachpb.Key("a"), EndKey: roachpb.Key("b").Next()}, {Key: roachpb.Key("c"), EndKey: nil}, + {Key: roachpb.Key("d"), EndKey: nil}, {Key: roachpb.Key("u"), EndKey: roachpb.Key("z")}, } @@ -1445,12 +1445,12 @@ func TestRollbackErrorStopsHeartbeat(t *testing.T) { }) } -// Test that intent tracking behaves correctly for transactions that attempt to +// Test that lock tracking behaves correctly for transactions that attempt to // run a batch containing an EndTxn. Since in case of an error it's not easy to -// determine whether any intents have been laid down (i.e. in case the batch was +// determine whether any locks have been laid down (i.e. in case the batch was // split by the DistSender and then there was mixed success for the sub-batches, // or in case a retriable error is returned), the test verifies that all -// possible intents are properly tracked and attached to a subsequent EndTxn. +// possible locks are properly tracked and attached to a subsequent EndTxn. func TestOnePCErrorTracking(t *testing.T) { defer leaktest.AfterTest(t)() ctx := context.Background() @@ -1470,7 +1470,7 @@ func TestOnePCErrorTracking(t *testing.T) { sender, ) db := client.NewDB(ambient, factory, clock) - var key = roachpb.Key("a") + keyA, keyB, keyC := roachpb.Key("a"), roachpb.Key("b"), roachpb.Key("c") // Register a matcher catching the commit attempt. sender.match(func(ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error) { @@ -1491,10 +1491,10 @@ func TestOnePCErrorTracking(t *testing.T) { if etReq.Commit { return nil, nil } - expIntents := []roachpb.Span{{Key: key}} - intents := etReq.LockSpans - if !reflect.DeepEqual(intents, expIntents) { - return nil, roachpb.NewErrorf("expected intents %s, got: %s", expIntents, intents) + expLocks := []roachpb.Span{{Key: keyA}, {Key: keyB, EndKey: keyC}} + locks := etReq.LockSpans + if !reflect.DeepEqual(locks, expLocks) { + return nil, roachpb.NewErrorf("expected locks %s, got: %s", expLocks, locks) } resp := ba.CreateReply() // Set the response's txn to the Aborted status (as the server would). This @@ -1509,12 +1509,13 @@ func TestOnePCErrorTracking(t *testing.T) { Txn: txn.TestingCloneTxn(), } b := txn.NewBatch() - b.Put(key, "test value") + b.Put(keyA, "test value") + b.ScanForUpdate(keyB, keyC) if err := txn.CommitInBatch(ctx, b); !testutils.IsError(err, "injected err") { t.Fatal(err) } - // Now send a rollback and verify that the TxnCoordSender attaches the intent + // Now send a rollback and verify that the TxnCoordSender attaches the locks // to it. if _, pErr := client.SendWrappedWith( ctx, txn, txnHeader, @@ -1739,12 +1740,12 @@ func TestEndWriteRestartReadOnlyTransaction(t *testing.T) { br.Txn = ba.Txn.Clone() calls = append(calls, ba.Methods()...) - if _, ok := ba.GetArg(roachpb.Put); ok { + switch ba.Requests[0].GetInner().Method() { + case roachpb.Put, roachpb.Scan: return nil, roachpb.NewErrorWithTxn( roachpb.NewTransactionRetryError(roachpb.RETRY_SERIALIZABLE, "test err"), ba.Txn) - } - if _, ok := ba.GetArg(roachpb.EndTxn); ok { + case roachpb.EndTxn: br.Txn.Status = roachpb.COMMITTED } return br, nil @@ -1765,28 +1766,42 @@ func TestEndWriteRestartReadOnlyTransaction(t *testing.T) { sender, ) db := client.NewDB(testutils.MakeAmbientCtx(), factory, clock) - expCalls := []roachpb.Method{roachpb.Put, roachpb.EndTxn} - - testutils.RunTrueAndFalse(t, "success", func(t *testing.T, success bool) { - calls = nil - firstIter := true - if err := db.Txn(ctx, func(ctx context.Context, txn *client.Txn) error { - if firstIter { - firstIter = false - if err := txn.Put(ctx, "consider", "phlebas"); err == nil { - t.Fatal("missing injected retriable error") + + testutils.RunTrueAndFalse(t, "write", func(t *testing.T, write bool) { + testutils.RunTrueAndFalse(t, "success", func(t *testing.T, success bool) { + calls = nil + firstIter := true + if err := db.Txn(ctx, func(ctx context.Context, txn *client.Txn) error { + if firstIter { + firstIter = false + var err error + if write { + err = txn.Put(ctx, "consider", "phlebas") + } else /* locking read */ { + _, err = txn.ScanForUpdate(ctx, "a", "b", 0) + } + if err == nil { + t.Fatal("missing injected retriable error") + } } + if !success { + return errors.New("aborting on purpose") + } + return nil + }); err == nil != success { + t.Fatalf("expected error: %t, got error: %v", !success, err) } - if !success { - return errors.New("aborting on purpose") + + var expCalls []roachpb.Method + if write { + expCalls = []roachpb.Method{roachpb.Put, roachpb.EndTxn} + } else { + expCalls = []roachpb.Method{roachpb.Scan, roachpb.EndTxn} } - return nil - }); err == nil != success { - t.Fatalf("expected error: %t, got error: %v", !success, err) - } - if !reflect.DeepEqual(expCalls, calls) { - t.Fatalf("expected %v, got %v", expCalls, calls) - } + if !reflect.DeepEqual(expCalls, calls) { + t.Fatalf("expected %v, got %v", expCalls, calls) + } + }) }) } diff --git a/pkg/kv/txn_interceptor_heartbeater_test.go b/pkg/kv/txn_interceptor_heartbeater_test.go index e4c3f8b79160..b51e1c29b3ce 100644 --- a/pkg/kv/txn_interceptor_heartbeater_test.go +++ b/pkg/kv/txn_interceptor_heartbeater_test.go @@ -15,6 +15,7 @@ import ( "testing" "time" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/testutils" "github.com/cockroachdb/cockroach/pkg/util/hlc" @@ -170,8 +171,7 @@ func TestTxnHeartbeaterLoopStartedOnFirstLock(t *testing.T) { if write { ba.Add(&roachpb.PutRequest{RequestHeader: keyAHeader}) } else { - t.Skip("TODO(nvanbenschoten): uncomment") - // ba.Add(&roachpb.ScanRequest{RequestHeader: keyAHeader, KeyLocking: lock.Exclusive}) + ba.Add(&roachpb.ScanRequest{RequestHeader: keyAHeader, KeyLocking: lock.Exclusive}) } br, pErr = th.SendLocked(ctx, ba) diff --git a/pkg/kv/txn_interceptor_pipeliner.go b/pkg/kv/txn_interceptor_pipeliner.go index d5f8913e0121..e592a57f41de 100644 --- a/pkg/kv/txn_interceptor_pipeliner.go +++ b/pkg/kv/txn_interceptor_pipeliner.go @@ -58,7 +58,7 @@ var pipelinedWritesMaxBatchSize = settings.RegisterNonNegativeIntSetting( ) // trackedWritesMaxSize is a threshold in bytes for lock spans stored on the -// coordinator during the lifetime of a transaction. Intents are included with a +// coordinator during the lifetime of a transaction. Locks are included with a // transaction on commit or abort, to be cleaned up asynchronously. If they // exceed this threshold, they're condensed to avoid memory blowup both on the // coordinator and (critically) on the EndTxn command at the Raft group @@ -170,7 +170,7 @@ var trackedWritesMaxSize = settings.RegisterPublicIntSetting( type txnPipeliner struct { st *cluster.Settings // Optional; used to condense lock spans, if provided. If not provided, a - // transaction's write footprint may grow without bound. + // transaction's lock footprint may grow without bound. riGen RangeIteratorGen wrapped lockedSender disabled bool @@ -179,12 +179,14 @@ type txnPipeliner struct { // to have succeeded. They will need to be proven before the transaction // can commit. ifWrites inFlightWriteSet - // The transaction's write footprint contains spans where intent writes have - // been performed at some point by the transaction. The span set contains - // spans encompassing all writes that have already been proven in this epoch - // and all writes, in-flight or not, at the end of prior epochs. All of the - // transaction's in-flight writes are morally in this set as well, but they - // are not stored here to avoid duplication. + // The transaction's lock footprint contains spans where locks have been + // acquired at some point by the transaction. The span set contains spans + // encompassing the lock spans from all writes that have already been proven + // in this epoch and the lock spans from all locking reads that have been + // performed in this epoch. Additionally, the span set contains all locks + // held at the end of prior epochs. All of the transaction's in-flight + // writes are morally in this set as well, but they are not stored here to + // avoid duplication. // // Unlike the in-flight writes, this set does not need to be tracked with // full precision. Instead, the tracking can be an overestimate (i.e. the @@ -200,8 +202,8 @@ func (tp *txnPipeliner) SendLocked( ctx context.Context, ba roachpb.BatchRequest, ) (*roachpb.BatchResponse, *roachpb.Error) { // If an EndTxn request is part of this batch, attach the in-flight writes - // and the write footprint to it. - ba, pErr := tp.attachWritesToEndTxn(ctx, ba) + // and the lock footprint to it. + ba, pErr := tp.attachLocksToEndTxn(ctx, ba) if pErr != nil { return nil, pErr } @@ -212,19 +214,20 @@ func (tp *txnPipeliner) SendLocked( // Send through wrapped lockedSender. Unlocks while sending then re-locks. br, pErr := tp.wrapped.SendLocked(ctx, ba) - // Update the in-flight write set and the write footprint with the results - // of the request. - tp.updateWriteTracking(ctx, ba, br) + // Update the in-flight write set and the lock footprint with the results of + // the request. + tp.updateLockTracking(ctx, ba, br) if pErr != nil { return nil, tp.adjustError(ctx, ba, pErr) } return tp.stripQueryIntents(br), nil } -// attachWritesToEndTxn attaches the in-flight writes and the write footprint -// that the interceptor has been tracking to any EndTxn requests present in the -// provided batch. It augments these sets with writes from the current batch. -func (tp *txnPipeliner) attachWritesToEndTxn( +// attachLocksToEndTxn attaches the in-flight writes and the lock footprint that +// the interceptor has been tracking to any EndTxn requests present in the +// provided batch. It augments these sets with locking requests from the current +// batch. +func (tp *txnPipeliner) attachLocksToEndTxn( ctx context.Context, ba roachpb.BatchRequest, ) (roachpb.BatchRequest, *roachpb.Error) { args, hasET := ba.GetArg(roachpb.EndTxn) @@ -255,20 +258,21 @@ func (tp *txnPipeliner) attachWritesToEndTxn( for _, ru := range ba.Requests[:len(ba.Requests)-1] { req := ru.GetInner() h := req.Header() - if roachpb.IsIntentWrite(req) { + if roachpb.IsLocking(req) { // Ranged writes are added immediately to the lock spans because // it's not clear where they will actually leave intents. Point - // writes are added to the in-flight writes set. + // writes are added to the in-flight writes set. All other locking + // requests are also added to the lock spans. // // If we see any ranged writes then we know that the txnCommitter // will fold the in-flight writes into the lock spans immediately // and forgo a parallel commit, but let's not break that abstraction // boundary here. - if roachpb.IsRange(req) { - et.LockSpans = append(et.LockSpans, h.Span()) - } else { + if roachpb.IsIntentWrite(req) && !roachpb.IsRange(req) { w := roachpb.SequencedWrite{Key: h.Key, Sequence: h.Sequence} et.InFlightWrites = append(et.InFlightWrites, w) + } else { + et.LockSpans = append(et.LockSpans, h.Span()) } } } @@ -294,7 +298,7 @@ func (tp *txnPipeliner) attachWritesToEndTxn( // touches any of the in-flight writes. In effect, this allows us to prove that // a write succeeded before depending on its existence. We later prune down the // list of writes we proved to exist that are no longer "in-flight" in -// updateWriteTracking. +// updateLockTracking. func (tp *txnPipeliner) chainToInFlightWrites(ba roachpb.BatchRequest) roachpb.BatchRequest { asyncConsensus := pipelinedWritesEnabled.Get(&tp.st.SV) && !tp.disabled @@ -425,32 +429,32 @@ func (tp *txnPipeliner) chainToInFlightWrites(ba roachpb.BatchRequest) roachpb.B return ba } -// updateWriteTracking reads the response for the given request and uses it to -// update the tracked in-flight write set and write footprint. It does so by -// performing three actions: 1. it adds all async writes that the request -// performed to the in-flight -// write set. -// 2. it adds all non-async writes that the request performed to the write -// footprint. -// 3. it moves all in-flight writes that the request proved to exist from -// the in-flight writes set to the write footprint. +// updateLockTracking reads the response for the given request and uses it to +// update the tracked in-flight write set and lock footprint. It does so by +// performing three actions: +// 1. it adds all async writes that the request performed to the in-flight +// write set. +// 2. it adds all non-async writes and locking reads that the request +// performed to the lock footprint. +// 3. it moves all in-flight writes that the request proved to exist from +// the in-flight writes set to the lock footprint. // -// After updating the write sets, the write footprint is condensed to ensure -// that it remains under its memory limit. +// After updating the write sets, the lock footprint is condensed to ensure that +// it remains under its memory limit. // // If no response is provided (indicating an error), all writes from the batch -// are added directly to the write footprint to avoid leaking any intents when -// the transaction cleans up. -func (tp *txnPipeliner) updateWriteTracking( +// are added directly to the lock footprint to avoid leaking any locks when the +// transaction cleans up. +func (tp *txnPipeliner) updateLockTracking( ctx context.Context, ba roachpb.BatchRequest, br *roachpb.BatchResponse, ) { - // After adding new writes to the write footprint, check whether we need to + // After adding new writes to the lock footprint, check whether we need to // condense the set to stay below memory limits. defer tp.footprint.maybeCondense(ctx, tp.riGen, trackedWritesMaxSize.Get(&tp.st.SV)) - // If the request failed, add all intent writes directly to the write - // footprint. This reduces the likelihood of dangling intents blocking - // concurrent writers for extended periods of time. See #3346. + // If the request failed, add all lock acquisitions attempts directly to the + // lock footprint. This reduces the likelihood of dangling locks blocking + // concurrent requests for extended periods of time. See #3346. if br == nil { // The transaction cannot continue in this epoch whether this is // a retryable error or not. @@ -494,19 +498,21 @@ func (tp *txnPipeliner) updateWriteTracking( // case here because it happens a lot in tests. if resp.(*roachpb.QueryIntentResponse).FoundIntent { tp.ifWrites.remove(qiReq.Key, qiReq.Txn.Sequence) - // Move to write footprint. + // Move to lock footprint. tp.footprint.insert(roachpb.Span{Key: qiReq.Key}) } - } else if roachpb.IsIntentWrite(req) { - // If the request was a transactional write, track its intents. + } else if roachpb.IsLocking(req) { + // If the request intended to acquire locks, track its lock spans. if ba.AsyncConsensus { // Record any writes that were performed asynchronously. We'll // need to prove that these succeeded sometime before we commit. header := req.Header() tp.ifWrites.insert(header.Key, header.Sequence) } else { - // If the writes weren't performed asynchronously then add them - // directly to our write footprint. + // If the lock acquisitions weren't performed asynchronously + // then add them directly to our lock footprint. Locking read + // requests will always hit this path because they will never + // use async consensus. if sp, ok := roachpb.ActualSpan(req, resp); ok { tp.footprint.insert(sp) } @@ -515,11 +521,7 @@ func (tp *txnPipeliner) updateWriteTracking( } } -func (tp *txnPipeliner) trackLocks(s roachpb.Span, dur lock.Durability) { - // TODO(nvanbenschoten): handle unreplicated locks. - if dur != lock.Replicated { - panic("unexpected lock durability") - } +func (tp *txnPipeliner) trackLocks(s roachpb.Span, _ lock.Durability) { tp.footprint.insert(s) } @@ -602,9 +604,9 @@ func (tp *txnPipeliner) importLeafFinalState(*roachpb.LeafTxnFinalState) {} // epochBumpedLocked implements the txnReqInterceptor interface. func (tp *txnPipeliner) epochBumpedLocked() { - // Move all in-flight writes into the write footprint. These writes no - // longer need to be tracked precisely, but we don't want to forget about - // them and fail to clean them up. + // Move all in-flight writes into the lock footprint. These writes no longer + // need to be tracked precisely, but we don't want to forget about them and + // fail to clean them up. if tp.ifWrites.len() > 0 { tp.ifWrites.ascend(func(w *inFlightWrite) { tp.footprint.insert(roachpb.Span{Key: w.Key}) @@ -617,9 +619,9 @@ func (tp *txnPipeliner) epochBumpedLocked() { // closeLocked implements the txnReqInterceptor interface. func (tp *txnPipeliner) closeLocked() {} -// haveWrites returns whether the interceptor has observed any writes, -// including currently in-flight ones. -func (tp *txnPipeliner) haveWrites() bool { +// hasAcquiredLocks returns whether the interceptor has made an attempt to +// acquire any locks, whether doing so was known to be successful or not. +func (tp *txnPipeliner) hasAcquiredLocks() bool { return tp.ifWrites.len() > 0 || !tp.footprint.empty() } @@ -927,7 +929,7 @@ func (s *condensableSpanSet) maybeCondense( if !cs.Valid() { // If we didn't fatal here then we would need to ensure that the // spans were restored or a transaction could lose part of its - // write footprint. + // lock footprint. log.Fatalf(ctx, "failed to condense lock spans: "+ "combining span %s yielded invalid result", s) } diff --git a/pkg/kv/txn_interceptor_pipeliner_test.go b/pkg/kv/txn_interceptor_pipeliner_test.go index ccc976595b2f..a58d8ae953eb 100644 --- a/pkg/kv/txn_interceptor_pipeliner_test.go +++ b/pkg/kv/txn_interceptor_pipeliner_test.go @@ -17,6 +17,7 @@ import ( "strings" "testing" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/settings/cluster" "github.com/cockroachdb/cockroach/pkg/storage/enginepb" @@ -87,32 +88,54 @@ func makeTxnProto() roachpb.Transaction { } // TestTxnPipeliner1PCTransaction tests that the writes performed by 1PC -// transactions are not pipelined by the txnPipeliner and that the interceptor -// attaches the writes as lock spans to the EndTxn request. +// transactions are not pipelined by the txnPipeliner. It also tests that the +// interceptor attaches any locks that the batch will acquire as lock spans to +// the EndTxn request except for those locks that correspond to point writes, +// which are attached to the EndTxn request separately. func TestTxnPipeliner1PCTransaction(t *testing.T) { defer leaktest.AfterTest(t)() ctx := context.Background() tp, mockSender := makeMockTxnPipeliner() txn := makeTxnProto() - keyA := roachpb.Key("a") + keyA, keyB := roachpb.Key("a"), roachpb.Key("b") + keyC, keyD := roachpb.Key("c"), roachpb.Key("d") var ba roachpb.BatchRequest ba.Header = roachpb.Header{Txn: &txn} + scanArgs := roachpb.ScanRequest{ + RequestHeader: roachpb.RequestHeader{Key: keyA, EndKey: keyB}, + KeyLocking: lock.Exclusive, + } + ba.Add(&scanArgs) putArgs := roachpb.PutRequest{RequestHeader: roachpb.RequestHeader{Key: keyA}} putArgs.Sequence = 1 ba.Add(&putArgs) + delRngArgs := roachpb.DeleteRangeRequest{ + RequestHeader: roachpb.RequestHeader{Key: keyC, EndKey: keyD}, + } + delRngArgs.Sequence = 2 + ba.Add(&delRngArgs) ba.Add(&roachpb.EndTxnRequest{Commit: true}) mockSender.MockSend(func(ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error) { - require.Len(t, ba.Requests, 2) + require.Len(t, ba.Requests, 4) require.False(t, ba.AsyncConsensus) - require.IsType(t, &roachpb.PutRequest{}, ba.Requests[0].GetInner()) - require.IsType(t, &roachpb.EndTxnRequest{}, ba.Requests[1].GetInner()) + require.IsType(t, &roachpb.ScanRequest{}, ba.Requests[0].GetInner()) + require.IsType(t, &roachpb.PutRequest{}, ba.Requests[1].GetInner()) + require.IsType(t, &roachpb.DeleteRangeRequest{}, ba.Requests[2].GetInner()) + require.IsType(t, &roachpb.EndTxnRequest{}, ba.Requests[3].GetInner()) - etReq := ba.Requests[1].GetInner().(*roachpb.EndTxnRequest) - require.Len(t, etReq.LockSpans, 0) - require.Equal(t, []roachpb.SequencedWrite{{Key: keyA, Sequence: 1}}, etReq.InFlightWrites) + etReq := ba.Requests[3].GetEndTxn() + expLocks := []roachpb.Span{ + {Key: keyA, EndKey: keyB}, + {Key: keyC, EndKey: keyD}, + } + require.Equal(t, expLocks, etReq.LockSpans) + expInFlight := []roachpb.SequencedWrite{ + {Key: keyA, Sequence: 1}, + } + require.Equal(t, expInFlight, etReq.InFlightWrites) br := ba.CreateReply() br.Txn = ba.Txn @@ -190,7 +213,7 @@ func TestTxnPipelinerTrackInFlightWrites(t *testing.T) { require.IsType(t, &roachpb.IncrementRequest{}, ba.Requests[3].GetInner()) require.IsType(t, &roachpb.DeleteRequest{}, ba.Requests[4].GetInner()) - qiReq := ba.Requests[0].GetInner().(*roachpb.QueryIntentRequest) + qiReq := ba.Requests[0].GetQueryIntent() require.Equal(t, keyA, qiReq.Key) require.Equal(t, txn.ID, qiReq.Txn.ID) require.Equal(t, txn.WriteTimestamp, qiReq.Txn.WriteTimestamp) @@ -243,9 +266,9 @@ func TestTxnPipelinerTrackInFlightWrites(t *testing.T) { require.IsType(t, &roachpb.QueryIntentRequest{}, ba.Requests[3].GetInner()) require.IsType(t, &roachpb.EndTxnRequest{}, ba.Requests[4].GetInner()) - qiReq1 := ba.Requests[1].GetInner().(*roachpb.QueryIntentRequest) - qiReq2 := ba.Requests[2].GetInner().(*roachpb.QueryIntentRequest) - qiReq3 := ba.Requests[3].GetInner().(*roachpb.QueryIntentRequest) + qiReq1 := ba.Requests[1].GetQueryIntent() + qiReq2 := ba.Requests[2].GetQueryIntent() + qiReq3 := ba.Requests[3].GetQueryIntent() require.Equal(t, keyA, qiReq1.Key) require.Equal(t, keyB, qiReq2.Key) require.Equal(t, keyC, qiReq3.Key) @@ -253,7 +276,7 @@ func TestTxnPipelinerTrackInFlightWrites(t *testing.T) { require.Equal(t, enginepb.TxnSeq(3), qiReq2.Txn.Sequence) require.Equal(t, enginepb.TxnSeq(5), qiReq3.Txn.Sequence) - etReq := ba.Requests[4].GetInner().(*roachpb.EndTxnRequest) + etReq := ba.Requests[4].GetEndTxn() require.Equal(t, []roachpb.Span{{Key: keyA}}, etReq.LockSpans) expInFlight := []roachpb.SequencedWrite{ {Key: keyA, Sequence: 2}, @@ -266,9 +289,9 @@ func TestTxnPipelinerTrackInFlightWrites(t *testing.T) { br = ba.CreateReply() br.Txn = ba.Txn br.Txn.Status = roachpb.COMMITTED - br.Responses[1].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true - br.Responses[2].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true - br.Responses[3].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true + br.Responses[1].GetQueryIntent().FoundIntent = true + br.Responses[2].GetQueryIntent().FoundIntent = true + br.Responses[3].GetQueryIntent().FoundIntent = true return br, nil }) @@ -363,7 +386,7 @@ func TestTxnPipelinerReads(t *testing.T) { require.IsType(t, &roachpb.QueryIntentRequest{}, ba.Requests[0].GetInner()) require.IsType(t, &roachpb.GetRequest{}, ba.Requests[1].GetInner()) - qiReq := ba.Requests[0].GetInner().(*roachpb.QueryIntentRequest) + qiReq := ba.Requests[0].GetQueryIntent() require.Equal(t, keyA, qiReq.Key) require.Equal(t, enginepb.TxnSeq(10), qiReq.Txn.Sequence) @@ -436,9 +459,9 @@ func TestTxnPipelinerRangedWrites(t *testing.T) { require.IsType(t, &roachpb.QueryIntentRequest{}, ba.Requests[3].GetInner()) require.IsType(t, &roachpb.DeleteRangeRequest{}, ba.Requests[4].GetInner()) - qiReq1 := ba.Requests[0].GetInner().(*roachpb.QueryIntentRequest) - qiReq2 := ba.Requests[2].GetInner().(*roachpb.QueryIntentRequest) - qiReq3 := ba.Requests[3].GetInner().(*roachpb.QueryIntentRequest) + qiReq1 := ba.Requests[0].GetQueryIntent() + qiReq2 := ba.Requests[2].GetQueryIntent() + qiReq3 := ba.Requests[3].GetQueryIntent() require.Equal(t, roachpb.Key("a"), qiReq1.Key) require.Equal(t, roachpb.Key("b"), qiReq2.Key) require.Equal(t, roachpb.Key("c"), qiReq3.Key) @@ -455,8 +478,8 @@ func TestTxnPipelinerRangedWrites(t *testing.T) { br = ba.CreateReply() br.Txn = ba.Txn br.Responses[0].GetQueryIntent().FoundIntent = true - br.Responses[2].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true - br.Responses[3].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true + br.Responses[2].GetQueryIntent().FoundIntent = true + br.Responses[3].GetQueryIntent().FoundIntent = true return br, nil }) @@ -512,15 +535,15 @@ func TestTxnPipelinerNonTransactionalRequests(t *testing.T) { require.IsType(t, &roachpb.QueryIntentRequest{}, ba.Requests[1].GetInner()) require.IsType(t, &roachpb.SubsumeRequest{}, ba.Requests[2].GetInner()) - qiReq1 := ba.Requests[0].GetInner().(*roachpb.QueryIntentRequest) - qiReq2 := ba.Requests[1].GetInner().(*roachpb.QueryIntentRequest) + qiReq1 := ba.Requests[0].GetQueryIntent() + qiReq2 := ba.Requests[1].GetQueryIntent() require.Equal(t, keyA, qiReq1.Key) require.Equal(t, keyC, qiReq2.Key) br = ba.CreateReply() br.Txn = ba.Txn br.Responses[0].GetQueryIntent().FoundIntent = true - br.Responses[1].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true + br.Responses[1].GetQueryIntent().FoundIntent = true return br, nil }) @@ -590,12 +613,12 @@ func TestTxnPipelinerManyWrites(t *testing.T) { require.IsType(t, &roachpb.QueryIntentRequest{}, ba.Requests[i].GetInner()) require.IsType(t, &roachpb.GetRequest{}, ba.Requests[i+1].GetInner()) - qiReq := ba.Requests[i].GetInner().(*roachpb.QueryIntentRequest) + qiReq := ba.Requests[i].GetQueryIntent() require.Equal(t, key, qiReq.Key) require.Equal(t, txn.ID, qiReq.Txn.ID) require.Equal(t, makeSeq(i), qiReq.Txn.Sequence) - getReq := ba.Requests[i+1].GetInner().(*roachpb.GetRequest) + getReq := ba.Requests[i+1].GetGet() require.Equal(t, key, getReq.Key) } } @@ -604,7 +627,7 @@ func TestTxnPipelinerManyWrites(t *testing.T) { br.Txn = ba.Txn for i := 0; i < writes; i++ { if i%2 == 0 { - br.Responses[i].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true + br.Responses[i].GetQueryIntent().FoundIntent = true } } return br, nil @@ -672,7 +695,7 @@ func TestTxnPipelinerTransactionAbort(t *testing.T) { require.False(t, ba.AsyncConsensus) require.IsType(t, &roachpb.EndTxnRequest{}, ba.Requests[0].GetInner()) - etReq := ba.Requests[0].GetInner().(*roachpb.EndTxnRequest) + etReq := ba.Requests[0].GetEndTxn() require.Len(t, etReq.LockSpans, 0) require.Equal(t, []roachpb.SequencedWrite{{Key: keyA, Sequence: 1}}, etReq.InFlightWrites) @@ -700,7 +723,7 @@ func TestTxnPipelinerTransactionAbort(t *testing.T) { require.False(t, ba.AsyncConsensus) require.IsType(t, &roachpb.EndTxnRequest{}, ba.Requests[0].GetInner()) - etReq := ba.Requests[0].GetInner().(*roachpb.EndTxnRequest) + etReq := ba.Requests[0].GetEndTxn() require.Len(t, etReq.LockSpans, 0) require.Equal(t, []roachpb.SequencedWrite{{Key: keyA, Sequence: 1}}, etReq.InFlightWrites) @@ -718,7 +741,7 @@ func TestTxnPipelinerTransactionAbort(t *testing.T) { // TestTxnPipelinerEpochIncrement tests that a txnPipeliner's in-flight write // set is reset on an epoch increment and that all writes in this set are moved -// to the write footprint so they will be removed when the transaction finishes. +// to the lock footprint so they will be removed when the transaction finishes. func TestTxnPipelinerEpochIncrement(t *testing.T) { defer leaktest.AfterTest(t)() tp, _ := makeMockTxnPipeliner() @@ -869,7 +892,7 @@ func TestTxnPipelinerEnableDisableMixTxn(t *testing.T) { require.IsType(t, &roachpb.QueryIntentRequest{}, ba.Requests[0].GetInner()) require.IsType(t, &roachpb.PutRequest{}, ba.Requests[1].GetInner()) - qiReq := ba.Requests[0].GetInner().(*roachpb.QueryIntentRequest) + qiReq := ba.Requests[0].GetQueryIntent() require.Equal(t, keyA, qiReq.Key) require.Equal(t, enginepb.TxnSeq(2), qiReq.Txn.Sequence) @@ -897,11 +920,11 @@ func TestTxnPipelinerEnableDisableMixTxn(t *testing.T) { require.IsType(t, &roachpb.QueryIntentRequest{}, ba.Requests[0].GetInner()) require.IsType(t, &roachpb.EndTxnRequest{}, ba.Requests[1].GetInner()) - qiReq := ba.Requests[0].GetInner().(*roachpb.QueryIntentRequest) + qiReq := ba.Requests[0].GetQueryIntent() require.Equal(t, keyC, qiReq.Key) require.Equal(t, enginepb.TxnSeq(3), qiReq.Txn.Sequence) - etReq := ba.Requests[1].GetInner().(*roachpb.EndTxnRequest) + etReq := ba.Requests[1].GetEndTxn() require.Equal(t, []roachpb.Span{{Key: keyA}}, etReq.LockSpans) require.Equal(t, []roachpb.SequencedWrite{{Key: keyC, Sequence: 3}}, etReq.InFlightWrites) @@ -1010,7 +1033,7 @@ func TestTxnPipelinerMaxInFlightSize(t *testing.T) { br = ba.CreateReply() br.Txn = ba.Txn br.Responses[0].GetQueryIntent().FoundIntent = true - br.Responses[2].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true + br.Responses[2].GetQueryIntent().FoundIntent = true return br, nil }) @@ -1034,7 +1057,7 @@ func TestTxnPipelinerMaxInFlightSize(t *testing.T) { br = ba.CreateReply() br.Txn = ba.Txn - br.Responses[1].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true + br.Responses[1].GetQueryIntent().FoundIntent = true return br, nil }) @@ -1057,7 +1080,7 @@ func TestTxnPipelinerMaxInFlightSize(t *testing.T) { br = ba.CreateReply() br.Txn = ba.Txn br.Responses[0].GetQueryIntent().FoundIntent = true - br.Responses[2].GetInner().(*roachpb.QueryIntentResponse).FoundIntent = true + br.Responses[2].GetQueryIntent().FoundIntent = true return br, nil }) @@ -1173,27 +1196,33 @@ func TestTxnPipelinerMaxBatchSize(t *testing.T) { require.Equal(t, 2, tp.ifWrites.len()) } -// TestTxnPipelinerRecordsWritesOnFailure tests that even when a request returns -// with an ABORTED transaction status or an error, the intent writes it attempted -// to perform are added to the write footprint. -func TestTxnPipelinerRecordsWritesOnFailure(t *testing.T) { +// TestTxnPipelinerRecordsLocksOnFailure tests that even when a request returns +// with an ABORTED transaction status or an error, the locks that it attempted +// to acquire are added to the lock footprint. +func TestTxnPipelinerRecordsLocksOnFailure(t *testing.T) { defer leaktest.AfterTest(t)() ctx := context.Background() tp, mockSender := makeMockTxnPipeliner() txn := makeTxnProto() - keyA, keyB := roachpb.Key("a"), roachpb.Key("b") + keyA, keyB, keyC := roachpb.Key("a"), roachpb.Key("b"), roachpb.Key("c") + keyD, keyE, keyF := roachpb.Key("d"), roachpb.Key("e"), roachpb.Key("f") - // Return an error for a write. + // Return an error for a point write, a range write, and a range locking + // read. var ba roachpb.BatchRequest ba.Header = roachpb.Header{Txn: &txn} ba.Add(&roachpb.PutRequest{RequestHeader: roachpb.RequestHeader{Key: keyA}}) + ba.Add(&roachpb.DeleteRangeRequest{RequestHeader: roachpb.RequestHeader{Key: keyB, EndKey: keyB.Next()}}) + ba.Add(&roachpb.ScanRequest{RequestHeader: roachpb.RequestHeader{Key: keyC, EndKey: keyC.Next()}, KeyLocking: lock.Exclusive}) mockPErr := roachpb.NewErrorf("boom") mockSender.MockSend(func(ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error) { - require.Len(t, ba.Requests, 1) - require.True(t, ba.AsyncConsensus) + require.Len(t, ba.Requests, 3) + require.False(t, ba.AsyncConsensus) require.IsType(t, &roachpb.PutRequest{}, ba.Requests[0].GetInner()) + require.IsType(t, &roachpb.DeleteRangeRequest{}, ba.Requests[1].GetInner()) + require.IsType(t, &roachpb.ScanRequest{}, ba.Requests[2].GetInner()) return nil, mockPErr }) @@ -1202,20 +1231,29 @@ func TestTxnPipelinerRecordsWritesOnFailure(t *testing.T) { require.Nil(t, br) require.Equal(t, mockPErr, pErr) require.Equal(t, 0, tp.ifWrites.len()) - require.Len(t, tp.footprint.asSlice(), 1) - // Return an ABORTED transaction record for a write. + var expLocks []roachpb.Span + expLocks = append(expLocks, roachpb.Span{Key: keyA}) + expLocks = append(expLocks, roachpb.Span{Key: keyB, EndKey: keyB.Next()}) + expLocks = append(expLocks, roachpb.Span{Key: keyC, EndKey: keyC.Next()}) + require.Equal(t, expLocks, tp.footprint.asSlice()) + + // Return an ABORTED transaction record for a point write, a range write, + // and a range locking read. ba.Requests = nil - ba.Add(&roachpb.PutRequest{RequestHeader: roachpb.RequestHeader{Key: keyB}}) + ba.Add(&roachpb.PutRequest{RequestHeader: roachpb.RequestHeader{Key: keyD}}) + ba.Add(&roachpb.DeleteRangeRequest{RequestHeader: roachpb.RequestHeader{Key: keyE, EndKey: keyE.Next()}}) + ba.Add(&roachpb.ScanRequest{RequestHeader: roachpb.RequestHeader{Key: keyF, EndKey: keyF.Next()}, KeyLocking: lock.Exclusive}) mockSender.MockSend(func(ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error) { - require.Len(t, ba.Requests, 1) - require.True(t, ba.AsyncConsensus) + require.Len(t, ba.Requests, 3) + require.False(t, ba.AsyncConsensus) require.IsType(t, &roachpb.PutRequest{}, ba.Requests[0].GetInner()) + require.IsType(t, &roachpb.DeleteRangeRequest{}, ba.Requests[1].GetInner()) + require.IsType(t, &roachpb.ScanRequest{}, ba.Requests[2].GetInner()) br = ba.CreateReply() br.Txn = ba.Txn - br.Txn.Status = roachpb.ABORTED return br, nil }) @@ -1223,5 +1261,31 @@ func TestTxnPipelinerRecordsWritesOnFailure(t *testing.T) { require.Nil(t, pErr) require.NotNil(t, br) require.Equal(t, 0, tp.ifWrites.len()) - require.Len(t, tp.footprint.asSlice(), 2) + + expLocks = append(expLocks, roachpb.Span{Key: keyD}) + expLocks = append(expLocks, roachpb.Span{Key: keyE, EndKey: keyE.Next()}) + expLocks = append(expLocks, roachpb.Span{Key: keyF, EndKey: keyF.Next()}) + require.Equal(t, expLocks, tp.footprint.asSlice()) + + // The lock spans are all attached to the EndTxn request when one is sent. + ba.Requests = nil + ba.Add(&roachpb.EndTxnRequest{Commit: false}) + + mockSender.MockSend(func(ba roachpb.BatchRequest) (*roachpb.BatchResponse, *roachpb.Error) { + require.Len(t, ba.Requests, 1) + require.IsType(t, &roachpb.EndTxnRequest{}, ba.Requests[0].GetInner()) + + etReq := ba.Requests[0].GetEndTxn() + require.Equal(t, expLocks, etReq.LockSpans) + require.Len(t, etReq.InFlightWrites, 0) + + br = ba.CreateReply() + br.Txn = ba.Txn + br.Txn.Status = roachpb.ABORTED + return br, nil + }) + + br, pErr = tp.SendLocked(ctx, ba) + require.Nil(t, pErr) + require.NotNil(t, br) } diff --git a/pkg/roachpb/api.go b/pkg/roachpb/api.go index 05cf7a2a2343..affbc816e512 100644 --- a/pkg/roachpb/api.go +++ b/pkg/roachpb/api.go @@ -996,28 +996,39 @@ func NewDeleteRange(startKey, endKey Key, returnKeys bool) Request { } } -// NewScan returns a Request initialized to scan from start to end keys -// with max results. -func NewScan(key, endKey Key) Request { +// NewScan returns a Request initialized to scan from start to end keys. +// If forUpdate is true, unreplicated, exclusive locks are acquired on +// each of the resulting keys. +func NewScan(key, endKey Key, forUpdate bool) Request { return &ScanRequest{ RequestHeader: RequestHeader{ Key: key, EndKey: endKey, }, + KeyLocking: scanLockStrength(forUpdate), } } -// NewReverseScan returns a Request initialized to reverse scan from end to -// start keys with max results. -func NewReverseScan(key, endKey Key) Request { +// NewReverseScan returns a Request initialized to reverse scan from end. +// If forUpdate is true, unreplicated, exclusive locks are acquired on +// each of the resulting keys. +func NewReverseScan(key, endKey Key, forUpdate bool) Request { return &ReverseScanRequest{ RequestHeader: RequestHeader{ Key: key, EndKey: endKey, }, + KeyLocking: scanLockStrength(forUpdate), } } +func scanLockStrength(forUpdate bool) lock.Strength { + if forUpdate { + return lock.Exclusive + } + return lock.None +} + func (*GetRequest) flags() int { return isRead | isTxn | updatesTSCache | needsRefresh } @@ -1091,9 +1102,20 @@ func (*ClearRangeRequest) flags() int { return isWrite | isRange | isAlone } // they clear all MVCC versions above their target time. func (*RevertRangeRequest) flags() int { return isWrite | isRange } -func (*ScanRequest) flags() int { return isRead | isRange | isTxn | updatesTSCache | needsRefresh } -func (*ReverseScanRequest) flags() int { - return isRead | isRange | isReverse | isTxn | updatesTSCache | needsRefresh +func (sr *ScanRequest) flags() int { + maybeLocking := 0 + if sr.KeyLocking != lock.None { + maybeLocking = isLocking + } + return isRead | isRange | isTxn | maybeLocking | updatesTSCache | needsRefresh +} + +func (rsr *ReverseScanRequest) flags() int { + maybeLocking := 0 + if rsr.KeyLocking != lock.None { + maybeLocking = isLocking + } + return isRead | isRange | isReverse | isTxn | maybeLocking | updatesTSCache | needsRefresh } // EndTxn updates the timestamp cache to prevent replays. @@ -1320,7 +1342,6 @@ func (rir *ResolveIntentRequest) AsLockUpdate() LockUpdate { Txn: rir.IntentTxn, Status: rir.Status, IgnoredSeqNums: rir.IgnoredSeqNums, - Durability: lock.Replicated, } } @@ -1332,6 +1353,5 @@ func (rirr *ResolveIntentRangeRequest) AsLockUpdate() LockUpdate { Txn: rirr.IntentTxn, Status: rirr.Status, IgnoredSeqNums: rirr.IgnoredSeqNums, - Durability: lock.Replicated, } } diff --git a/pkg/roachpb/api.pb.go b/pkg/roachpb/api.pb.go index 7493df3ae4cd..a70abb9526ff 100644 --- a/pkg/roachpb/api.pb.go +++ b/pkg/roachpb/api.pb.go @@ -6,6 +6,7 @@ package roachpb import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" +import lock "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" import enginepb "github.com/cockroachdb/cockroach/pkg/storage/enginepb" import hlc "github.com/cockroachdb/cockroach/pkg/util/hlc" import tracing "github.com/cockroachdb/cockroach/pkg/util/tracing" @@ -71,7 +72,7 @@ func (x ReadConsistencyType) String() string { return proto.EnumName(ReadConsistencyType_name, int32(x)) } func (ReadConsistencyType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{0} + return fileDescriptor_api_6ead497ae315f5e8, []int{0} } // ScanFormat is an enumeration of the available response formats for MVCCScan @@ -99,7 +100,7 @@ func (x ScanFormat) String() string { return proto.EnumName(ScanFormat_name, int32(x)) } func (ScanFormat) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{1} + return fileDescriptor_api_6ead497ae315f5e8, []int{1} } type ChecksumMode int32 @@ -146,7 +147,7 @@ func (x ChecksumMode) String() string { return proto.EnumName(ChecksumMode_name, int32(x)) } func (ChecksumMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{2} + return fileDescriptor_api_6ead497ae315f5e8, []int{2} } // PushTxnType determines what action to take when pushing a transaction. @@ -177,7 +178,7 @@ func (x PushTxnType) String() string { return proto.EnumName(PushTxnType_name, int32(x)) } func (PushTxnType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{3} + return fileDescriptor_api_6ead497ae315f5e8, []int{3} } type ExternalStorageProvider int32 @@ -215,7 +216,7 @@ func (x ExternalStorageProvider) String() string { return proto.EnumName(ExternalStorageProvider_name, int32(x)) } func (ExternalStorageProvider) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{4} + return fileDescriptor_api_6ead497ae315f5e8, []int{4} } type MVCCFilter int32 @@ -238,7 +239,7 @@ func (x MVCCFilter) String() string { return proto.EnumName(MVCCFilter_name, int32(x)) } func (MVCCFilter) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{5} + return fileDescriptor_api_6ead497ae315f5e8, []int{5} } type ResponseHeader_ResumeReason int32 @@ -264,7 +265,7 @@ func (x ResponseHeader_ResumeReason) String() string { return proto.EnumName(ResponseHeader_ResumeReason_name, int32(x)) } func (ResponseHeader_ResumeReason) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{2, 0} + return fileDescriptor_api_6ead497ae315f5e8, []int{2, 0} } type CheckConsistencyResponse_Status int32 @@ -306,7 +307,7 @@ func (x CheckConsistencyResponse_Status) String() string { return proto.EnumName(CheckConsistencyResponse_Status_name, int32(x)) } func (CheckConsistencyResponse_Status) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{26, 0} + return fileDescriptor_api_6ead497ae315f5e8, []int{26, 0} } // RangeInfo describes a range which executed a request. It contains @@ -320,7 +321,7 @@ func (m *RangeInfo) Reset() { *m = RangeInfo{} } func (m *RangeInfo) String() string { return proto.CompactTextString(m) } func (*RangeInfo) ProtoMessage() {} func (*RangeInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{0} + return fileDescriptor_api_6ead497ae315f5e8, []int{0} } func (m *RangeInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -363,7 +364,7 @@ func (m *RequestHeader) Reset() { *m = RequestHeader{} } func (m *RequestHeader) String() string { return proto.CompactTextString(m) } func (*RequestHeader) ProtoMessage() {} func (*RequestHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{1} + return fileDescriptor_api_6ead497ae315f5e8, []int{1} } func (m *RequestHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -430,7 +431,7 @@ func (m *ResponseHeader) Reset() { *m = ResponseHeader{} } func (m *ResponseHeader) String() string { return proto.CompactTextString(m) } func (*ResponseHeader) ProtoMessage() {} func (*ResponseHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{2} + return fileDescriptor_api_6ead497ae315f5e8, []int{2} } func (m *ResponseHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -464,7 +465,7 @@ func (m *GetRequest) Reset() { *m = GetRequest{} } func (m *GetRequest) String() string { return proto.CompactTextString(m) } func (*GetRequest) ProtoMessage() {} func (*GetRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{3} + return fileDescriptor_api_6ead497ae315f5e8, []int{3} } func (m *GetRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -502,7 +503,7 @@ func (m *GetResponse) Reset() { *m = GetResponse{} } func (m *GetResponse) String() string { return proto.CompactTextString(m) } func (*GetResponse) ProtoMessage() {} func (*GetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{4} + return fileDescriptor_api_6ead497ae315f5e8, []int{4} } func (m *GetResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -545,7 +546,7 @@ func (m *PutRequest) Reset() { *m = PutRequest{} } func (m *PutRequest) String() string { return proto.CompactTextString(m) } func (*PutRequest) ProtoMessage() {} func (*PutRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{5} + return fileDescriptor_api_6ead497ae315f5e8, []int{5} } func (m *PutRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -579,7 +580,7 @@ func (m *PutResponse) Reset() { *m = PutResponse{} } func (m *PutResponse) String() string { return proto.CompactTextString(m) } func (*PutResponse) ProtoMessage() {} func (*PutResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{6} + return fileDescriptor_api_6ead497ae315f5e8, []int{6} } func (m *PutResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -633,7 +634,7 @@ func (m *ConditionalPutRequest) Reset() { *m = ConditionalPutRequest{} } func (m *ConditionalPutRequest) String() string { return proto.CompactTextString(m) } func (*ConditionalPutRequest) ProtoMessage() {} func (*ConditionalPutRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{7} + return fileDescriptor_api_6ead497ae315f5e8, []int{7} } func (m *ConditionalPutRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -668,7 +669,7 @@ func (m *ConditionalPutResponse) Reset() { *m = ConditionalPutResponse{} func (m *ConditionalPutResponse) String() string { return proto.CompactTextString(m) } func (*ConditionalPutResponse) ProtoMessage() {} func (*ConditionalPutResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{8} + return fileDescriptor_api_6ead497ae315f5e8, []int{8} } func (m *ConditionalPutResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -714,7 +715,7 @@ func (m *InitPutRequest) Reset() { *m = InitPutRequest{} } func (m *InitPutRequest) String() string { return proto.CompactTextString(m) } func (*InitPutRequest) ProtoMessage() {} func (*InitPutRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{9} + return fileDescriptor_api_6ead497ae315f5e8, []int{9} } func (m *InitPutRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -748,7 +749,7 @@ func (m *InitPutResponse) Reset() { *m = InitPutResponse{} } func (m *InitPutResponse) String() string { return proto.CompactTextString(m) } func (*InitPutResponse) ProtoMessage() {} func (*InitPutResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{10} + return fileDescriptor_api_6ead497ae315f5e8, []int{10} } func (m *InitPutResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -788,7 +789,7 @@ func (m *IncrementRequest) Reset() { *m = IncrementRequest{} } func (m *IncrementRequest) String() string { return proto.CompactTextString(m) } func (*IncrementRequest) ProtoMessage() {} func (*IncrementRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{11} + return fileDescriptor_api_6ead497ae315f5e8, []int{11} } func (m *IncrementRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -825,7 +826,7 @@ func (m *IncrementResponse) Reset() { *m = IncrementResponse{} } func (m *IncrementResponse) String() string { return proto.CompactTextString(m) } func (*IncrementResponse) ProtoMessage() {} func (*IncrementResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{12} + return fileDescriptor_api_6ead497ae315f5e8, []int{12} } func (m *IncrementResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -859,7 +860,7 @@ func (m *DeleteRequest) Reset() { *m = DeleteRequest{} } func (m *DeleteRequest) String() string { return proto.CompactTextString(m) } func (*DeleteRequest) ProtoMessage() {} func (*DeleteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{13} + return fileDescriptor_api_6ead497ae315f5e8, []int{13} } func (m *DeleteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -893,7 +894,7 @@ func (m *DeleteResponse) Reset() { *m = DeleteResponse{} } func (m *DeleteResponse) String() string { return proto.CompactTextString(m) } func (*DeleteResponse) ProtoMessage() {} func (*DeleteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{14} + return fileDescriptor_api_6ead497ae315f5e8, []int{14} } func (m *DeleteResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -945,7 +946,7 @@ func (m *DeleteRangeRequest) Reset() { *m = DeleteRangeRequest{} } func (m *DeleteRangeRequest) String() string { return proto.CompactTextString(m) } func (*DeleteRangeRequest) ProtoMessage() {} func (*DeleteRangeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{15} + return fileDescriptor_api_6ead497ae315f5e8, []int{15} } func (m *DeleteRangeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -982,7 +983,7 @@ func (m *DeleteRangeResponse) Reset() { *m = DeleteRangeResponse{} } func (m *DeleteRangeResponse) String() string { return proto.CompactTextString(m) } func (*DeleteRangeResponse) ProtoMessage() {} func (*DeleteRangeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{16} + return fileDescriptor_api_6ead497ae315f5e8, []int{16} } func (m *DeleteRangeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1029,7 +1030,7 @@ func (m *ClearRangeRequest) Reset() { *m = ClearRangeRequest{} } func (m *ClearRangeRequest) String() string { return proto.CompactTextString(m) } func (*ClearRangeRequest) ProtoMessage() {} func (*ClearRangeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{17} + return fileDescriptor_api_6ead497ae315f5e8, []int{17} } func (m *ClearRangeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1063,7 +1064,7 @@ func (m *ClearRangeResponse) Reset() { *m = ClearRangeResponse{} } func (m *ClearRangeResponse) String() string { return proto.CompactTextString(m) } func (*ClearRangeResponse) ProtoMessage() {} func (*ClearRangeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{18} + return fileDescriptor_api_6ead497ae315f5e8, []int{18} } func (m *ClearRangeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1104,7 +1105,7 @@ func (m *RevertRangeRequest) Reset() { *m = RevertRangeRequest{} } func (m *RevertRangeRequest) String() string { return proto.CompactTextString(m) } func (*RevertRangeRequest) ProtoMessage() {} func (*RevertRangeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{19} + return fileDescriptor_api_6ead497ae315f5e8, []int{19} } func (m *RevertRangeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1138,7 +1139,7 @@ func (m *RevertRangeResponse) Reset() { *m = RevertRangeResponse{} } func (m *RevertRangeResponse) String() string { return proto.CompactTextString(m) } func (*RevertRangeResponse) ProtoMessage() {} func (*RevertRangeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{20} + return fileDescriptor_api_6ead497ae315f5e8, []int{20} } func (m *RevertRangeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1172,13 +1173,24 @@ type ScanRequest struct { // will set the batch_responses field in the ScanResponse instead of the rows // field. ScanFormat ScanFormat `protobuf:"varint,4,opt,name=scan_format,json=scanFormat,proto3,enum=cockroach.roachpb.ScanFormat" json:"scan_format,omitempty"` + // The desired key-level locking mode used during this scan. When set to None + // (the default), no key-level locking mode is used - meaning that the scan + // does not acquire any locks. When set to any other strength, a lock of that + // strength is acquired with the Unreplicated durability (i.e. best-effort) on + // each of the keys scanned by the request, subject to any key limit applied + // to the batch which limits the number of keys returned. + // + // NOTE: the locks acquire with this strength are point locks on each of the + // keys returned by the request, not a single range lock over the entire span + // scanned by the request. + KeyLocking lock.Strength `protobuf:"varint,5,opt,name=key_locking,json=keyLocking,proto3,enum=cockroach.kv.kvserver.concurrency.lock.Strength" json:"key_locking,omitempty"` } func (m *ScanRequest) Reset() { *m = ScanRequest{} } func (m *ScanRequest) String() string { return proto.CompactTextString(m) } func (*ScanRequest) ProtoMessage() {} func (*ScanRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{21} + return fileDescriptor_api_6ead497ae315f5e8, []int{21} } func (m *ScanRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1225,7 +1237,7 @@ func (m *ScanResponse) Reset() { *m = ScanResponse{} } func (m *ScanResponse) String() string { return proto.CompactTextString(m) } func (*ScanResponse) ProtoMessage() {} func (*ScanResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{22} + return fileDescriptor_api_6ead497ae315f5e8, []int{22} } func (m *ScanResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1259,13 +1271,24 @@ type ReverseScanRequest struct { // will set the batch_responses field in the ScanResponse instead of the rows // field. ScanFormat ScanFormat `protobuf:"varint,4,opt,name=scan_format,json=scanFormat,proto3,enum=cockroach.roachpb.ScanFormat" json:"scan_format,omitempty"` + // The desired key-level locking mode used during this scan. When set to None + // (the default), no key-level locking mode is used - meaning that the scan + // does not acquire any locks. When set to any other strength, a lock of that + // strength is acquired with the Unreplicated durability (i.e. best-effort) on + // each of the keys scanned by the request, subject to any key limit applied + // to the batch which limits the number of keys returned. + // + // NOTE: the locks acquire with this strength are point locks on each of the + // keys returned by the request, not a single range lock over the entire span + // scanned by the request. + KeyLocking lock.Strength `protobuf:"varint,5,opt,name=key_locking,json=keyLocking,proto3,enum=cockroach.kv.kvserver.concurrency.lock.Strength" json:"key_locking,omitempty"` } func (m *ReverseScanRequest) Reset() { *m = ReverseScanRequest{} } func (m *ReverseScanRequest) String() string { return proto.CompactTextString(m) } func (*ReverseScanRequest) ProtoMessage() {} func (*ReverseScanRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{23} + return fileDescriptor_api_6ead497ae315f5e8, []int{23} } func (m *ReverseScanRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1312,7 +1335,7 @@ func (m *ReverseScanResponse) Reset() { *m = ReverseScanResponse{} } func (m *ReverseScanResponse) String() string { return proto.CompactTextString(m) } func (*ReverseScanResponse) ProtoMessage() {} func (*ReverseScanResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{24} + return fileDescriptor_api_6ead497ae315f5e8, []int{24} } func (m *ReverseScanResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1365,7 +1388,7 @@ func (m *CheckConsistencyRequest) Reset() { *m = CheckConsistencyRequest func (m *CheckConsistencyRequest) String() string { return proto.CompactTextString(m) } func (*CheckConsistencyRequest) ProtoMessage() {} func (*CheckConsistencyRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{25} + return fileDescriptor_api_6ead497ae315f5e8, []int{25} } func (m *CheckConsistencyRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1402,7 +1425,7 @@ func (m *CheckConsistencyResponse) Reset() { *m = CheckConsistencyRespon func (m *CheckConsistencyResponse) String() string { return proto.CompactTextString(m) } func (*CheckConsistencyResponse) ProtoMessage() {} func (*CheckConsistencyResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{26} + return fileDescriptor_api_6ead497ae315f5e8, []int{26} } func (m *CheckConsistencyResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1446,7 +1469,7 @@ func (m *CheckConsistencyResponse_Result) Reset() { *m = CheckConsistenc func (m *CheckConsistencyResponse_Result) String() string { return proto.CompactTextString(m) } func (*CheckConsistencyResponse_Result) ProtoMessage() {} func (*CheckConsistencyResponse_Result) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{26, 0} + return fileDescriptor_api_6ead497ae315f5e8, []int{26, 0} } func (m *CheckConsistencyResponse_Result) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1494,7 +1517,7 @@ func (m *RecomputeStatsRequest) Reset() { *m = RecomputeStatsRequest{} } func (m *RecomputeStatsRequest) String() string { return proto.CompactTextString(m) } func (*RecomputeStatsRequest) ProtoMessage() {} func (*RecomputeStatsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{27} + return fileDescriptor_api_6ead497ae315f5e8, []int{27} } func (m *RecomputeStatsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1530,7 +1553,7 @@ func (m *RecomputeStatsResponse) Reset() { *m = RecomputeStatsResponse{} func (m *RecomputeStatsResponse) String() string { return proto.CompactTextString(m) } func (*RecomputeStatsResponse) ProtoMessage() {} func (*RecomputeStatsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{28} + return fileDescriptor_api_6ead497ae315f5e8, []int{28} } func (m *RecomputeStatsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1625,7 +1648,7 @@ func (m *EndTxnRequest) Reset() { *m = EndTxnRequest{} } func (m *EndTxnRequest) String() string { return proto.CompactTextString(m) } func (*EndTxnRequest) ProtoMessage() {} func (*EndTxnRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{29} + return fileDescriptor_api_6ead497ae315f5e8, []int{29} } func (m *EndTxnRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1671,7 +1694,7 @@ func (m *EndTxnResponse) Reset() { *m = EndTxnResponse{} } func (m *EndTxnResponse) String() string { return proto.CompactTextString(m) } func (*EndTxnResponse) ProtoMessage() {} func (*EndTxnResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{30} + return fileDescriptor_api_6ead497ae315f5e8, []int{30} } func (m *EndTxnResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1732,7 +1755,7 @@ func (m *AdminSplitRequest) Reset() { *m = AdminSplitRequest{} } func (m *AdminSplitRequest) String() string { return proto.CompactTextString(m) } func (*AdminSplitRequest) ProtoMessage() {} func (*AdminSplitRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{31} + return fileDescriptor_api_6ead497ae315f5e8, []int{31} } func (m *AdminSplitRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1767,7 +1790,7 @@ func (m *AdminSplitResponse) Reset() { *m = AdminSplitResponse{} } func (m *AdminSplitResponse) String() string { return proto.CompactTextString(m) } func (*AdminSplitResponse) ProtoMessage() {} func (*AdminSplitResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{32} + return fileDescriptor_api_6ead497ae315f5e8, []int{32} } func (m *AdminSplitResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1806,7 +1829,7 @@ func (m *AdminUnsplitRequest) Reset() { *m = AdminUnsplitRequest{} } func (m *AdminUnsplitRequest) String() string { return proto.CompactTextString(m) } func (*AdminUnsplitRequest) ProtoMessage() {} func (*AdminUnsplitRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{33} + return fileDescriptor_api_6ead497ae315f5e8, []int{33} } func (m *AdminUnsplitRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1841,7 +1864,7 @@ func (m *AdminUnsplitResponse) Reset() { *m = AdminUnsplitResponse{} } func (m *AdminUnsplitResponse) String() string { return proto.CompactTextString(m) } func (*AdminUnsplitResponse) ProtoMessage() {} func (*AdminUnsplitResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{34} + return fileDescriptor_api_6ead497ae315f5e8, []int{34} } func (m *AdminUnsplitResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1884,7 +1907,7 @@ func (m *AdminMergeRequest) Reset() { *m = AdminMergeRequest{} } func (m *AdminMergeRequest) String() string { return proto.CompactTextString(m) } func (*AdminMergeRequest) ProtoMessage() {} func (*AdminMergeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{35} + return fileDescriptor_api_6ead497ae315f5e8, []int{35} } func (m *AdminMergeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1919,7 +1942,7 @@ func (m *AdminMergeResponse) Reset() { *m = AdminMergeResponse{} } func (m *AdminMergeResponse) String() string { return proto.CompactTextString(m) } func (*AdminMergeResponse) ProtoMessage() {} func (*AdminMergeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{36} + return fileDescriptor_api_6ead497ae315f5e8, []int{36} } func (m *AdminMergeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1957,7 +1980,7 @@ func (m *AdminTransferLeaseRequest) Reset() { *m = AdminTransferLeaseReq func (m *AdminTransferLeaseRequest) String() string { return proto.CompactTextString(m) } func (*AdminTransferLeaseRequest) ProtoMessage() {} func (*AdminTransferLeaseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{37} + return fileDescriptor_api_6ead497ae315f5e8, []int{37} } func (m *AdminTransferLeaseRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1990,7 +2013,7 @@ func (m *AdminTransferLeaseResponse) Reset() { *m = AdminTransferLeaseRe func (m *AdminTransferLeaseResponse) String() string { return proto.CompactTextString(m) } func (*AdminTransferLeaseResponse) ProtoMessage() {} func (*AdminTransferLeaseResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{38} + return fileDescriptor_api_6ead497ae315f5e8, []int{38} } func (m *AdminTransferLeaseResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2025,7 +2048,7 @@ func (m *ReplicationChange) Reset() { *m = ReplicationChange{} } func (m *ReplicationChange) String() string { return proto.CompactTextString(m) } func (*ReplicationChange) ProtoMessage() {} func (*ReplicationChange) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{39} + return fileDescriptor_api_6ead497ae315f5e8, []int{39} } func (m *ReplicationChange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2083,7 +2106,7 @@ func (m *AdminChangeReplicasRequest) Reset() { *m = AdminChangeReplicasR func (m *AdminChangeReplicasRequest) String() string { return proto.CompactTextString(m) } func (*AdminChangeReplicasRequest) ProtoMessage() {} func (*AdminChangeReplicasRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{40} + return fileDescriptor_api_6ead497ae315f5e8, []int{40} } func (m *AdminChangeReplicasRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2118,7 +2141,7 @@ func (m *AdminChangeReplicasResponse) Reset() { *m = AdminChangeReplicas func (m *AdminChangeReplicasResponse) String() string { return proto.CompactTextString(m) } func (*AdminChangeReplicasResponse) ProtoMessage() {} func (*AdminChangeReplicasResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{41} + return fileDescriptor_api_6ead497ae315f5e8, []int{41} } func (m *AdminChangeReplicasResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2155,7 +2178,7 @@ func (m *AdminRelocateRangeRequest) Reset() { *m = AdminRelocateRangeReq func (m *AdminRelocateRangeRequest) String() string { return proto.CompactTextString(m) } func (*AdminRelocateRangeRequest) ProtoMessage() {} func (*AdminRelocateRangeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{42} + return fileDescriptor_api_6ead497ae315f5e8, []int{42} } func (m *AdminRelocateRangeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2188,7 +2211,7 @@ func (m *AdminRelocateRangeResponse) Reset() { *m = AdminRelocateRangeRe func (m *AdminRelocateRangeResponse) String() string { return proto.CompactTextString(m) } func (*AdminRelocateRangeResponse) ProtoMessage() {} func (*AdminRelocateRangeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{43} + return fileDescriptor_api_6ead497ae315f5e8, []int{43} } func (m *AdminRelocateRangeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2227,7 +2250,7 @@ func (m *HeartbeatTxnRequest) Reset() { *m = HeartbeatTxnRequest{} } func (m *HeartbeatTxnRequest) String() string { return proto.CompactTextString(m) } func (*HeartbeatTxnRequest) ProtoMessage() {} func (*HeartbeatTxnRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{44} + return fileDescriptor_api_6ead497ae315f5e8, []int{44} } func (m *HeartbeatTxnRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2264,7 +2287,7 @@ func (m *HeartbeatTxnResponse) Reset() { *m = HeartbeatTxnResponse{} } func (m *HeartbeatTxnResponse) String() string { return proto.CompactTextString(m) } func (*HeartbeatTxnResponse) ProtoMessage() {} func (*HeartbeatTxnResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{45} + return fileDescriptor_api_6ead497ae315f5e8, []int{45} } func (m *HeartbeatTxnResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2302,7 +2325,7 @@ func (m *GCRequest) Reset() { *m = GCRequest{} } func (m *GCRequest) String() string { return proto.CompactTextString(m) } func (*GCRequest) ProtoMessage() {} func (*GCRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{46} + return fileDescriptor_api_6ead497ae315f5e8, []int{46} } func (m *GCRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2336,7 +2359,7 @@ func (m *GCRequest_GCKey) Reset() { *m = GCRequest_GCKey{} } func (m *GCRequest_GCKey) String() string { return proto.CompactTextString(m) } func (*GCRequest_GCKey) ProtoMessage() {} func (*GCRequest_GCKey) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{46, 0} + return fileDescriptor_api_6ead497ae315f5e8, []int{46, 0} } func (m *GCRequest_GCKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2370,7 +2393,7 @@ func (m *GCResponse) Reset() { *m = GCResponse{} } func (m *GCResponse) String() string { return proto.CompactTextString(m) } func (*GCResponse) ProtoMessage() {} func (*GCResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{47} + return fileDescriptor_api_6ead497ae315f5e8, []int{47} } func (m *GCResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2439,7 +2462,7 @@ func (m *PushTxnRequest) Reset() { *m = PushTxnRequest{} } func (m *PushTxnRequest) String() string { return proto.CompactTextString(m) } func (*PushTxnRequest) ProtoMessage() {} func (*PushTxnRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{48} + return fileDescriptor_api_6ead497ae315f5e8, []int{48} } func (m *PushTxnRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2482,7 +2505,7 @@ func (m *PushTxnResponse) Reset() { *m = PushTxnResponse{} } func (m *PushTxnResponse) String() string { return proto.CompactTextString(m) } func (*PushTxnResponse) ProtoMessage() {} func (*PushTxnResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{49} + return fileDescriptor_api_6ead497ae315f5e8, []int{49} } func (m *PushTxnResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2529,7 +2552,7 @@ func (m *RecoverTxnRequest) Reset() { *m = RecoverTxnRequest{} } func (m *RecoverTxnRequest) String() string { return proto.CompactTextString(m) } func (*RecoverTxnRequest) ProtoMessage() {} func (*RecoverTxnRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{50} + return fileDescriptor_api_6ead497ae315f5e8, []int{50} } func (m *RecoverTxnRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2565,7 +2588,7 @@ func (m *RecoverTxnResponse) Reset() { *m = RecoverTxnResponse{} } func (m *RecoverTxnResponse) String() string { return proto.CompactTextString(m) } func (*RecoverTxnResponse) ProtoMessage() {} func (*RecoverTxnResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{51} + return fileDescriptor_api_6ead497ae315f5e8, []int{51} } func (m *RecoverTxnResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2609,7 +2632,7 @@ func (m *QueryTxnRequest) Reset() { *m = QueryTxnRequest{} } func (m *QueryTxnRequest) String() string { return proto.CompactTextString(m) } func (*QueryTxnRequest) ProtoMessage() {} func (*QueryTxnRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{52} + return fileDescriptor_api_6ead497ae315f5e8, []int{52} } func (m *QueryTxnRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2648,7 +2671,7 @@ func (m *QueryTxnResponse) Reset() { *m = QueryTxnResponse{} } func (m *QueryTxnResponse) String() string { return proto.CompactTextString(m) } func (*QueryTxnResponse) ProtoMessage() {} func (*QueryTxnResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{53} + return fileDescriptor_api_6ead497ae315f5e8, []int{53} } func (m *QueryTxnResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2708,7 +2731,7 @@ func (m *QueryIntentRequest) Reset() { *m = QueryIntentRequest{} } func (m *QueryIntentRequest) String() string { return proto.CompactTextString(m) } func (*QueryIntentRequest) ProtoMessage() {} func (*QueryIntentRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{54} + return fileDescriptor_api_6ead497ae315f5e8, []int{54} } func (m *QueryIntentRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2744,7 +2767,7 @@ func (m *QueryIntentResponse) Reset() { *m = QueryIntentResponse{} } func (m *QueryIntentResponse) String() string { return proto.CompactTextString(m) } func (*QueryIntentResponse) ProtoMessage() {} func (*QueryIntentResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{55} + return fileDescriptor_api_6ead497ae315f5e8, []int{55} } func (m *QueryIntentResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2790,7 +2813,7 @@ func (m *ResolveIntentRequest) Reset() { *m = ResolveIntentRequest{} } func (m *ResolveIntentRequest) String() string { return proto.CompactTextString(m) } func (*ResolveIntentRequest) ProtoMessage() {} func (*ResolveIntentRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{56} + return fileDescriptor_api_6ead497ae315f5e8, []int{56} } func (m *ResolveIntentRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2825,7 +2848,7 @@ func (m *ResolveIntentResponse) Reset() { *m = ResolveIntentResponse{} } func (m *ResolveIntentResponse) String() string { return proto.CompactTextString(m) } func (*ResolveIntentResponse) ProtoMessage() {} func (*ResolveIntentResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{57} + return fileDescriptor_api_6ead497ae315f5e8, []int{57} } func (m *ResolveIntentResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2875,7 +2898,7 @@ func (m *ResolveIntentRangeRequest) Reset() { *m = ResolveIntentRangeReq func (m *ResolveIntentRangeRequest) String() string { return proto.CompactTextString(m) } func (*ResolveIntentRangeRequest) ProtoMessage() {} func (*ResolveIntentRangeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{58} + return fileDescriptor_api_6ead497ae315f5e8, []int{58} } func (m *ResolveIntentRangeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2910,7 +2933,7 @@ func (m *ResolveIntentRangeResponse) Reset() { *m = ResolveIntentRangeRe func (m *ResolveIntentRangeResponse) String() string { return proto.CompactTextString(m) } func (*ResolveIntentRangeResponse) ProtoMessage() {} func (*ResolveIntentRangeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{59} + return fileDescriptor_api_6ead497ae315f5e8, []int{59} } func (m *ResolveIntentRangeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2947,7 +2970,7 @@ func (m *MergeRequest) Reset() { *m = MergeRequest{} } func (m *MergeRequest) String() string { return proto.CompactTextString(m) } func (*MergeRequest) ProtoMessage() {} func (*MergeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{60} + return fileDescriptor_api_6ead497ae315f5e8, []int{60} } func (m *MergeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2981,7 +3004,7 @@ func (m *MergeResponse) Reset() { *m = MergeResponse{} } func (m *MergeResponse) String() string { return proto.CompactTextString(m) } func (*MergeResponse) ProtoMessage() {} func (*MergeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{61} + return fileDescriptor_api_6ead497ae315f5e8, []int{61} } func (m *MergeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3026,7 +3049,7 @@ func (m *TruncateLogRequest) Reset() { *m = TruncateLogRequest{} } func (m *TruncateLogRequest) String() string { return proto.CompactTextString(m) } func (*TruncateLogRequest) ProtoMessage() {} func (*TruncateLogRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{62} + return fileDescriptor_api_6ead497ae315f5e8, []int{62} } func (m *TruncateLogRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3060,7 +3083,7 @@ func (m *TruncateLogResponse) Reset() { *m = TruncateLogResponse{} } func (m *TruncateLogResponse) String() string { return proto.CompactTextString(m) } func (*TruncateLogResponse) ProtoMessage() {} func (*TruncateLogResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{63} + return fileDescriptor_api_6ead497ae315f5e8, []int{63} } func (m *TruncateLogResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3104,7 +3127,7 @@ func (m *RequestLeaseRequest) Reset() { *m = RequestLeaseRequest{} } func (m *RequestLeaseRequest) String() string { return proto.CompactTextString(m) } func (*RequestLeaseRequest) ProtoMessage() {} func (*RequestLeaseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{64} + return fileDescriptor_api_6ead497ae315f5e8, []int{64} } func (m *RequestLeaseRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3153,7 +3176,7 @@ func (m *TransferLeaseRequest) Reset() { *m = TransferLeaseRequest{} } func (m *TransferLeaseRequest) String() string { return proto.CompactTextString(m) } func (*TransferLeaseRequest) ProtoMessage() {} func (*TransferLeaseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{65} + return fileDescriptor_api_6ead497ae315f5e8, []int{65} } func (m *TransferLeaseRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3190,7 +3213,7 @@ func (m *LeaseInfoRequest) Reset() { *m = LeaseInfoRequest{} } func (m *LeaseInfoRequest) String() string { return proto.CompactTextString(m) } func (*LeaseInfoRequest) ProtoMessage() {} func (*LeaseInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{66} + return fileDescriptor_api_6ead497ae315f5e8, []int{66} } func (m *LeaseInfoRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3227,7 +3250,7 @@ func (m *LeaseInfoResponse) Reset() { *m = LeaseInfoResponse{} } func (m *LeaseInfoResponse) String() string { return proto.CompactTextString(m) } func (*LeaseInfoResponse) ProtoMessage() {} func (*LeaseInfoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{67} + return fileDescriptor_api_6ead497ae315f5e8, []int{67} } func (m *LeaseInfoResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3262,7 +3285,7 @@ func (m *RequestLeaseResponse) Reset() { *m = RequestLeaseResponse{} } func (m *RequestLeaseResponse) String() string { return proto.CompactTextString(m) } func (*RequestLeaseResponse) ProtoMessage() {} func (*RequestLeaseResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{68} + return fileDescriptor_api_6ead497ae315f5e8, []int{68} } func (m *RequestLeaseResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3317,7 +3340,7 @@ func (m *ComputeChecksumRequest) Reset() { *m = ComputeChecksumRequest{} func (m *ComputeChecksumRequest) String() string { return proto.CompactTextString(m) } func (*ComputeChecksumRequest) ProtoMessage() {} func (*ComputeChecksumRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{69} + return fileDescriptor_api_6ead497ae315f5e8, []int{69} } func (m *ComputeChecksumRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3354,7 +3377,7 @@ func (m *ComputeChecksumResponse) Reset() { *m = ComputeChecksumResponse func (m *ComputeChecksumResponse) String() string { return proto.CompactTextString(m) } func (*ComputeChecksumResponse) ProtoMessage() {} func (*ComputeChecksumResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{70} + return fileDescriptor_api_6ead497ae315f5e8, []int{70} } func (m *ComputeChecksumResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3393,7 +3416,7 @@ func (m *ExternalStorage) Reset() { *m = ExternalStorage{} } func (m *ExternalStorage) String() string { return proto.CompactTextString(m) } func (*ExternalStorage) ProtoMessage() {} func (*ExternalStorage) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{71} + return fileDescriptor_api_6ead497ae315f5e8, []int{71} } func (m *ExternalStorage) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3427,7 +3450,7 @@ func (m *ExternalStorage_LocalFilePath) Reset() { *m = ExternalStorage_L func (m *ExternalStorage_LocalFilePath) String() string { return proto.CompactTextString(m) } func (*ExternalStorage_LocalFilePath) ProtoMessage() {} func (*ExternalStorage_LocalFilePath) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{71, 0} + return fileDescriptor_api_6ead497ae315f5e8, []int{71, 0} } func (m *ExternalStorage_LocalFilePath) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3460,7 +3483,7 @@ func (m *ExternalStorage_Http) Reset() { *m = ExternalStorage_Http{} } func (m *ExternalStorage_Http) String() string { return proto.CompactTextString(m) } func (*ExternalStorage_Http) ProtoMessage() {} func (*ExternalStorage_Http) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{71, 1} + return fileDescriptor_api_6ead497ae315f5e8, []int{71, 1} } func (m *ExternalStorage_Http) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3500,7 +3523,7 @@ func (m *ExternalStorage_S3) Reset() { *m = ExternalStorage_S3{} } func (m *ExternalStorage_S3) String() string { return proto.CompactTextString(m) } func (*ExternalStorage_S3) ProtoMessage() {} func (*ExternalStorage_S3) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{71, 2} + return fileDescriptor_api_6ead497ae315f5e8, []int{71, 2} } func (m *ExternalStorage_S3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3539,7 +3562,7 @@ func (m *ExternalStorage_GCS) Reset() { *m = ExternalStorage_GCS{} } func (m *ExternalStorage_GCS) String() string { return proto.CompactTextString(m) } func (*ExternalStorage_GCS) ProtoMessage() {} func (*ExternalStorage_GCS) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{71, 3} + return fileDescriptor_api_6ead497ae315f5e8, []int{71, 3} } func (m *ExternalStorage_GCS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3575,7 +3598,7 @@ func (m *ExternalStorage_Azure) Reset() { *m = ExternalStorage_Azure{} } func (m *ExternalStorage_Azure) String() string { return proto.CompactTextString(m) } func (*ExternalStorage_Azure) ProtoMessage() {} func (*ExternalStorage_Azure) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{71, 4} + return fileDescriptor_api_6ead497ae315f5e8, []int{71, 4} } func (m *ExternalStorage_Azure) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3614,7 +3637,7 @@ func (m *ExternalStorage_Workload) Reset() { *m = ExternalStorage_Worklo func (m *ExternalStorage_Workload) String() string { return proto.CompactTextString(m) } func (*ExternalStorage_Workload) ProtoMessage() {} func (*ExternalStorage_Workload) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{71, 5} + return fileDescriptor_api_6ead497ae315f5e8, []int{71, 5} } func (m *ExternalStorage_Workload) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3654,7 +3677,7 @@ func (m *WriteBatchRequest) Reset() { *m = WriteBatchRequest{} } func (m *WriteBatchRequest) String() string { return proto.CompactTextString(m) } func (*WriteBatchRequest) ProtoMessage() {} func (*WriteBatchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{72} + return fileDescriptor_api_6ead497ae315f5e8, []int{72} } func (m *WriteBatchRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3688,7 +3711,7 @@ func (m *WriteBatchResponse) Reset() { *m = WriteBatchResponse{} } func (m *WriteBatchResponse) String() string { return proto.CompactTextString(m) } func (*WriteBatchResponse) ProtoMessage() {} func (*WriteBatchResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{73} + return fileDescriptor_api_6ead497ae315f5e8, []int{73} } func (m *WriteBatchResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3722,7 +3745,7 @@ func (m *FileEncryptionOptions) Reset() { *m = FileEncryptionOptions{} } func (m *FileEncryptionOptions) String() string { return proto.CompactTextString(m) } func (*FileEncryptionOptions) ProtoMessage() {} func (*FileEncryptionOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{74} + return fileDescriptor_api_6ead497ae315f5e8, []int{74} } func (m *FileEncryptionOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3792,7 +3815,7 @@ func (m *ExportRequest) Reset() { *m = ExportRequest{} } func (m *ExportRequest) String() string { return proto.CompactTextString(m) } func (*ExportRequest) ProtoMessage() {} func (*ExportRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{75} + return fileDescriptor_api_6ead497ae315f5e8, []int{75} } func (m *ExportRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3844,7 +3867,7 @@ func (m *BulkOpSummary) Reset() { *m = BulkOpSummary{} } func (m *BulkOpSummary) String() string { return proto.CompactTextString(m) } func (*BulkOpSummary) ProtoMessage() {} func (*BulkOpSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{76} + return fileDescriptor_api_6ead497ae315f5e8, []int{76} } func (m *BulkOpSummary) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3880,7 +3903,7 @@ func (m *ExportResponse) Reset() { *m = ExportResponse{} } func (m *ExportResponse) String() string { return proto.CompactTextString(m) } func (*ExportResponse) ProtoMessage() {} func (*ExportResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{77} + return fileDescriptor_api_6ead497ae315f5e8, []int{77} } func (m *ExportResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3920,7 +3943,7 @@ func (m *ExportResponse_File) Reset() { *m = ExportResponse_File{} } func (m *ExportResponse_File) String() string { return proto.CompactTextString(m) } func (*ExportResponse_File) ProtoMessage() {} func (*ExportResponse_File) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{77, 0} + return fileDescriptor_api_6ead497ae315f5e8, []int{77, 0} } func (m *ExportResponse_File) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3971,7 +3994,7 @@ func (m *ImportRequest) Reset() { *m = ImportRequest{} } func (m *ImportRequest) String() string { return proto.CompactTextString(m) } func (*ImportRequest) ProtoMessage() {} func (*ImportRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{78} + return fileDescriptor_api_6ead497ae315f5e8, []int{78} } func (m *ImportRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4006,7 +4029,7 @@ func (m *ImportRequest_File) Reset() { *m = ImportRequest_File{} } func (m *ImportRequest_File) String() string { return proto.CompactTextString(m) } func (*ImportRequest_File) ProtoMessage() {} func (*ImportRequest_File) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{78, 0} + return fileDescriptor_api_6ead497ae315f5e8, []int{78, 0} } func (m *ImportRequest_File) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4042,7 +4065,7 @@ func (m *ImportRequest_TableRekey) Reset() { *m = ImportRequest_TableRek func (m *ImportRequest_TableRekey) String() string { return proto.CompactTextString(m) } func (*ImportRequest_TableRekey) ProtoMessage() {} func (*ImportRequest_TableRekey) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{78, 1} + return fileDescriptor_api_6ead497ae315f5e8, []int{78, 1} } func (m *ImportRequest_TableRekey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4077,7 +4100,7 @@ func (m *ImportResponse) Reset() { *m = ImportResponse{} } func (m *ImportResponse) String() string { return proto.CompactTextString(m) } func (*ImportResponse) ProtoMessage() {} func (*ImportResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{79} + return fileDescriptor_api_6ead497ae315f5e8, []int{79} } func (m *ImportResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4115,7 +4138,7 @@ func (m *AdminScatterRequest) Reset() { *m = AdminScatterRequest{} } func (m *AdminScatterRequest) String() string { return proto.CompactTextString(m) } func (*AdminScatterRequest) ProtoMessage() {} func (*AdminScatterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{80} + return fileDescriptor_api_6ead497ae315f5e8, []int{80} } func (m *AdminScatterRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4150,7 +4173,7 @@ func (m *AdminScatterResponse) Reset() { *m = AdminScatterResponse{} } func (m *AdminScatterResponse) String() string { return proto.CompactTextString(m) } func (*AdminScatterResponse) ProtoMessage() {} func (*AdminScatterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{81} + return fileDescriptor_api_6ead497ae315f5e8, []int{81} } func (m *AdminScatterResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4183,7 +4206,7 @@ func (m *AdminScatterResponse_Range) Reset() { *m = AdminScatterResponse func (m *AdminScatterResponse_Range) String() string { return proto.CompactTextString(m) } func (*AdminScatterResponse_Range) ProtoMessage() {} func (*AdminScatterResponse_Range) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{81, 0} + return fileDescriptor_api_6ead497ae315f5e8, []int{81, 0} } func (m *AdminScatterResponse_Range) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4228,7 +4251,7 @@ func (m *AdminVerifyProtectedTimestampRequest) Reset() { *m = AdminVerif func (m *AdminVerifyProtectedTimestampRequest) String() string { return proto.CompactTextString(m) } func (*AdminVerifyProtectedTimestampRequest) ProtoMessage() {} func (*AdminVerifyProtectedTimestampRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{82} + return fileDescriptor_api_6ead497ae315f5e8, []int{82} } func (m *AdminVerifyProtectedTimestampRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4266,7 +4289,7 @@ func (m *AdminVerifyProtectedTimestampResponse) Reset() { *m = AdminVeri func (m *AdminVerifyProtectedTimestampResponse) String() string { return proto.CompactTextString(m) } func (*AdminVerifyProtectedTimestampResponse) ProtoMessage() {} func (*AdminVerifyProtectedTimestampResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{83} + return fileDescriptor_api_6ead497ae315f5e8, []int{83} } func (m *AdminVerifyProtectedTimestampResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4319,7 +4342,7 @@ func (m *AddSSTableRequest) Reset() { *m = AddSSTableRequest{} } func (m *AddSSTableRequest) String() string { return proto.CompactTextString(m) } func (*AddSSTableRequest) ProtoMessage() {} func (*AddSSTableRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{84} + return fileDescriptor_api_6ead497ae315f5e8, []int{84} } func (m *AddSSTableRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4353,7 +4376,7 @@ func (m *AddSSTableResponse) Reset() { *m = AddSSTableResponse{} } func (m *AddSSTableResponse) String() string { return proto.CompactTextString(m) } func (*AddSSTableResponse) ProtoMessage() {} func (*AddSSTableResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{85} + return fileDescriptor_api_6ead497ae315f5e8, []int{85} } func (m *AddSSTableResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4397,7 +4420,7 @@ func (m *RefreshRequest) Reset() { *m = RefreshRequest{} } func (m *RefreshRequest) String() string { return proto.CompactTextString(m) } func (*RefreshRequest) ProtoMessage() {} func (*RefreshRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{86} + return fileDescriptor_api_6ead497ae315f5e8, []int{86} } func (m *RefreshRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4431,7 +4454,7 @@ func (m *RefreshResponse) Reset() { *m = RefreshResponse{} } func (m *RefreshResponse) String() string { return proto.CompactTextString(m) } func (*RefreshResponse) ProtoMessage() {} func (*RefreshResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{87} + return fileDescriptor_api_6ead497ae315f5e8, []int{87} } func (m *RefreshResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4470,7 +4493,7 @@ func (m *RefreshRangeRequest) Reset() { *m = RefreshRangeRequest{} } func (m *RefreshRangeRequest) String() string { return proto.CompactTextString(m) } func (*RefreshRangeRequest) ProtoMessage() {} func (*RefreshRangeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{88} + return fileDescriptor_api_6ead497ae315f5e8, []int{88} } func (m *RefreshRangeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4504,7 +4527,7 @@ func (m *RefreshRangeResponse) Reset() { *m = RefreshRangeResponse{} } func (m *RefreshRangeResponse) String() string { return proto.CompactTextString(m) } func (*RefreshRangeResponse) ProtoMessage() {} func (*RefreshRangeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{89} + return fileDescriptor_api_6ead497ae315f5e8, []int{89} } func (m *RefreshRangeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4553,7 +4576,7 @@ func (m *SubsumeRequest) Reset() { *m = SubsumeRequest{} } func (m *SubsumeRequest) String() string { return proto.CompactTextString(m) } func (*SubsumeRequest) ProtoMessage() {} func (*SubsumeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{90} + return fileDescriptor_api_6ead497ae315f5e8, []int{90} } func (m *SubsumeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4602,7 +4625,7 @@ func (m *SubsumeResponse) Reset() { *m = SubsumeResponse{} } func (m *SubsumeResponse) String() string { return proto.CompactTextString(m) } func (*SubsumeResponse) ProtoMessage() {} func (*SubsumeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{91} + return fileDescriptor_api_6ead497ae315f5e8, []int{91} } func (m *SubsumeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4637,7 +4660,7 @@ func (m *RangeStatsRequest) Reset() { *m = RangeStatsRequest{} } func (m *RangeStatsRequest) String() string { return proto.CompactTextString(m) } func (*RangeStatsRequest) ProtoMessage() {} func (*RangeStatsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{92} + return fileDescriptor_api_6ead497ae315f5e8, []int{92} } func (m *RangeStatsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4676,7 +4699,7 @@ func (m *RangeStatsResponse) Reset() { *m = RangeStatsResponse{} } func (m *RangeStatsResponse) String() string { return proto.CompactTextString(m) } func (*RangeStatsResponse) ProtoMessage() {} func (*RangeStatsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{93} + return fileDescriptor_api_6ead497ae315f5e8, []int{93} } func (m *RangeStatsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4759,7 +4782,7 @@ func (m *RequestUnion) Reset() { *m = RequestUnion{} } func (m *RequestUnion) String() string { return proto.CompactTextString(m) } func (*RequestUnion) ProtoMessage() {} func (*RequestUnion) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{94} + return fileDescriptor_api_6ead497ae315f5e8, []int{94} } func (m *RequestUnion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6209,7 +6232,7 @@ func (m *ResponseUnion) Reset() { *m = ResponseUnion{} } func (m *ResponseUnion) String() string { return proto.CompactTextString(m) } func (*ResponseUnion) ProtoMessage() {} func (*ResponseUnion) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{95} + return fileDescriptor_api_6ead497ae315f5e8, []int{95} } func (m *ResponseUnion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7655,7 +7678,7 @@ func (m *Header) Reset() { *m = Header{} } func (m *Header) String() string { return proto.CompactTextString(m) } func (*Header) ProtoMessage() {} func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{96} + return fileDescriptor_api_6ead497ae315f5e8, []int{96} } func (m *Header) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7691,7 +7714,7 @@ type BatchRequest struct { func (m *BatchRequest) Reset() { *m = BatchRequest{} } func (*BatchRequest) ProtoMessage() {} func (*BatchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{97} + return fileDescriptor_api_6ead497ae315f5e8, []int{97} } func (m *BatchRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7728,7 +7751,7 @@ type BatchResponse struct { func (m *BatchResponse) Reset() { *m = BatchResponse{} } func (*BatchResponse) ProtoMessage() {} func (*BatchResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{98} + return fileDescriptor_api_6ead497ae315f5e8, []int{98} } func (m *BatchResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7786,7 +7809,7 @@ func (m *BatchResponse_Header) Reset() { *m = BatchResponse_Header{} } func (m *BatchResponse_Header) String() string { return proto.CompactTextString(m) } func (*BatchResponse_Header) ProtoMessage() {} func (*BatchResponse_Header) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{98, 0} + return fileDescriptor_api_6ead497ae315f5e8, []int{98, 0} } func (m *BatchResponse_Header) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7825,7 +7848,7 @@ func (m *RangeFeedRequest) Reset() { *m = RangeFeedRequest{} } func (m *RangeFeedRequest) String() string { return proto.CompactTextString(m) } func (*RangeFeedRequest) ProtoMessage() {} func (*RangeFeedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{99} + return fileDescriptor_api_6ead497ae315f5e8, []int{99} } func (m *RangeFeedRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7866,7 +7889,7 @@ func (m *RangeFeedValue) Reset() { *m = RangeFeedValue{} } func (m *RangeFeedValue) String() string { return proto.CompactTextString(m) } func (*RangeFeedValue) ProtoMessage() {} func (*RangeFeedValue) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{100} + return fileDescriptor_api_6ead497ae315f5e8, []int{100} } func (m *RangeFeedValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7907,7 +7930,7 @@ func (m *RangeFeedCheckpoint) Reset() { *m = RangeFeedCheckpoint{} } func (m *RangeFeedCheckpoint) String() string { return proto.CompactTextString(m) } func (*RangeFeedCheckpoint) ProtoMessage() {} func (*RangeFeedCheckpoint) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{101} + return fileDescriptor_api_6ead497ae315f5e8, []int{101} } func (m *RangeFeedCheckpoint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7944,7 +7967,7 @@ func (m *RangeFeedError) Reset() { *m = RangeFeedError{} } func (m *RangeFeedError) String() string { return proto.CompactTextString(m) } func (*RangeFeedError) ProtoMessage() {} func (*RangeFeedError) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{102} + return fileDescriptor_api_6ead497ae315f5e8, []int{102} } func (m *RangeFeedError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7981,7 +8004,7 @@ func (m *RangeFeedEvent) Reset() { *m = RangeFeedEvent{} } func (m *RangeFeedEvent) String() string { return proto.CompactTextString(m) } func (*RangeFeedEvent) ProtoMessage() {} func (*RangeFeedEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_api_5d2d2e885d05d537, []int{103} + return fileDescriptor_api_6ead497ae315f5e8, []int{103} } func (m *RangeFeedEvent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8448,6 +8471,9 @@ func (this *ScanRequest) Equal(that interface{}) bool { if this.ScanFormat != that1.ScanFormat { return false } + if this.KeyLocking != that1.KeyLocking { + return false + } return true } func (this *ReverseScanRequest) Equal(that interface{}) bool { @@ -8475,6 +8501,9 @@ func (this *ReverseScanRequest) Equal(that interface{}) bool { if this.ScanFormat != that1.ScanFormat { return false } + if this.KeyLocking != that1.KeyLocking { + return false + } return true } func (this *CheckConsistencyRequest) Equal(that interface{}) bool { @@ -10910,6 +10939,11 @@ func (m *ScanRequest) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintApi(dAtA, i, uint64(m.ScanFormat)) } + if m.KeyLocking != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintApi(dAtA, i, uint64(m.KeyLocking)) + } return i, nil } @@ -10999,6 +11033,11 @@ func (m *ReverseScanRequest) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintApi(dAtA, i, uint64(m.ScanFormat)) } + if m.KeyLocking != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintApi(dAtA, i, uint64(m.KeyLocking)) + } return i, nil } @@ -16588,6 +16627,9 @@ func (m *ScanRequest) Size() (n int) { if m.ScanFormat != 0 { n += 1 + sovApi(uint64(m.ScanFormat)) } + if m.KeyLocking != 0 { + n += 1 + sovApi(uint64(m.KeyLocking)) + } return n } @@ -16631,6 +16673,9 @@ func (m *ReverseScanRequest) Size() (n int) { if m.ScanFormat != 0 { n += 1 + sovApi(uint64(m.ScanFormat)) } + if m.KeyLocking != 0 { + n += 1 + sovApi(uint64(m.KeyLocking)) + } return n } @@ -21793,6 +21838,25 @@ func (m *ScanRequest) Unmarshal(dAtA []byte) error { break } } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyLocking", wireType) + } + m.KeyLocking = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.KeyLocking |= (lock.Strength(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -22063,6 +22127,25 @@ func (m *ReverseScanRequest) Unmarshal(dAtA []byte) error { break } } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyLocking", wireType) + } + m.KeyLocking = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.KeyLocking |= (lock.Strength(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -37300,462 +37383,467 @@ var ( ErrIntOverflowApi = fmt.Errorf("proto: integer overflow") ) -func init() { proto.RegisterFile("roachpb/api.proto", fileDescriptor_api_5d2d2e885d05d537) } - -var fileDescriptor_api_5d2d2e885d05d537 = []byte{ - // 7260 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x5b, 0x6c, 0x23, 0xc9, - 0x75, 0xb6, 0x9a, 0xa4, 0x28, 0xf2, 0x90, 0xa2, 0x5a, 0xa5, 0xb9, 0x70, 0x34, 0xb3, 0x92, 0x86, - 0x3b, 0xb7, 0x1d, 0xef, 0x6a, 0x76, 0x66, 0xbc, 0xff, 0xae, 0x77, 0xd6, 0x6b, 0x4b, 0x14, 0x67, - 0xa8, 0xd1, 0x48, 0xa3, 0x6d, 0x52, 0xb3, 0xde, 0xb5, 0x17, 0xed, 0x56, 0x77, 0x89, 0x6a, 0x0f, - 0xd9, 0xcd, 0xe9, 0x6e, 0x8e, 0xa4, 0x01, 0x7e, 0xfc, 0x7f, 0x92, 0x07, 0x07, 0x4e, 0xb0, 0xc8, - 0x43, 0x10, 0x04, 0x76, 0x02, 0x2f, 0xe0, 0x00, 0x4e, 0x62, 0x38, 0x48, 0xf2, 0x96, 0xc0, 0x81, - 0xf3, 0x90, 0x00, 0x1b, 0x23, 0x01, 0x8c, 0x00, 0x81, 0x8d, 0x00, 0x11, 0x6c, 0x19, 0x08, 0x0c, - 0x3f, 0x04, 0xc8, 0x53, 0x80, 0x7d, 0x08, 0x82, 0xba, 0xf4, 0x8d, 0x6c, 0x5e, 0x24, 0xf7, 0x26, - 0x0b, 0xe4, 0x85, 0x60, 0x9f, 0xaa, 0x73, 0xba, 0xea, 0x54, 0xd5, 0xa9, 0xf3, 0x55, 0x9d, 0xaa, - 0x86, 0x69, 0xcb, 0x54, 0xd4, 0xdd, 0xf6, 0xf6, 0x0d, 0xa5, 0xad, 0x2f, 0xb6, 0x2d, 0xd3, 0x31, - 0xd1, 0xb4, 0x6a, 0xaa, 0x8f, 0x29, 0x79, 0x91, 0x27, 0xce, 0x22, 0x37, 0x97, 0xa6, 0x38, 0x0a, - 0xcb, 0x36, 0x7b, 0xca, 0xa5, 0x61, 0xcb, 0x32, 0x2d, 0x9b, 0x53, 0xcf, 0xb8, 0xd4, 0x16, 0x76, - 0x94, 0x40, 0xee, 0xf3, 0xb6, 0x63, 0x5a, 0x4a, 0x03, 0xdf, 0xc0, 0x46, 0x43, 0x37, 0x30, 0xc9, - 0xf0, 0x54, 0x55, 0x79, 0xe2, 0x85, 0xc8, 0xc4, 0xdb, 0x3c, 0xb5, 0xd8, 0x71, 0xf4, 0xe6, 0x8d, - 0xdd, 0xa6, 0x7a, 0xc3, 0xd1, 0x5b, 0xd8, 0x76, 0x94, 0x56, 0x9b, 0xa7, 0x2c, 0xd0, 0x14, 0xc7, - 0x52, 0x54, 0xdd, 0x68, 0xdc, 0xb0, 0xb0, 0x6a, 0x5a, 0x1a, 0xd6, 0x64, 0xbb, 0xad, 0x18, 0x6e, - 0x21, 0x1b, 0x66, 0xc3, 0xa4, 0x7f, 0x6f, 0x90, 0x7f, 0x8c, 0x5a, 0xfa, 0x7f, 0x90, 0x95, 0x14, - 0xa3, 0x81, 0x57, 0x8d, 0x1d, 0x13, 0xbd, 0x01, 0x29, 0x0d, 0xdb, 0x6a, 0x51, 0x58, 0x10, 0xae, - 0xe5, 0x6e, 0x95, 0x16, 0x7b, 0x6a, 0xbf, 0x48, 0xf3, 0xae, 0x60, 0x5b, 0xb5, 0xf4, 0xb6, 0x63, - 0x5a, 0xcb, 0xa9, 0x0f, 0x0f, 0xe7, 0xc7, 0x24, 0xca, 0x85, 0x3e, 0x0d, 0xe3, 0x4d, 0xac, 0xd8, - 0xb8, 0x98, 0xa0, 0xec, 0xc5, 0x08, 0xf6, 0x07, 0x24, 0x9d, 0x33, 0xb1, 0xcc, 0xa5, 0xef, 0x09, - 0x30, 0x29, 0xe1, 0x27, 0x1d, 0x6c, 0x3b, 0x55, 0xac, 0x68, 0xd8, 0x42, 0xe7, 0x20, 0xf9, 0x18, - 0x1f, 0x14, 0x93, 0x0b, 0xc2, 0xb5, 0xfc, 0xf2, 0xc4, 0x47, 0x87, 0xf3, 0xc9, 0x35, 0x7c, 0x20, - 0x11, 0x1a, 0x5a, 0x80, 0x09, 0x6c, 0x68, 0x32, 0x49, 0x4e, 0x85, 0x93, 0xd3, 0xd8, 0xd0, 0xd6, - 0xf0, 0x01, 0xfa, 0x12, 0x64, 0x6c, 0x22, 0xcd, 0x50, 0x71, 0x71, 0x7c, 0x41, 0xb8, 0x36, 0xbe, - 0xfc, 0xf9, 0x8f, 0x0e, 0xe7, 0xdf, 0x68, 0xe8, 0xce, 0x6e, 0x67, 0x7b, 0x51, 0x35, 0x5b, 0x37, - 0xbc, 0x52, 0x69, 0xdb, 0xfe, 0xff, 0x1b, 0xed, 0xc7, 0x8d, 0x1b, 0xdd, 0xaa, 0x5f, 0xac, 0xef, - 0x1b, 0x35, 0xfc, 0x44, 0xf2, 0x24, 0xbe, 0x9e, 0xfa, 0xf9, 0x07, 0xf3, 0xc2, 0xfd, 0x54, 0x46, - 0x10, 0x13, 0xf7, 0x53, 0x99, 0x84, 0x98, 0x2c, 0xbd, 0x9f, 0x84, 0x82, 0x84, 0xed, 0xb6, 0x69, - 0xd8, 0x98, 0x97, 0xff, 0x65, 0x48, 0x3a, 0xfb, 0x06, 0x2d, 0x7f, 0xee, 0xd6, 0x5c, 0x84, 0x16, - 0xea, 0x96, 0x62, 0xd8, 0x8a, 0xea, 0xe8, 0xa6, 0x21, 0x91, 0xac, 0xe8, 0x35, 0xc8, 0x59, 0xd8, - 0xee, 0xb4, 0x30, 0x6d, 0x2f, 0x5a, 0xb5, 0xdc, 0xad, 0xb3, 0x11, 0x9c, 0xb5, 0xb6, 0x62, 0x48, - 0xc0, 0xf2, 0x92, 0xff, 0xe8, 0x1c, 0x64, 0x8c, 0x4e, 0x8b, 0x28, 0xc4, 0xa6, 0xd5, 0x4d, 0x4a, - 0x13, 0x46, 0xa7, 0xb5, 0x86, 0x0f, 0x6c, 0x54, 0x86, 0x9c, 0x45, 0x5a, 0x4b, 0xd6, 0x8d, 0x1d, - 0xd3, 0x2e, 0xa6, 0x17, 0x92, 0xd7, 0x72, 0xb7, 0x2e, 0xf4, 0x6b, 0x53, 0xd2, 0xfe, 0xbc, 0x61, - 0xc0, 0x72, 0x09, 0x36, 0xaa, 0xc1, 0x24, 0x2f, 0x99, 0x85, 0x15, 0xdb, 0x34, 0x8a, 0x13, 0x0b, - 0xc2, 0xb5, 0xc2, 0xad, 0xc5, 0x28, 0x31, 0x21, 0x2d, 0x90, 0xc7, 0x4e, 0x0b, 0x4b, 0x94, 0x4b, - 0xca, 0x5b, 0x81, 0x27, 0x74, 0x1e, 0xb2, 0xa4, 0xd0, 0xdb, 0x07, 0x0e, 0xb6, 0x8b, 0x19, 0x5a, - 0x6a, 0x52, 0x8b, 0x65, 0xf2, 0x5c, 0x7a, 0x13, 0xf2, 0x41, 0x56, 0x84, 0xa0, 0x20, 0x55, 0x6a, - 0x5b, 0xeb, 0x15, 0x79, 0x6b, 0x63, 0x6d, 0xe3, 0xe1, 0xdb, 0x1b, 0xe2, 0x18, 0x3a, 0x05, 0x22, - 0xa7, 0xad, 0x55, 0xde, 0x91, 0x1f, 0xac, 0xae, 0xaf, 0xd6, 0x45, 0x61, 0x36, 0xf5, 0xeb, 0xdf, - 0x9a, 0x1b, 0x2b, 0x3d, 0x02, 0xb8, 0x87, 0x1d, 0xde, 0xa3, 0xd0, 0x32, 0xa4, 0x77, 0x69, 0x79, - 0x78, 0x9f, 0x5e, 0x88, 0x2c, 0x78, 0xa0, 0xf7, 0x2d, 0x67, 0x88, 0x0e, 0x7e, 0x78, 0x38, 0x2f, - 0x48, 0x9c, 0x93, 0x35, 0x7a, 0xe9, 0xfb, 0x02, 0xe4, 0xa8, 0x60, 0x56, 0x4b, 0x54, 0xee, 0x92, - 0x7c, 0x71, 0xa8, 0x4a, 0x7a, 0x45, 0xa3, 0x45, 0x18, 0x7f, 0xaa, 0x34, 0x3b, 0x83, 0x86, 0xcc, - 0x23, 0x92, 0x2e, 0xb1, 0x6c, 0xe8, 0x0e, 0xe4, 0x75, 0xc3, 0xc1, 0x86, 0x23, 0x33, 0xb6, 0xe4, - 0x10, 0xb6, 0x1c, 0xcb, 0x4d, 0x1f, 0x4a, 0x7f, 0x29, 0x00, 0x6c, 0x76, 0xe2, 0x54, 0x0d, 0x19, - 0xf2, 0x23, 0x95, 0xdf, 0x1d, 0xf2, 0xac, 0x16, 0x67, 0x20, 0xad, 0x1b, 0x4d, 0xdd, 0x60, 0xe5, - 0xcf, 0x48, 0xfc, 0x09, 0x9d, 0x82, 0xf1, 0xed, 0xa6, 0x6e, 0x68, 0x74, 0x00, 0x64, 0x24, 0xf6, - 0xc0, 0xd5, 0x2f, 0x41, 0x8e, 0x96, 0x3d, 0x46, 0xed, 0x97, 0xbe, 0x9e, 0x80, 0xd3, 0x65, 0xd3, - 0xd0, 0x74, 0x32, 0x12, 0x95, 0xe6, 0x27, 0x42, 0x37, 0xaf, 0x40, 0x16, 0xef, 0xb7, 0x47, 0x6c, - 0xde, 0x0c, 0xde, 0x6f, 0xd3, 0x7f, 0xd1, 0xaa, 0x43, 0x9f, 0x86, 0xb3, 0x4a, 0xb3, 0x69, 0xee, - 0xc9, 0xfa, 0x8e, 0xac, 0x99, 0xd8, 0x96, 0x0d, 0xd3, 0x91, 0xf1, 0xbe, 0x6e, 0x3b, 0xd4, 0x58, - 0x64, 0xa4, 0x19, 0x9a, 0xbc, 0xba, 0xb3, 0x62, 0x62, 0x7b, 0xc3, 0x74, 0x2a, 0x24, 0x89, 0x2b, - 0xfc, 0x3d, 0x38, 0xd3, 0xad, 0x9b, 0x38, 0x75, 0xff, 0x8f, 0x02, 0x14, 0x56, 0x0d, 0xdd, 0xf9, - 0x44, 0x28, 0xdd, 0xd3, 0x5e, 0x32, 0xa8, 0xbd, 0xeb, 0x20, 0xee, 0x28, 0x7a, 0xf3, 0xa1, 0x51, - 0x37, 0x5b, 0xdb, 0xb6, 0x63, 0x1a, 0xd8, 0xe6, 0xea, 0xed, 0xa1, 0x73, 0x9d, 0x3d, 0x82, 0x29, - 0xaf, 0x4e, 0x71, 0x2a, 0xeb, 0x19, 0x88, 0xab, 0x86, 0x6a, 0xe1, 0x16, 0x36, 0x62, 0xd5, 0xd6, - 0x05, 0xc8, 0xea, 0xae, 0x5c, 0xaa, 0xb1, 0xa4, 0xe4, 0x13, 0x78, 0x9d, 0x3a, 0x30, 0x1d, 0x78, - 0x77, 0x9c, 0xc6, 0x8f, 0x4c, 0x03, 0x78, 0x4f, 0xf6, 0xdb, 0x8b, 0x4c, 0x03, 0x78, 0x8f, 0x19, - 0xab, 0x77, 0x60, 0x72, 0x05, 0x37, 0xb1, 0x83, 0xe3, 0xb7, 0xe4, 0x5b, 0x50, 0x70, 0x45, 0xc7, - 0xd9, 0x48, 0xbf, 0x2f, 0x00, 0xe2, 0x72, 0xc9, 0xfc, 0x19, 0x67, 0x3b, 0xcd, 0x13, 0xff, 0xc0, - 0xe9, 0x58, 0x06, 0x9b, 0xe8, 0x59, 0x2f, 0x05, 0x46, 0xa2, 0x73, 0xbd, 0x6f, 0x51, 0x53, 0x41, - 0x8b, 0xea, 0xf9, 0x2b, 0xc4, 0x53, 0xd9, 0x83, 0x99, 0x50, 0xf1, 0xe2, 0x6d, 0xca, 0x14, 0x2d, - 0x59, 0x62, 0x21, 0x19, 0x74, 0xca, 0x28, 0xb1, 0xf4, 0x1e, 0x4c, 0x97, 0x9b, 0x58, 0xb1, 0xe2, - 0x56, 0x0b, 0x6f, 0xce, 0x77, 0x00, 0x05, 0xc5, 0xc7, 0xd9, 0xa4, 0x7f, 0x20, 0x00, 0x92, 0xf0, - 0x53, 0x6c, 0x39, 0xb1, 0x37, 0xe9, 0x0a, 0xe4, 0x1c, 0xc5, 0x6a, 0x60, 0x47, 0x26, 0x9e, 0x3c, - 0x37, 0x57, 0xcf, 0x05, 0x04, 0x11, 0x7f, 0x7e, 0x71, 0xb7, 0xa9, 0x2e, 0xd6, 0x5d, 0x4f, 0xdf, - 0x75, 0xcf, 0x18, 0x1f, 0x21, 0x73, 0x0d, 0xbc, 0x0b, 0x33, 0xa1, 0x52, 0xc6, 0xa9, 0x82, 0x6f, - 0x09, 0x90, 0xab, 0xa9, 0x8a, 0x11, 0x67, 0xdd, 0xdf, 0x84, 0x9c, 0xad, 0x2a, 0x86, 0xbc, 0x63, - 0x5a, 0x2d, 0xc5, 0xa1, 0x5d, 0xb6, 0x10, 0xaa, 0xbb, 0xe7, 0xee, 0xaa, 0x8a, 0x71, 0x97, 0x66, - 0x92, 0xc0, 0xf6, 0xfe, 0x07, 0x7b, 0xf5, 0xfd, 0x54, 0x26, 0x29, 0xa6, 0x4a, 0xff, 0x21, 0x40, - 0x9e, 0x95, 0x32, 0xce, 0x5e, 0xfd, 0x0a, 0xa4, 0x2c, 0x73, 0x8f, 0xf5, 0xea, 0xdc, 0xad, 0xf3, - 0x11, 0x22, 0xd6, 0xf0, 0x41, 0x70, 0x3a, 0xa1, 0xd9, 0xd1, 0x32, 0x70, 0xb7, 0x4b, 0xa6, 0xdc, - 0xc9, 0x51, 0xb9, 0x81, 0x71, 0x49, 0x44, 0xc6, 0x55, 0x98, 0xda, 0x56, 0x1c, 0x75, 0x57, 0xb6, - 0x78, 0x21, 0xc9, 0xd4, 0x93, 0xbc, 0x96, 0x97, 0x0a, 0x94, 0xec, 0x16, 0xdd, 0x2e, 0xfd, 0xb1, - 0xdb, 0x45, 0x6d, 0xfc, 0xc9, 0x6f, 0xa6, 0xff, 0x14, 0x78, 0x4f, 0x75, 0x0b, 0xfb, 0xbf, 0xad, - 0xb5, 0xbe, 0x99, 0x80, 0xb3, 0xe5, 0x5d, 0xac, 0x3e, 0x2e, 0x9b, 0x86, 0xad, 0xdb, 0x0e, 0x36, - 0xd4, 0x83, 0x38, 0x9b, 0xec, 0x3c, 0x64, 0xf7, 0x74, 0x67, 0x57, 0xd6, 0xf4, 0x9d, 0x1d, 0x6a, - 0x53, 0x32, 0x52, 0x86, 0x10, 0x56, 0xf4, 0x9d, 0x1d, 0x74, 0x1b, 0x52, 0x2d, 0x53, 0x63, 0x5e, - 0x65, 0xe1, 0xd6, 0x7c, 0x84, 0x78, 0x5a, 0x34, 0xbb, 0xd3, 0x5a, 0x37, 0x35, 0x2c, 0xd1, 0xcc, - 0x68, 0x0e, 0x40, 0x25, 0xd4, 0xb6, 0xa9, 0x1b, 0x0e, 0x9f, 0x5d, 0x02, 0x14, 0x54, 0x85, 0xac, - 0x83, 0xad, 0x96, 0x6e, 0x28, 0x0e, 0x01, 0xdc, 0x44, 0x79, 0x97, 0x22, 0x0b, 0xde, 0x6e, 0xea, - 0xaa, 0xd2, 0xb3, 0x72, 0xe0, 0x33, 0x73, 0x5b, 0xf6, 0x7e, 0x0a, 0x8a, 0xbd, 0x1a, 0x8a, 0xb3, - 0x9f, 0x6c, 0x42, 0x9a, 0xa0, 0xd1, 0xa6, 0xc3, 0x7b, 0xca, 0xad, 0x7e, 0x8a, 0x88, 0x28, 0x01, - 0x45, 0xb5, 0x4d, 0x87, 0x17, 0x9e, 0xcb, 0x99, 0xfd, 0x9e, 0x00, 0x69, 0x96, 0x80, 0x6e, 0x42, - 0x86, 0x83, 0x6e, 0x8d, 0x96, 0x31, 0xb9, 0x7c, 0xe6, 0xe8, 0x70, 0x7e, 0x82, 0x41, 0xec, 0x95, - 0x8f, 0xfc, 0xbf, 0xd2, 0x04, 0x43, 0xd9, 0x1a, 0x69, 0x33, 0xdb, 0x51, 0x2c, 0x87, 0xae, 0x6a, - 0x90, 0x36, 0xcb, 0x4b, 0x19, 0x4a, 0x58, 0xc3, 0x07, 0xe8, 0x3e, 0xa4, 0x6d, 0x47, 0x71, 0x3a, - 0x36, 0x6f, 0xb5, 0x63, 0x15, 0xb6, 0x46, 0x39, 0x25, 0x2e, 0x81, 0x38, 0x09, 0x1a, 0x76, 0x14, - 0xbd, 0x49, 0x9b, 0x31, 0x2b, 0xf1, 0xa7, 0xd2, 0x37, 0x04, 0x48, 0xb3, 0xac, 0xe8, 0x2c, 0xcc, - 0x48, 0x4b, 0x1b, 0xf7, 0x2a, 0xf2, 0xea, 0xc6, 0x4a, 0xa5, 0x5e, 0x91, 0xd6, 0x57, 0x37, 0x96, - 0xea, 0x15, 0x71, 0x0c, 0x9d, 0x01, 0xe4, 0x26, 0x94, 0x1f, 0x6e, 0xd4, 0x56, 0x6b, 0xf5, 0xca, - 0x46, 0x5d, 0x14, 0x28, 0x12, 0xa7, 0xf4, 0x00, 0x35, 0x81, 0x2e, 0xc1, 0x42, 0x37, 0x55, 0xae, - 0xd5, 0x97, 0xea, 0x35, 0xb9, 0x52, 0xab, 0xaf, 0xae, 0x2f, 0xd5, 0x2b, 0x2b, 0x62, 0x72, 0x40, - 0x2e, 0xf2, 0x12, 0x49, 0xaa, 0x94, 0xeb, 0x62, 0xaa, 0xf4, 0x0c, 0x4e, 0x4b, 0x58, 0x35, 0x5b, - 0xed, 0x8e, 0x83, 0x49, 0x29, 0xed, 0x38, 0xc7, 0xcb, 0x59, 0x98, 0xd0, 0xac, 0x03, 0xd9, 0xea, - 0x18, 0x7c, 0xb4, 0xa4, 0x35, 0xeb, 0x40, 0xea, 0x18, 0xbc, 0x33, 0xfe, 0xa9, 0x00, 0x67, 0xba, - 0x5f, 0x1e, 0x67, 0x57, 0x7c, 0x0b, 0x72, 0x8a, 0xa6, 0x61, 0x4d, 0xd6, 0x70, 0xd3, 0x51, 0xb8, - 0x13, 0x70, 0x3d, 0x20, 0x89, 0xaf, 0x48, 0x2d, 0x7a, 0x2b, 0x52, 0xeb, 0x8f, 0xca, 0x65, 0x5a, - 0x90, 0x15, 0xc2, 0xe1, 0x9a, 0x22, 0x2a, 0x84, 0x52, 0x4a, 0x7f, 0x9e, 0x82, 0xc9, 0x8a, 0xa1, - 0xd5, 0xf7, 0x63, 0x9d, 0x0a, 0xce, 0x40, 0x5a, 0x35, 0x5b, 0x2d, 0xdd, 0x71, 0xd5, 0xc4, 0x9e, - 0xd0, 0x67, 0x20, 0xa3, 0x61, 0x45, 0xf3, 0xb0, 0xfc, 0x30, 0x17, 0x46, 0xf2, 0xb2, 0xa3, 0x2f, - 0xc3, 0x59, 0x62, 0x41, 0x2d, 0x43, 0x69, 0xca, 0x4c, 0x9a, 0xec, 0x58, 0x7a, 0xa3, 0x81, 0x2d, - 0xbe, 0xfe, 0x75, 0x2d, 0xa2, 0x9c, 0xab, 0x9c, 0xa3, 0x4c, 0x19, 0xea, 0x2c, 0xbf, 0x74, 0x5a, - 0x8f, 0x22, 0xa3, 0x37, 0x00, 0x9a, 0xa6, 0xfa, 0x98, 0xae, 0xa9, 0xd9, 0xdc, 0x36, 0xf5, 0x5b, - 0x54, 0x73, 0xcd, 0x11, 0x61, 0x20, 0xcf, 0x36, 0xba, 0x41, 0x7c, 0xee, 0x27, 0x1d, 0xdd, 0xc2, - 0xf2, 0xcd, 0xb6, 0x5a, 0x4c, 0x93, 0x7a, 0x2f, 0x17, 0x8e, 0x0e, 0xe7, 0x41, 0x62, 0xe4, 0x9b, - 0x9b, 0x65, 0xe2, 0x83, 0xb3, 0xff, 0x6d, 0x15, 0x2d, 0xc3, 0x1c, 0x99, 0x2d, 0x79, 0x5d, 0x14, - 0x47, 0xde, 0xd5, 0x1b, 0xbb, 0xd8, 0x92, 0xbd, 0x95, 0x5a, 0xba, 0xd4, 0x95, 0x91, 0x66, 0x55, - 0xc5, 0x60, 0x05, 0x5d, 0x72, 0xaa, 0x34, 0x8b, 0xa7, 0x1e, 0xa2, 0xe7, 0xb6, 0xa9, 0xdb, 0xa6, - 0x51, 0xcc, 0x32, 0x3d, 0xb3, 0x27, 0xf4, 0x16, 0x88, 0xba, 0x21, 0xef, 0x34, 0xf5, 0xc6, 0xae, - 0x23, 0xef, 0x59, 0xba, 0x83, 0xed, 0xe2, 0x34, 0xad, 0x50, 0x54, 0xbf, 0xab, 0xf1, 0xe5, 0x4a, - 0xed, 0x6d, 0x92, 0x93, 0x57, 0xad, 0xa0, 0x1b, 0x77, 0x29, 0x3f, 0x25, 0xda, 0xde, 0xec, 0x3c, - 0x21, 0x66, 0x4a, 0xff, 0x22, 0x40, 0xc1, 0xed, 0x34, 0x71, 0xf6, 0xef, 0x6b, 0x20, 0x9a, 0x06, - 0x96, 0xdb, 0xbb, 0x8a, 0x8d, 0xb9, 0x62, 0xf8, 0x14, 0x52, 0x30, 0x0d, 0xbc, 0x49, 0xc8, 0x4c, - 0x13, 0x68, 0x13, 0xa6, 0x6d, 0x47, 0x69, 0xe8, 0x46, 0x23, 0xa0, 0xaf, 0xf1, 0xd1, 0x9d, 0x62, - 0x91, 0x73, 0x7b, 0xf4, 0x90, 0xdf, 0xf1, 0x23, 0x01, 0xa6, 0x97, 0xb4, 0x96, 0x6e, 0xd4, 0xda, - 0x4d, 0x3d, 0x56, 0x04, 0x7d, 0x09, 0xb2, 0x36, 0x91, 0xe9, 0x1b, 0x6f, 0x1f, 0xfd, 0x64, 0x68, - 0x0a, 0xb1, 0xe2, 0x0f, 0x60, 0x0a, 0xef, 0xb7, 0x75, 0x4b, 0x71, 0x74, 0xd3, 0x60, 0x0e, 0x7f, - 0x6a, 0xf4, 0xba, 0x15, 0x7c, 0x5e, 0xdf, 0xe9, 0xe7, 0x35, 0x7b, 0x07, 0x50, 0xb0, 0x62, 0x71, - 0x7a, 0xfe, 0x32, 0xcc, 0x50, 0xd1, 0x5b, 0x86, 0x1d, 0xb3, 0xd6, 0xb8, 0x75, 0xfd, 0x22, 0x9c, - 0x0a, 0xbf, 0x20, 0xce, 0xd2, 0xbf, 0xc7, 0x5b, 0x7c, 0x1d, 0x5b, 0x1f, 0x13, 0xe8, 0x0c, 0x8a, - 0x8f, 0xb3, 0xe4, 0x5f, 0x13, 0xe0, 0x1c, 0x95, 0x4d, 0xb7, 0x09, 0x76, 0xb0, 0x45, 0x37, 0x4d, - 0xe2, 0xec, 0xb4, 0xcf, 0x43, 0x9a, 0x61, 0x48, 0xda, 0x63, 0xc7, 0x97, 0x73, 0xc4, 0x2f, 0xa9, - 0x39, 0xa6, 0x45, 0xfc, 0x12, 0x9e, 0xc4, 0xeb, 0xa9, 0xc0, 0x6c, 0x54, 0x59, 0x62, 0x06, 0xd9, - 0xd3, 0xdc, 0x3d, 0x24, 0x5d, 0xbc, 0xbc, 0x4b, 0xfc, 0x22, 0x54, 0x81, 0x9c, 0x4a, 0xff, 0xc9, - 0xce, 0x41, 0x1b, 0x53, 0xf9, 0x85, 0x41, 0x9e, 0x25, 0x63, 0xab, 0x1f, 0xb4, 0x31, 0x71, 0x4f, - 0xdd, 0xff, 0x44, 0x5d, 0x81, 0xaa, 0x0e, 0xf4, 0x4d, 0xe9, 0xf8, 0xa2, 0x79, 0x5d, 0xf7, 0x2e, - 0xa4, 0x89, 0xbf, 0x48, 0x72, 0x55, 0xb0, 0x37, 0x71, 0xa6, 0x58, 0xbd, 0x91, 0x77, 0xe1, 0x8c, - 0x86, 0xdb, 0x16, 0x56, 0x15, 0x07, 0x6b, 0x72, 0xb0, 0xfa, 0x89, 0x63, 0x54, 0xff, 0x94, 0x2f, - 0xc3, 0xa7, 0xa2, 0x77, 0x00, 0x05, 0x64, 0xb3, 0x9a, 0xb9, 0x68, 0xe7, 0x38, 0x4a, 0x99, 0xf6, - 0xa5, 0x30, 0xba, 0x8d, 0xca, 0x90, 0xc1, 0xfb, 0x6d, 0x99, 0xee, 0x1c, 0xa6, 0x8e, 0xb9, 0x73, - 0x38, 0x81, 0xf7, 0xdb, 0x84, 0x88, 0xb6, 0xc8, 0x0c, 0xe7, 0xba, 0x03, 0xb4, 0xd8, 0xf6, 0x70, - 0x38, 0xe1, 0xf7, 0x17, 0x2e, 0x6e, 0xca, 0xf3, 0x04, 0x98, 0x08, 0xde, 0x76, 0x1f, 0x08, 0x70, - 0x3e, 0xb2, 0xed, 0xe2, 0x9c, 0xec, 0xdc, 0xcd, 0xd3, 0xc4, 0x49, 0x36, 0x4f, 0x4b, 0xdf, 0x71, - 0x47, 0xbd, 0x84, 0x9b, 0x26, 0x51, 0xef, 0xc7, 0xb0, 0xe2, 0x34, 0xe1, 0x36, 0x7b, 0xe2, 0xd8, - 0xcd, 0xee, 0xb2, 0x76, 0x99, 0x85, 0xae, 0xc2, 0xc6, 0x69, 0x16, 0x7e, 0x47, 0x80, 0x99, 0x2a, - 0x56, 0x2c, 0x67, 0x1b, 0x2b, 0x4e, 0xcc, 0xee, 0xec, 0x2b, 0x90, 0x34, 0xcc, 0xbd, 0xe3, 0x2c, - 0xba, 0x91, 0xfc, 0xfe, 0xb4, 0x15, 0x2e, 0x57, 0x9c, 0xb5, 0xfe, 0xbb, 0x04, 0x64, 0xef, 0x95, - 0xe3, 0xac, 0xeb, 0x1b, 0x7c, 0x69, 0x96, 0x0d, 0xf5, 0xa8, 0x6e, 0xe9, 0xbd, 0x6f, 0xf1, 0x5e, - 0x79, 0x0d, 0x1f, 0xb8, 0xdd, 0x92, 0x70, 0xa1, 0x25, 0xc8, 0x3a, 0xbb, 0x16, 0xb6, 0x77, 0xcd, - 0xa6, 0x76, 0x1c, 0x9f, 0xc5, 0xe7, 0x9a, 0x7d, 0x0c, 0xe3, 0x54, 0xae, 0xbb, 0xaf, 0x2f, 0x44, - 0xec, 0xeb, 0x93, 0xd7, 0x78, 0x6e, 0x5f, 0xe2, 0x38, 0xaf, 0x71, 0x09, 0xac, 0x71, 0x3c, 0xdf, - 0x68, 0x5c, 0x4c, 0x97, 0xde, 0x02, 0x20, 0x55, 0x8b, 0xb3, 0x79, 0x7e, 0x33, 0x09, 0x85, 0xcd, - 0x8e, 0xbd, 0x1b, 0x73, 0x7f, 0x2c, 0x03, 0xb4, 0x3b, 0x36, 0x05, 0x0b, 0xfb, 0x06, 0xaf, 0xff, - 0x90, 0xc0, 0x01, 0x57, 0x01, 0x8c, 0xaf, 0xbe, 0x6f, 0xa0, 0x2a, 0x17, 0x82, 0x65, 0x3f, 0xfa, - 0xe0, 0xf9, 0x41, 0x58, 0xb2, 0xbe, 0x6f, 0xac, 0x63, 0x0f, 0x44, 0x32, 0x49, 0x98, 0x48, 0x7a, - 0x03, 0x26, 0xc8, 0x83, 0xec, 0x98, 0xc7, 0x69, 0xf2, 0x34, 0xe1, 0xa9, 0x9b, 0xe8, 0x0e, 0x64, - 0x19, 0x37, 0x99, 0xb8, 0xd2, 0x74, 0xe2, 0x8a, 0xaa, 0x0b, 0x57, 0x23, 0x9d, 0xb2, 0x32, 0x94, - 0x95, 0x4c, 0x53, 0xa7, 0x60, 0x7c, 0xc7, 0xb4, 0x54, 0x4c, 0xe3, 0x0c, 0x32, 0x12, 0x7b, 0x08, - 0xb6, 0xea, 0xfd, 0x54, 0x26, 0x23, 0x66, 0xef, 0xa7, 0x32, 0x59, 0x11, 0x4a, 0xdf, 0x10, 0x60, - 0xca, 0x6b, 0x8e, 0x38, 0x6d, 0x79, 0x39, 0xa4, 0xcb, 0xe3, 0x37, 0x08, 0x51, 0x63, 0xe9, 0x1f, - 0xa8, 0x63, 0xa3, 0x9a, 0x4f, 0x69, 0xfb, 0xc4, 0xd9, 0x5f, 0xee, 0xb0, 0x08, 0x93, 0xc4, 0x71, - 0xdb, 0x98, 0x06, 0x9b, 0xdc, 0x84, 0x53, 0x7a, 0x8b, 0x58, 0x79, 0xdd, 0x69, 0x1e, 0x70, 0x54, - 0xe6, 0x60, 0x77, 0xef, 0x73, 0xc6, 0x4f, 0x2b, 0xbb, 0x49, 0xdc, 0xf0, 0xb1, 0xdd, 0x10, 0xbf, - 0x3e, 0x71, 0x2a, 0x7c, 0x15, 0x26, 0x2d, 0x26, 0x9a, 0x78, 0x27, 0xc7, 0xd4, 0x79, 0xde, 0x63, - 0x25, 0x6a, 0xff, 0x76, 0x02, 0xa6, 0xde, 0xea, 0x60, 0xeb, 0xe0, 0x93, 0xa4, 0xf4, 0x2b, 0x30, - 0xb5, 0xa7, 0xe8, 0x8e, 0xbc, 0x63, 0x5a, 0x72, 0xa7, 0xad, 0x29, 0x8e, 0x1b, 0xfb, 0x30, 0x49, - 0xc8, 0x77, 0x4d, 0x6b, 0x8b, 0x12, 0x11, 0x06, 0xf4, 0xd8, 0x30, 0xf7, 0x0c, 0x99, 0x90, 0x29, - 0x1a, 0xde, 0x37, 0xf8, 0x62, 0xf2, 0xf2, 0xab, 0xff, 0x7c, 0x38, 0x7f, 0x7b, 0xa4, 0x40, 0x26, - 0x1a, 0x0b, 0xd6, 0xe9, 0xe8, 0xda, 0xe2, 0xd6, 0xd6, 0xea, 0x8a, 0x24, 0x52, 0x91, 0x6f, 0x33, - 0x89, 0xf5, 0x7d, 0xc3, 0x9d, 0xc5, 0x3f, 0x12, 0x40, 0xf4, 0x35, 0x15, 0x67, 0x73, 0x56, 0x20, - 0xf7, 0xa4, 0x83, 0x2d, 0xfd, 0x04, 0x8d, 0x09, 0x9c, 0x91, 0x18, 0xa2, 0x77, 0x21, 0x1f, 0xd2, - 0x43, 0xf2, 0x97, 0xd3, 0x43, 0x6e, 0xcf, 0x57, 0x41, 0xe9, 0x6f, 0x05, 0x40, 0xb4, 0xf2, 0xab, - 0x6c, 0x1d, 0xff, 0x93, 0xd2, 0x53, 0xae, 0x81, 0x48, 0xa3, 0x08, 0x65, 0x7d, 0x47, 0x6e, 0xe9, - 0xb6, 0xad, 0x1b, 0x0d, 0xde, 0x55, 0x0a, 0x94, 0xbe, 0xba, 0xb3, 0xce, 0xa8, 0xbc, 0x11, 0xff, - 0x2f, 0xcc, 0x84, 0xaa, 0x11, 0x67, 0x33, 0x5e, 0x84, 0xfc, 0x8e, 0xd9, 0x31, 0x34, 0x99, 0xed, - 0x75, 0xf0, 0xc5, 0xbf, 0x1c, 0xa5, 0xb1, 0xf7, 0x95, 0xfe, 0x3d, 0x01, 0xa7, 0x24, 0x6c, 0x9b, - 0xcd, 0xa7, 0x38, 0x7e, 0x45, 0x56, 0x81, 0xef, 0xb2, 0xc8, 0x27, 0xd2, 0x67, 0x96, 0x31, 0xb3, - 0x29, 0x2d, 0xbc, 0x8e, 0x7e, 0x69, 0x70, 0x5f, 0xec, 0x5d, 0x39, 0xe7, 0xcb, 0x72, 0xa9, 0xd0, - 0xb2, 0x9c, 0x09, 0x53, 0x7a, 0xc3, 0x30, 0x89, 0xcd, 0xb2, 0xf1, 0x13, 0xa3, 0xd3, 0x72, 0x31, - 0xcb, 0xe2, 0xa0, 0x42, 0xae, 0x32, 0x96, 0x1a, 0x7e, 0xb2, 0xd1, 0x69, 0x51, 0xcf, 0x79, 0xf9, - 0x0c, 0x29, 0xef, 0xd1, 0xe1, 0x7c, 0x21, 0x94, 0x66, 0x4b, 0x05, 0xdd, 0x7b, 0x26, 0xd2, 0x79, - 0x93, 0x7f, 0x09, 0x4e, 0x77, 0xa9, 0x3c, 0x4e, 0x1f, 0xe7, 0xaf, 0x93, 0x70, 0x2e, 0x2c, 0x3e, - 0x6e, 0x24, 0xf2, 0x49, 0x6f, 0xd6, 0x2a, 0x4c, 0xb6, 0x74, 0xe3, 0x64, 0x0b, 0x91, 0xf9, 0x96, - 0x6e, 0xf8, 0xeb, 0xb9, 0x11, 0x1d, 0x24, 0xfd, 0xdf, 0xd0, 0x41, 0x14, 0x98, 0x8d, 0x6a, 0xc1, - 0x38, 0x7b, 0xc9, 0xfb, 0x02, 0xe4, 0xe3, 0x5e, 0x5b, 0x3b, 0x59, 0xf4, 0x16, 0xaf, 0x73, 0x1d, - 0x26, 0x3f, 0x86, 0xc5, 0xb8, 0x6f, 0x0b, 0x80, 0xea, 0x56, 0xc7, 0x20, 0x20, 0xf7, 0x81, 0xd9, - 0x88, 0xb3, 0xb2, 0xa7, 0x60, 0x5c, 0x37, 0x34, 0xbc, 0x4f, 0x2b, 0x9b, 0x92, 0xd8, 0x43, 0x68, - 0x03, 0x31, 0x39, 0xd2, 0x06, 0xa2, 0x1f, 0x04, 0x12, 0x2a, 0x68, 0x9c, 0x5a, 0xf8, 0x93, 0x04, - 0xcc, 0xf0, 0xea, 0xc4, 0xbe, 0x18, 0x79, 0xa2, 0xa8, 0x71, 0xf4, 0x59, 0x80, 0xb6, 0x85, 0x9f, - 0xca, 0x8c, 0x35, 0x39, 0x12, 0x6b, 0x96, 0x70, 0x50, 0x02, 0xfa, 0x02, 0x4c, 0x91, 0x11, 0xde, - 0xb6, 0xcc, 0xb6, 0x69, 0x13, 0x27, 0xc5, 0x1e, 0x0d, 0xe9, 0x4c, 0x1f, 0x1d, 0xce, 0x4f, 0xae, - 0xeb, 0xc6, 0x26, 0x67, 0xac, 0xd7, 0x24, 0x62, 0x2a, 0xbc, 0x47, 0x77, 0x00, 0xfe, 0x93, 0x00, - 0xa7, 0x3e, 0xb6, 0xe5, 0xdb, 0xff, 0x09, 0x8d, 0x79, 0x33, 0x8f, 0x48, 0x1f, 0x57, 0x8d, 0x1d, - 0x33, 0xfe, 0x45, 0xf5, 0xf7, 0x05, 0x98, 0x0e, 0x88, 0x8f, 0xd3, 0x93, 0x39, 0xd9, 0xd9, 0x84, - 0x2f, 0x12, 0xdf, 0x26, 0xd8, 0xed, 0xe3, 0x1c, 0x54, 0x7f, 0x95, 0x80, 0x33, 0x65, 0xb6, 0xb5, - 0xec, 0xc6, 0x5d, 0xc4, 0xd9, 0x4b, 0x8a, 0x30, 0xf1, 0x14, 0x5b, 0xb6, 0x6e, 0xb2, 0x19, 0x76, - 0x52, 0x72, 0x1f, 0xd1, 0x2c, 0x64, 0x6c, 0x43, 0x69, 0xdb, 0xbb, 0xa6, 0xbb, 0x1b, 0xe7, 0x3d, - 0x7b, 0x31, 0x22, 0xe3, 0x27, 0x8f, 0x11, 0x49, 0x0f, 0x8e, 0x11, 0x99, 0xf8, 0xa5, 0x63, 0x44, - 0xf8, 0xd6, 0xd7, 0x0f, 0x04, 0x38, 0xdb, 0xa3, 0xbf, 0x38, 0xfb, 0xcc, 0x57, 0x20, 0xa7, 0x72, - 0xc1, 0xc4, 0x1a, 0xb3, 0xdd, 0xbd, 0x55, 0x92, 0xed, 0x84, 0x00, 0xe4, 0xe8, 0x70, 0x1e, 0xdc, - 0xa2, 0xae, 0xae, 0x70, 0x15, 0x91, 0xff, 0x5a, 0xe9, 0x37, 0x72, 0x30, 0x55, 0xd9, 0x67, 0x6b, - 0xd7, 0x35, 0xe6, 0x0f, 0xa0, 0xbb, 0x90, 0x69, 0x5b, 0xe6, 0x53, 0xdd, 0xad, 0x46, 0x21, 0x14, - 0x1a, 0xe0, 0x56, 0xa3, 0x8b, 0x6b, 0x93, 0x73, 0x48, 0x1e, 0x2f, 0xaa, 0x43, 0xf6, 0x81, 0xa9, - 0x2a, 0xcd, 0xbb, 0x7a, 0xd3, 0xed, 0xff, 0x2f, 0x0f, 0x17, 0xb4, 0xe8, 0xf1, 0x6c, 0x2a, 0xce, - 0xae, 0xdb, 0x14, 0x1e, 0x11, 0xad, 0x42, 0xa6, 0xea, 0x38, 0x6d, 0x92, 0xc8, 0xad, 0xc9, 0xd5, - 0x11, 0x84, 0x12, 0x16, 0x2e, 0xcb, 0x63, 0x47, 0x75, 0x98, 0xbe, 0x67, 0x9a, 0x8d, 0x26, 0x2e, - 0x37, 0xcd, 0x8e, 0x56, 0x36, 0x8d, 0x1d, 0xbd, 0xc1, 0xed, 0xf1, 0x95, 0x11, 0x64, 0xde, 0x2b, - 0xd7, 0xa4, 0x5e, 0x01, 0x68, 0x09, 0x32, 0xb5, 0xdb, 0x5c, 0x18, 0x73, 0xe0, 0x2e, 0x8f, 0x20, - 0xac, 0x76, 0x5b, 0xf2, 0xd8, 0xd0, 0x7d, 0xc8, 0x2d, 0x3d, 0xeb, 0x58, 0x98, 0x4b, 0x49, 0xf7, - 0x8d, 0x4b, 0xe8, 0x96, 0x42, 0xb9, 0xa4, 0x20, 0x33, 0xaa, 0x41, 0xe1, 0x6d, 0xd3, 0x7a, 0xdc, - 0x34, 0x15, 0xb7, 0x86, 0x13, 0x54, 0xdc, 0xa7, 0x46, 0x10, 0xe7, 0x32, 0x4a, 0x5d, 0x22, 0x66, - 0xbf, 0x00, 0x93, 0xa1, 0x66, 0x42, 0x08, 0x52, 0x6d, 0xd2, 0x22, 0x02, 0x8d, 0xf0, 0xa1, 0xff, - 0xd1, 0x4b, 0x30, 0x61, 0x98, 0x1a, 0x76, 0xfb, 0xf0, 0xe4, 0xf2, 0xa9, 0xa3, 0xc3, 0xf9, 0xf4, - 0x86, 0xa9, 0x31, 0x87, 0x82, 0xff, 0x93, 0xd2, 0x24, 0x93, 0xeb, 0x4e, 0xcc, 0x5e, 0x81, 0x14, - 0x69, 0x1f, 0x62, 0x46, 0xb6, 0x15, 0x1b, 0x6f, 0x59, 0x3a, 0x97, 0xe9, 0x3e, 0xf2, 0x7c, 0x3f, - 0x16, 0x20, 0x51, 0xbb, 0x4d, 0x5c, 0xe9, 0xed, 0x8e, 0xfa, 0x18, 0x3b, 0x3c, 0x17, 0x7f, 0xa2, - 0x2e, 0xb6, 0x85, 0x77, 0x74, 0xe6, 0xe5, 0x64, 0x25, 0xfe, 0x84, 0x9e, 0x03, 0x50, 0x54, 0x15, - 0xdb, 0xb6, 0xec, 0x1e, 0xf5, 0xca, 0x4a, 0x59, 0x46, 0x59, 0xc3, 0x07, 0x84, 0xcd, 0xc6, 0xaa, - 0x85, 0x1d, 0x37, 0x54, 0x89, 0x3d, 0x11, 0x36, 0x07, 0xb7, 0xda, 0xb2, 0x63, 0x3e, 0xc6, 0x06, - 0x6d, 0xd5, 0x2c, 0x31, 0x0f, 0xad, 0x76, 0x9d, 0x10, 0x88, 0x65, 0xc3, 0x86, 0xe6, 0x9b, 0xa1, - 0xac, 0xe4, 0x3d, 0x13, 0x91, 0x16, 0x6e, 0xe8, 0xfc, 0x08, 0x53, 0x56, 0xe2, 0x4f, 0x44, 0x63, - 0x4a, 0xc7, 0xd9, 0xa5, 0xc1, 0x19, 0x59, 0x89, 0xfe, 0xe7, 0x55, 0xfb, 0xba, 0x00, 0xc9, 0x7b, - 0xe5, 0xda, 0xb1, 0xeb, 0xe6, 0x4a, 0x4c, 0xfa, 0x12, 0x69, 0x84, 0xa0, 0xde, 0x6c, 0xea, 0x46, - 0x83, 0x38, 0x1d, 0x5f, 0xc1, 0xaa, 0x5b, 0xb3, 0x02, 0x27, 0x6f, 0x32, 0x2a, 0x5a, 0x80, 0x9c, - 0x6a, 0x61, 0x0d, 0x1b, 0x8e, 0xae, 0x34, 0x6d, 0x5e, 0xc5, 0x20, 0x89, 0x17, 0xee, 0xab, 0x02, - 0x8c, 0xd3, 0xee, 0x85, 0x2e, 0x40, 0x56, 0x35, 0x0d, 0x47, 0xd1, 0x0d, 0x6e, 0x27, 0xb2, 0x92, - 0x4f, 0xe8, 0x5b, 0xc8, 0x8b, 0x90, 0x57, 0x54, 0xd5, 0xec, 0x18, 0x8e, 0x6c, 0x28, 0x2d, 0xcc, - 0x0b, 0x9b, 0xe3, 0xb4, 0x0d, 0xa5, 0x85, 0xd1, 0x3c, 0xb8, 0x8f, 0xde, 0x81, 0xbb, 0xac, 0x04, - 0x9c, 0xb4, 0x86, 0x0f, 0x78, 0x49, 0x7e, 0x20, 0x40, 0xc6, 0xed, 0x96, 0xa4, 0x30, 0x0d, 0x6c, - 0x60, 0x4b, 0x71, 0x4c, 0xaf, 0x30, 0x1e, 0xa1, 0x7b, 0x4e, 0xca, 0xfa, 0x73, 0xd2, 0x29, 0x18, - 0x77, 0x94, 0xed, 0xa6, 0x5b, 0x0e, 0xf6, 0x40, 0x57, 0x83, 0x9b, 0x4a, 0x83, 0x2d, 0x80, 0x65, - 0x25, 0xf6, 0x40, 0xaa, 0xc4, 0x43, 0x52, 0x99, 0x76, 0xf8, 0x13, 0x29, 0x2f, 0x8b, 0xc2, 0xdc, - 0xc6, 0x0d, 0xdd, 0xa0, 0x1d, 0x20, 0x29, 0x01, 0x25, 0x2d, 0x13, 0x0a, 0x3a, 0x0f, 0x59, 0x96, - 0x01, 0x1b, 0x1a, 0xed, 0x05, 0x49, 0x29, 0x43, 0x09, 0x15, 0xf7, 0x98, 0x11, 0x77, 0x44, 0xbe, - 0x2b, 0xc0, 0x34, 0x8b, 0x9d, 0x61, 0xe1, 0x9b, 0xf1, 0xcd, 0xca, 0xaf, 0x43, 0x56, 0x53, 0x1c, - 0x85, 0x9d, 0xf3, 0x4b, 0x0c, 0x3c, 0xe7, 0xe7, 0x9a, 0x49, 0x92, 0x9f, 0x9e, 0xf5, 0x43, 0x90, - 0x22, 0xff, 0xd9, 0xc1, 0x48, 0x89, 0xfe, 0xf7, 0xa3, 0x11, 0x82, 0xc5, 0x8d, 0xd3, 0x4b, 0xb9, - 0x01, 0xa7, 0x89, 0x71, 0xa9, 0x18, 0xaa, 0x75, 0xd0, 0x26, 0x18, 0xfa, 0x21, 0xfd, 0xb5, 0x91, - 0x18, 0xd8, 0xcd, 0xa1, 0x9b, 0x38, 0xbc, 0x2c, 0x7f, 0x93, 0x86, 0xc9, 0xca, 0x7e, 0xdb, 0xb4, - 0x62, 0x5d, 0x09, 0x5a, 0x86, 0x09, 0x0e, 0x93, 0x07, 0xec, 0xaf, 0x76, 0x99, 0x4d, 0x77, 0xeb, - 0x92, 0x33, 0xa2, 0x65, 0x00, 0x16, 0x68, 0x49, 0x03, 0x70, 0x92, 0xc7, 0xd8, 0x65, 0xa2, 0x6c, - 0x84, 0x8a, 0x36, 0x20, 0xd7, 0x7a, 0xaa, 0xaa, 0xf2, 0x8e, 0xde, 0x74, 0x78, 0xa4, 0x5a, 0x74, - 0x4c, 0xf4, 0xfa, 0xa3, 0x72, 0xf9, 0x2e, 0xcd, 0xc4, 0x82, 0xc6, 0xfc, 0x67, 0x09, 0x88, 0x04, - 0xf6, 0x1f, 0xbd, 0x08, 0xfc, 0x18, 0x87, 0x6c, 0xbb, 0x87, 0xb2, 0x96, 0x27, 0x8f, 0x0e, 0xe7, - 0xb3, 0x12, 0xa5, 0xd6, 0x6a, 0x75, 0x29, 0xcb, 0x32, 0xd4, 0x6c, 0x07, 0x3d, 0x0f, 0x93, 0x66, - 0x4b, 0x77, 0x64, 0xd7, 0x71, 0xe0, 0xbe, 0x56, 0x9e, 0x10, 0x5d, 0xc7, 0x02, 0xd5, 0xe1, 0x2a, - 0x36, 0xc8, 0xf0, 0xa1, 0xf5, 0x94, 0xb7, 0xd9, 0x02, 0x9e, 0xc3, 0x86, 0xa0, 0x6c, 0xb6, 0x1d, - 0xbd, 0xa5, 0x3f, 0xa3, 0x3b, 0xbc, 0x7c, 0x93, 0xe5, 0x79, 0x96, 0x9d, 0xd4, 0x6f, 0x99, 0xae, - 0xec, 0xf1, 0xbc, 0x0f, 0x03, 0x59, 0xd1, 0x57, 0x05, 0x38, 0xc3, 0x15, 0x29, 0x6f, 0x1f, 0xc8, - 0x4d, 0x32, 0xeb, 0xe8, 0xce, 0x81, 0xfc, 0xf8, 0x69, 0x31, 0x43, 0x3d, 0xba, 0xcf, 0x44, 0x36, - 0x48, 0xa0, 0x1f, 0x2c, 0xba, 0xcd, 0x72, 0xf0, 0x80, 0x33, 0xaf, 0x3d, 0xad, 0x18, 0x8e, 0x75, - 0xb0, 0x7c, 0xf6, 0xe8, 0x70, 0x7e, 0xa6, 0x37, 0xf5, 0x91, 0x34, 0x63, 0xf7, 0xb2, 0xa0, 0x2a, - 0x00, 0xf6, 0x7a, 0x23, 0x8d, 0x93, 0x8b, 0x9e, 0x93, 0x23, 0xbb, 0xad, 0x14, 0xe0, 0x45, 0xd7, - 0x40, 0xe4, 0x67, 0x30, 0x76, 0xf4, 0x26, 0x96, 0x6d, 0xfd, 0x19, 0x2e, 0x02, 0x35, 0x0b, 0x05, - 0x46, 0x27, 0x22, 0x6a, 0xfa, 0x33, 0x3c, 0xfb, 0x15, 0x28, 0xf6, 0x2b, 0x7d, 0x70, 0x20, 0x64, - 0xd9, 0x6e, 0xe6, 0x6b, 0xe1, 0x65, 0x8c, 0x11, 0xba, 0xaa, 0xbb, 0x94, 0x91, 0x78, 0xcd, 0x35, - 0x41, 0xdf, 0x49, 0xc0, 0xe4, 0x72, 0xa7, 0xf9, 0xf8, 0x61, 0xbb, 0xd6, 0x69, 0xb5, 0x14, 0xeb, - 0x80, 0x58, 0x2f, 0x66, 0x3a, 0x48, 0x31, 0x05, 0x66, 0xbd, 0xa8, 0x6d, 0xd0, 0x9f, 0x61, 0x32, - 0xbf, 0x04, 0xc2, 0x3b, 0x78, 0x1c, 0x3c, 0xad, 0x89, 0x4f, 0xa6, 0xa1, 0xea, 0xaf, 0x41, 0x31, - 0x90, 0x91, 0xae, 0x39, 0xc8, 0xd8, 0x70, 0x2c, 0x1d, 0xb3, 0x35, 0xb4, 0xa4, 0x14, 0x88, 0x41, - 0x59, 0x25, 0xc9, 0x15, 0x96, 0x8a, 0xea, 0x90, 0x27, 0x19, 0x0f, 0x64, 0x6a, 0xff, 0xdd, 0x95, - 0xce, 0x9b, 0x11, 0x95, 0x0b, 0x95, 0x7b, 0x91, 0x6a, 0xa9, 0x4c, 0x79, 0xe8, 0x5f, 0x29, 0x87, - 0x7d, 0xca, 0xec, 0x9b, 0x20, 0x76, 0x67, 0x08, 0x6a, 0x34, 0xc5, 0x34, 0x7a, 0x2a, 0xa8, 0xd1, - 0x64, 0x40, 0x5b, 0xf7, 0x53, 0x99, 0x94, 0x38, 0x5e, 0xfa, 0x69, 0x12, 0x0a, 0x6e, 0x67, 0x8b, - 0x13, 0x02, 0x2c, 0xc3, 0x38, 0xe9, 0x1a, 0x6e, 0xc4, 0xc4, 0x95, 0x01, 0x7d, 0x9c, 0xc7, 0x5c, - 0x93, 0x2e, 0xe3, 0x82, 0x48, 0xca, 0x1a, 0x87, 0xd9, 0x99, 0xfd, 0x95, 0x04, 0xa4, 0xa8, 0xd7, - 0x7d, 0x13, 0x52, 0x74, 0xea, 0x10, 0x46, 0x99, 0x3a, 0x68, 0x56, 0xcf, 0x25, 0x4c, 0x04, 0x5c, - 0x42, 0xe2, 0x5f, 0xed, 0x2a, 0xaf, 0xdc, 0xbc, 0x45, 0x4d, 0x4e, 0x5e, 0xe2, 0x4f, 0x68, 0x99, - 0x86, 0xf2, 0x98, 0x96, 0x83, 0x35, 0xee, 0xed, 0x2e, 0x0c, 0x6b, 0x5f, 0x77, 0x9a, 0x72, 0xf9, - 0xd0, 0x39, 0x48, 0x12, 0x5b, 0x36, 0xc1, 0xb6, 0xf9, 0x8f, 0x0e, 0xe7, 0x93, 0xc4, 0x8a, 0x11, - 0x1a, 0xba, 0x01, 0xb9, 0xb0, 0xe1, 0x10, 0xae, 0x65, 0x99, 0x79, 0x0c, 0x0c, 0x7a, 0x68, 0x7a, - 0x03, 0x8c, 0x21, 0x3d, 0xde, 0xc6, 0xff, 0x7f, 0x1c, 0x26, 0x57, 0x5b, 0x71, 0x4f, 0x2c, 0x4b, - 0xe1, 0x16, 0x8e, 0x82, 0x08, 0xa1, 0x97, 0x46, 0x34, 0x70, 0x68, 0x4e, 0x4f, 0x1e, 0x6f, 0x4e, - 0x5f, 0x25, 0x5e, 0x29, 0x3f, 0xbd, 0x9f, 0xec, 0x83, 0x06, 0xc2, 0xef, 0xaf, 0x13, 0x5b, 0x2d, - 0x11, 0x1e, 0xff, 0x14, 0x02, 0x0d, 0xd5, 0x78, 0x93, 0x3a, 0xbf, 0xac, 0x97, 0xa5, 0x47, 0xef, - 0x65, 0x13, 0xd8, 0xd0, 0xe8, 0xd4, 0x16, 0xb6, 0xab, 0x13, 0x27, 0xb7, 0xab, 0xb3, 0xcf, 0x78, - 0x67, 0x7d, 0x1d, 0x92, 0x9a, 0x6e, 0x0d, 0xb8, 0x4d, 0x22, 0x7a, 0xc2, 0x26, 0x4c, 0x43, 0x7a, - 0x6d, 0x2a, 0xd8, 0x6b, 0x83, 0xab, 0x02, 0xb3, 0x0f, 0x01, 0x7c, 0x0d, 0xa1, 0x05, 0x48, 0x9b, - 0x4d, 0xcd, 0x3d, 0x8c, 0x31, 0xb9, 0x9c, 0x3d, 0x3a, 0x9c, 0x1f, 0x7f, 0xd8, 0xd4, 0x56, 0x57, - 0xa4, 0x71, 0xb3, 0xa9, 0xad, 0x6a, 0xf4, 0x02, 0x05, 0xbc, 0x27, 0x7b, 0x91, 0x5b, 0x79, 0x69, - 0xc2, 0xc0, 0x7b, 0x2b, 0xd8, 0x56, 0xbb, 0x22, 0x4a, 0x48, 0x17, 0xfc, 0xa6, 0x00, 0x05, 0xb7, - 0x35, 0xe2, 0x35, 0x33, 0x19, 0xbd, 0xc5, 0x87, 0x5d, 0xf2, 0x78, 0xc3, 0xce, 0xe5, 0xe3, 0x87, - 0x3c, 0xbf, 0x26, 0xf0, 0xa8, 0xdd, 0x9a, 0xaa, 0x38, 0xc4, 0xd9, 0x88, 0x71, 0xa8, 0xbc, 0x00, - 0xa2, 0xa5, 0x18, 0x9a, 0xd9, 0xd2, 0x9f, 0x61, 0xb6, 0x8c, 0x68, 0xf3, 0x1d, 0xc1, 0x29, 0x8f, - 0x4e, 0xd7, 0xc9, 0xdc, 0x55, 0xd0, 0x5f, 0x08, 0x3c, 0xc2, 0xd7, 0x2b, 0x4c, 0x9c, 0x4a, 0x5b, - 0x83, 0xb4, 0xc5, 0xe2, 0x04, 0xd9, 0xd0, 0x7d, 0x29, 0x42, 0x48, 0xd4, 0xdb, 0x59, 0x18, 0x9e, - 0x37, 0x78, 0xa8, 0x88, 0xd9, 0xcf, 0xc3, 0x38, 0x25, 0x9f, 0xc0, 0xc0, 0x72, 0xcd, 0xff, 0x6b, - 0x02, 0x2e, 0xd1, 0xd7, 0x3d, 0xc2, 0x96, 0xbe, 0x73, 0xb0, 0x69, 0x99, 0x0e, 0x56, 0x1d, 0xac, - 0xf9, 0x67, 0x1f, 0x62, 0xb5, 0x5a, 0xd9, 0xb6, 0xfb, 0x82, 0x63, 0xc5, 0x4b, 0x79, 0x5c, 0x68, - 0x0d, 0xa6, 0xd8, 0x2d, 0x31, 0xb2, 0xd2, 0xd4, 0x9f, 0x62, 0x59, 0x71, 0x8e, 0x33, 0x37, 0x4d, - 0x32, 0xde, 0x25, 0xc2, 0xba, 0xe4, 0x20, 0x0d, 0xb2, 0x5c, 0x98, 0xae, 0xf1, 0x9b, 0x59, 0xee, - 0xfd, 0x72, 0x0b, 0x65, 0x19, 0x89, 0xca, 0x5b, 0x5d, 0x91, 0x32, 0x4c, 0xb2, 0xb7, 0xd1, 0xf1, - 0x23, 0x01, 0x2e, 0x0f, 0x51, 0x74, 0x9c, 0xdd, 0x6c, 0x16, 0x32, 0x4f, 0xc9, 0x8b, 0x74, 0xae, - 0xe9, 0x8c, 0xe4, 0x3d, 0xa3, 0x75, 0x98, 0xdc, 0x51, 0xf4, 0x26, 0xf1, 0xb8, 0x58, 0x4f, 0xec, - 0x1f, 0x64, 0x17, 0x1d, 0xfb, 0x99, 0x67, 0xec, 0x34, 0x91, 0x9e, 0x0e, 0x9c, 0x5e, 0xd2, 0xb4, - 0x5a, 0x8d, 0x5b, 0xb0, 0xf8, 0xfa, 0x8b, 0x0b, 0x1d, 0x13, 0x3e, 0x74, 0x44, 0x2f, 0x01, 0xd2, - 0x74, 0x9b, 0xdd, 0x0f, 0x61, 0xef, 0x2a, 0x9a, 0xb9, 0xe7, 0x87, 0x1a, 0x4c, 0xbb, 0x29, 0x35, - 0x37, 0x01, 0xd5, 0x80, 0xe2, 0x16, 0xd9, 0x76, 0x14, 0x6f, 0xb7, 0xe4, 0xf2, 0x48, 0x47, 0x95, - 0x18, 0xa0, 0xf1, 0x1e, 0xa5, 0x2c, 0x91, 0x43, 0xff, 0x12, 0x0f, 0x5c, 0x27, 0x55, 0x77, 0x64, - 0xc5, 0x76, 0xcf, 0xb5, 0xb0, 0x9b, 0x29, 0x0a, 0x8c, 0xbe, 0x64, 0x07, 0x8f, 0xab, 0xb0, 0xb0, - 0x7b, 0x5f, 0x41, 0x71, 0x02, 0xdd, 0x3f, 0x14, 0xa0, 0x20, 0xe1, 0x1d, 0x0b, 0xdb, 0xb1, 0x02, - 0xfe, 0xbb, 0x90, 0xb7, 0x98, 0x54, 0x79, 0xc7, 0x32, 0x5b, 0xc7, 0x19, 0x63, 0x39, 0xce, 0x78, - 0xd7, 0x32, 0x5b, 0xa1, 0x93, 0xfc, 0x8f, 0x60, 0xca, 0x2b, 0x69, 0x9c, 0x2a, 0xf8, 0x2e, 0x3d, - 0x9e, 0xcb, 0x04, 0xc7, 0xbd, 0xe7, 0xff, 0x71, 0xe8, 0x81, 0x6e, 0xcf, 0x04, 0x8b, 0x1b, 0xa7, - 0x32, 0x7e, 0x21, 0x40, 0xa1, 0xd6, 0xd9, 0x66, 0x37, 0x11, 0xc5, 0xa7, 0x87, 0x0a, 0x64, 0x9b, - 0x78, 0xc7, 0x91, 0x4f, 0x14, 0x2a, 0x9e, 0x21, 0xac, 0x34, 0x5c, 0xfe, 0x1e, 0x80, 0x45, 0x0f, - 0x83, 0x51, 0x39, 0xc9, 0x63, 0xca, 0xc9, 0x52, 0x5e, 0xdf, 0xc9, 0x29, 0x7d, 0x37, 0x01, 0x53, - 0x5e, 0x65, 0xe3, 0xb4, 0x9e, 0x6f, 0x87, 0xac, 0x46, 0xf2, 0x38, 0x56, 0x63, 0x9a, 0x87, 0x3c, - 0x44, 0x5b, 0x8e, 0x45, 0x98, 0xa1, 0x2e, 0x88, 0xac, 0xb4, 0xdb, 0x4d, 0xdd, 0x85, 0xb2, 0xd4, - 0x2e, 0xa5, 0xa4, 0x69, 0x9a, 0xb4, 0xc4, 0x52, 0x28, 0x88, 0x25, 0xfd, 0x6f, 0xc7, 0xc2, 0xf8, - 0x19, 0x96, 0x29, 0xaa, 0x3a, 0x4e, 0x48, 0x47, 0x8e, 0x31, 0xd6, 0x08, 0x1f, 0xef, 0x79, 0xef, - 0xc1, 0x34, 0xd5, 0x6c, 0xdc, 0x07, 0x52, 0x79, 0x73, 0xfc, 0x44, 0x00, 0x14, 0x94, 0xff, 0xf1, - 0xb5, 0x48, 0x22, 0xbe, 0x16, 0x79, 0x11, 0x10, 0x0b, 0xdd, 0xb3, 0xe5, 0x36, 0xb6, 0x64, 0x1b, - 0xab, 0x26, 0xbf, 0x51, 0x47, 0x90, 0x44, 0x9e, 0xb2, 0x89, 0xad, 0x1a, 0xa5, 0x97, 0xde, 0x9f, - 0x85, 0x3c, 0x57, 0xc6, 0x96, 0xa1, 0x9b, 0x06, 0xba, 0x09, 0xc9, 0x06, 0x5f, 0x62, 0xcf, 0x45, - 0xae, 0xa8, 0xf9, 0xb7, 0x7a, 0x55, 0xc7, 0x24, 0x92, 0x97, 0xb0, 0xb4, 0x3b, 0x4e, 0x84, 0xff, - 0xe3, 0xc7, 0x18, 0x07, 0x59, 0xda, 0x1d, 0x07, 0xd5, 0x60, 0x4a, 0xf5, 0x6f, 0x35, 0x92, 0x09, - 0x7b, 0xb2, 0x2f, 0xd2, 0x89, 0xbc, 0x1b, 0xaa, 0x3a, 0x26, 0x15, 0xd4, 0x50, 0x02, 0x2a, 0x07, - 0xaf, 0xd1, 0x49, 0xf5, 0x84, 0x33, 0xf9, 0x87, 0x57, 0xc3, 0x57, 0xf8, 0x54, 0xc7, 0x02, 0xb7, - 0xed, 0xa0, 0xd7, 0x21, 0xad, 0xd1, 0xeb, 0x59, 0x78, 0xd7, 0x8c, 0xea, 0x3d, 0xa1, 0x1b, 0x71, - 0xaa, 0x63, 0x12, 0xe7, 0x40, 0xf7, 0x21, 0xcf, 0xfe, 0x31, 0x3f, 0x84, 0xc3, 0xbf, 0xcb, 0xfd, - 0x25, 0x04, 0xac, 0x7b, 0x75, 0x4c, 0xca, 0x69, 0x3e, 0x15, 0x7d, 0x1a, 0x52, 0xb6, 0xaa, 0xb8, - 0x00, 0x70, 0xae, 0xcf, 0x75, 0x0f, 0x3e, 0x33, 0xcd, 0x8d, 0xee, 0xb0, 0x8b, 0xf9, 0x9c, 0x7d, - 0x77, 0x45, 0x2e, 0xaa, 0xf8, 0xa1, 0x73, 0xc9, 0xa4, 0xf8, 0x98, 0x12, 0xd0, 0x3d, 0xc8, 0x29, - 0xc4, 0xa1, 0x93, 0xe9, 0x39, 0x40, 0xba, 0x04, 0x17, 0xbd, 0x43, 0xdc, 0x73, 0x86, 0xb3, 0x4a, - 0x0f, 0x3f, 0xbb, 0x44, 0x5f, 0x50, 0x0b, 0x5b, 0x0d, 0x5c, 0xcc, 0x0d, 0x16, 0x14, 0x0c, 0x5f, - 0xf2, 0x04, 0x51, 0x22, 0x71, 0xec, 0x76, 0xdd, 0x33, 0x1e, 0xb4, 0x52, 0xf9, 0xbe, 0xbb, 0x91, - 0x11, 0x67, 0x54, 0xaa, 0x63, 0x52, 0x7e, 0x37, 0x40, 0x46, 0x8b, 0x90, 0x68, 0xa8, 0xc5, 0x49, - 0x2a, 0xe3, 0xc2, 0xa0, 0x13, 0x18, 0xd5, 0x31, 0x29, 0xd1, 0x50, 0x09, 0x94, 0x67, 0x21, 0xf4, - 0xfb, 0x46, 0xb1, 0xd0, 0x77, 0xa8, 0x87, 0x0f, 0x22, 0x54, 0xc7, 0x24, 0x1a, 0xb5, 0x4f, 0xde, - 0xb7, 0x09, 0x05, 0x8b, 0xc5, 0x7f, 0xb9, 0x91, 0x9b, 0x62, 0xdf, 0x1d, 0xda, 0xa8, 0xe0, 0xcd, - 0x2a, 0x75, 0xf0, 0x03, 0x74, 0xf4, 0x65, 0x38, 0x15, 0x96, 0xc8, 0x7b, 0xda, 0x34, 0x95, 0xfb, - 0xe2, 0x50, 0xb9, 0xe1, 0x0e, 0x87, 0xac, 0x9e, 0x44, 0xf4, 0x2a, 0x8c, 0xb3, 0x56, 0x43, 0x54, - 0x64, 0x54, 0xe8, 0x41, 0x57, 0x83, 0xb1, 0xfc, 0xa4, 0xf3, 0x3b, 0x3c, 0xf0, 0x49, 0x6e, 0x9a, - 0x8d, 0xe2, 0x4c, 0xdf, 0xce, 0xdf, 0x1b, 0xc8, 0x45, 0x3a, 0xbf, 0xe3, 0x53, 0x49, 0xbb, 0x5b, - 0x2c, 0x85, 0xc7, 0xc9, 0x9c, 0xea, 0xdb, 0xee, 0x11, 0xf1, 0x50, 0x55, 0x1a, 0x8a, 0xee, 0x93, - 0x49, 0xd1, 0x2c, 0x76, 0xdd, 0x89, 0x4c, 0xc7, 0xd4, 0xe9, 0xbe, 0x45, 0xeb, 0xbd, 0xc2, 0xa5, - 0x4a, 0x1d, 0x1f, 0x8f, 0x8a, 0x1e, 0x81, 0xc8, 0x2f, 0x22, 0xf0, 0x97, 0xff, 0xcf, 0x50, 0x79, - 0x2f, 0x44, 0x9a, 0xae, 0xa8, 0xc0, 0x92, 0xea, 0x98, 0x34, 0xa5, 0x86, 0x53, 0xd0, 0x3b, 0x30, - 0x4d, 0xe5, 0xc9, 0xaa, 0x7f, 0x83, 0x44, 0xb1, 0xd8, 0x73, 0x13, 0x41, 0xff, 0xcb, 0x26, 0x5c, - 0xc9, 0xa2, 0xda, 0x95, 0x44, 0xba, 0xb1, 0x6e, 0xe8, 0x0e, 0xb5, 0xb2, 0xb3, 0x7d, 0xbb, 0x71, - 0xf8, 0x16, 0x38, 0xd2, 0x8d, 0x75, 0x46, 0x21, 0xdd, 0xd8, 0xe1, 0x41, 0x54, 0xbc, 0x39, 0x2e, - 0xf4, 0xed, 0xc6, 0x51, 0xd1, 0x56, 0xa4, 0x1b, 0x3b, 0x41, 0x3a, 0xe9, 0xc6, 0xcc, 0x40, 0x74, - 0xc9, 0x7d, 0xae, 0x6f, 0x37, 0xee, 0x7b, 0x12, 0x97, 0x74, 0x63, 0xa5, 0x27, 0x11, 0xad, 0x00, - 0x30, 0xbf, 0x44, 0x37, 0x76, 0xcc, 0xe2, 0x5c, 0xdf, 0xc9, 0xa0, 0x3b, 0x8c, 0x8a, 0x4c, 0x06, - 0x4d, 0x97, 0x46, 0x0c, 0x19, 0x45, 0x43, 0x32, 0xdd, 0x9e, 0x2c, 0xce, 0xf7, 0x35, 0x64, 0x3d, - 0xbb, 0x94, 0xc4, 0x90, 0xed, 0x79, 0x44, 0x32, 0xab, 0xb0, 0x85, 0xd9, 0xe2, 0x42, 0x7f, 0xb3, - 0x1c, 0xdc, 0xa5, 0xa1, 0x66, 0x99, 0x12, 0xd0, 0x12, 0x64, 0xc9, 0xb4, 0x7d, 0x40, 0xcd, 0xd0, - 0xc5, 0xbe, 0x2e, 0x66, 0xd7, 0x59, 0x8b, 0xea, 0x98, 0x94, 0x79, 0xc2, 0x49, 0xe4, 0xf5, 0x6c, - 0x81, 0xaa, 0x58, 0xea, 0xfb, 0xfa, 0xd0, 0xf2, 0x26, 0x79, 0x3d, 0xe3, 0x40, 0x2a, 0x9c, 0x66, - 0x6d, 0xc5, 0x0f, 0xc2, 0x5a, 0xfc, 0xd4, 0x66, 0xf1, 0x79, 0x2a, 0xaa, 0xef, 0x72, 0x4f, 0xe4, - 0xf9, 0xdc, 0xea, 0x98, 0x34, 0xa3, 0xf4, 0xa6, 0x92, 0x01, 0xcf, 0xa7, 0x1e, 0xb6, 0x48, 0x54, - 0xbc, 0xd4, 0x77, 0xc0, 0x47, 0x2c, 0xab, 0x91, 0x01, 0xaf, 0x04, 0xc8, 0x6c, 0x02, 0xd2, 0x64, - 0xdb, 0x66, 0x9b, 0xd9, 0x97, 0x07, 0x4c, 0x40, 0x5d, 0x30, 0x9f, 0x4d, 0x40, 0x5a, 0x8d, 0x71, - 0x12, 0x41, 0x6a, 0x13, 0x2b, 0x16, 0x37, 0xb3, 0x57, 0xfa, 0x0a, 0xea, 0xb9, 0x59, 0x8d, 0x08, - 0x52, 0x3d, 0x22, 0x71, 0x78, 0x2c, 0xf7, 0x06, 0x13, 0xee, 0xf3, 0x5d, 0xed, 0xeb, 0xf0, 0x44, - 0x5e, 0xb4, 0x42, 0x1c, 0x1e, 0x2b, 0x94, 0x80, 0x3e, 0x0b, 0x13, 0x1c, 0x93, 0x15, 0xaf, 0x0d, - 0xf0, 0x44, 0x83, 0x60, 0x9a, 0x8c, 0x6b, 0xce, 0xc3, 0xac, 0x2c, 0xc3, 0x82, 0xac, 0x7a, 0x2f, - 0x0c, 0xb0, 0xb2, 0x3d, 0x70, 0x94, 0x59, 0x59, 0x9f, 0x4c, 0xac, 0x2c, 0xeb, 0xa7, 0x7c, 0xae, - 0xbb, 0xde, 0xd7, 0xca, 0xf6, 0x9e, 0xf7, 0x20, 0x56, 0xf6, 0x89, 0x4f, 0x25, 0x35, 0xb3, 0x19, - 0x0e, 0x2a, 0x7e, 0xaa, 0x6f, 0xcd, 0xc2, 0xb0, 0x90, 0xd4, 0x8c, 0xf3, 0x90, 0x66, 0x63, 0xd1, - 0xbb, 0x4c, 0xd3, 0x2f, 0xf6, 0x3f, 0x73, 0xde, 0x8d, 0x1e, 0xaa, 0xee, 0xbd, 0xbb, 0x4c, 0xc3, - 0x9e, 0xa1, 0xb2, 0xf8, 0x09, 0x5b, 0xae, 0xa9, 0x97, 0x06, 0x1b, 0xaa, 0xa8, 0xc3, 0xc3, 0x9e, - 0xa1, 0x0a, 0x25, 0xd2, 0xa2, 0xb2, 0x63, 0x53, 0x74, 0x7c, 0x2f, 0x0e, 0x38, 0x1e, 0xdf, 0x75, - 0x84, 0x8d, 0x16, 0xd5, 0x23, 0xfa, 0x43, 0xa8, 0xc3, 0xee, 0x71, 0x28, 0xde, 0x18, 0x3c, 0x84, - 0xc2, 0xf7, 0x49, 0x78, 0x43, 0x88, 0x93, 0xbd, 0x39, 0xd3, 0xf5, 0x30, 0x5e, 0x1e, 0x3c, 0x67, - 0x76, 0xbb, 0x16, 0x6c, 0xce, 0xe4, 0x3e, 0xc5, 0xaf, 0x0a, 0xb0, 0xc0, 0xca, 0x46, 0x97, 0xec, - 0x0e, 0x64, 0x6f, 0xf9, 0x33, 0x10, 0xdc, 0x7f, 0x93, 0xbe, 0xe0, 0xd5, 0x7e, 0xc5, 0x1d, 0xb2, - 0x9c, 0x5b, 0x1d, 0x93, 0x9e, 0x53, 0x06, 0xe5, 0x5b, 0x9e, 0xe0, 0x7b, 0x97, 0xde, 0xc9, 0xc5, - 0x29, 0x51, 0xbc, 0x9f, 0xca, 0x9c, 0x15, 0x8b, 0xf7, 0x53, 0x99, 0x73, 0xe2, 0xec, 0xfd, 0x54, - 0xe6, 0xbc, 0x78, 0xa1, 0xf4, 0x6f, 0xe7, 0x60, 0xd2, 0x05, 0x6f, 0x0c, 0x11, 0xdd, 0x0a, 0x22, - 0xa2, 0xb9, 0x7e, 0x88, 0x88, 0xc3, 0x3d, 0x0e, 0x89, 0x6e, 0x05, 0x21, 0xd1, 0x5c, 0x3f, 0x48, - 0xe4, 0xf3, 0x10, 0x4c, 0x54, 0xef, 0x87, 0x89, 0x5e, 0x18, 0x01, 0x13, 0x79, 0xa2, 0xba, 0x41, - 0xd1, 0x4a, 0x2f, 0x28, 0xba, 0x34, 0x18, 0x14, 0x79, 0xa2, 0x02, 0xa8, 0xe8, 0x4e, 0x17, 0x2a, - 0xba, 0x38, 0x00, 0x15, 0x79, 0xfc, 0x2e, 0x2c, 0x5a, 0x8b, 0x84, 0x45, 0x57, 0x86, 0xc1, 0x22, - 0x4f, 0x4e, 0x08, 0x17, 0xbd, 0x12, 0xc2, 0x45, 0xf3, 0x7d, 0x71, 0x91, 0xc7, 0xcd, 0x80, 0xd1, - 0x1b, 0xdd, 0xc0, 0xe8, 0xe2, 0x00, 0x60, 0xe4, 0xd7, 0x80, 0x23, 0xa3, 0x6a, 0x14, 0x32, 0xba, - 0x3c, 0x04, 0x19, 0x79, 0x52, 0x82, 0xd0, 0xa8, 0x1a, 0x05, 0x8d, 0x2e, 0x0f, 0x81, 0x46, 0x5d, - 0x92, 0x18, 0x36, 0xda, 0x88, 0xc6, 0x46, 0x57, 0x87, 0x62, 0x23, 0x4f, 0x5a, 0x18, 0x1c, 0xdd, - 0x08, 0x80, 0xa3, 0xe7, 0xfa, 0x80, 0x23, 0x8f, 0x95, 0xa0, 0xa3, 0xcf, 0xf5, 0xa0, 0xa3, 0xd2, - 0x20, 0x74, 0xe4, 0xf1, 0x7a, 0xf0, 0xe8, 0xad, 0x3e, 0xf0, 0xe8, 0xda, 0x70, 0x78, 0xe4, 0x09, - 0xeb, 0xc2, 0x47, 0xca, 0x40, 0x7c, 0xf4, 0xd2, 0x88, 0xf8, 0xc8, 0x93, 0x1e, 0x05, 0x90, 0x5e, - 0x0b, 0x03, 0xa4, 0x85, 0xfe, 0x00, 0xc9, 0x13, 0xc3, 0x11, 0xd2, 0x5a, 0x24, 0x42, 0xba, 0x32, - 0x0c, 0x21, 0xf9, 0xe3, 0x20, 0x08, 0x91, 0x36, 0xa2, 0x21, 0xd2, 0xd5, 0xa1, 0x10, 0xc9, 0x6f, - 0xfe, 0x10, 0x46, 0x5a, 0x8b, 0xc4, 0x48, 0x57, 0x86, 0x61, 0x24, 0xbf, 0x70, 0x41, 0x90, 0xf4, - 0x76, 0x5f, 0x90, 0x74, 0x7d, 0x14, 0x90, 0xe4, 0x09, 0xed, 0x41, 0x49, 0xef, 0xf6, 0x47, 0x49, - 0x9f, 0x3a, 0xc6, 0x95, 0x7c, 0x91, 0x30, 0xe9, 0x73, 0x3d, 0x30, 0xa9, 0x34, 0x08, 0x26, 0xf9, - 0xfd, 0xd9, 0xc5, 0x49, 0xca, 0x40, 0x54, 0xf3, 0xd2, 0x88, 0xa8, 0xc6, 0xef, 0x7c, 0x11, 0xb0, - 0xa6, 0x12, 0x01, 0x6b, 0x2e, 0x0d, 0x86, 0x35, 0xbe, 0x39, 0xf7, 0x71, 0x4d, 0x35, 0x0a, 0xd7, - 0x5c, 0x1e, 0x82, 0x6b, 0x7c, 0x2b, 0x14, 0x00, 0x36, 0x77, 0xba, 0x80, 0xcd, 0xc5, 0xa1, 0xa1, - 0x39, 0x01, 0x64, 0xb3, 0xdc, 0x8b, 0x6c, 0x9e, 0x1f, 0x88, 0x6c, 0x3c, 0x09, 0x3e, 0xb4, 0xb9, - 0xd3, 0x05, 0x6d, 0x2e, 0x0e, 0x80, 0x36, 0x7e, 0x01, 0x38, 0xb6, 0xd1, 0x06, 0x63, 0x9b, 0xc5, - 0x51, 0xb1, 0x8d, 0x27, 0x38, 0x12, 0xdc, 0x6c, 0x44, 0x83, 0x9b, 0xab, 0x23, 0x6e, 0x94, 0xf7, - 0xa0, 0x9b, 0x6a, 0x14, 0xba, 0xb9, 0x3c, 0x04, 0xdd, 0x04, 0xe7, 0x10, 0x0f, 0xde, 0x54, 0xa3, - 0xe0, 0xcd, 0xe5, 0x21, 0xf0, 0xc6, 0x97, 0x14, 0xc0, 0x37, 0xf5, 0x7e, 0xf8, 0xe6, 0x85, 0x11, - 0xf0, 0x8d, 0xef, 0xbc, 0x74, 0x01, 0x9c, 0x37, 0xbb, 0x01, 0x4e, 0x69, 0x10, 0xc0, 0xf1, 0x47, - 0xa4, 0x8b, 0x70, 0x36, 0xa2, 0x11, 0xce, 0xd5, 0xa1, 0x08, 0x27, 0x68, 0x24, 0x03, 0x10, 0x67, - 0x2d, 0x12, 0xe2, 0x5c, 0x19, 0x06, 0x71, 0x7c, 0x23, 0x19, 0xc4, 0x38, 0x6f, 0x76, 0x63, 0x9c, - 0xd2, 0x20, 0x8c, 0xe3, 0x57, 0xce, 0x05, 0x39, 0xd5, 0x28, 0x90, 0x73, 0x79, 0x08, 0xc8, 0xf1, - 0x1b, 0x2f, 0x80, 0x72, 0x94, 0x81, 0x28, 0xe7, 0xa5, 0x11, 0x51, 0x4e, 0x97, 0xe1, 0x0a, 0xc3, - 0x9c, 0x6a, 0x14, 0xcc, 0xb9, 0x3c, 0x04, 0xe6, 0x04, 0x0a, 0xeb, 0xe3, 0x9c, 0x8d, 0x68, 0x9c, - 0x73, 0x75, 0x28, 0xce, 0xe9, 0x1a, 0x4d, 0x2e, 0xd0, 0x59, 0x8b, 0x04, 0x3a, 0x57, 0x86, 0x01, - 0x9d, 0xae, 0x89, 0x8f, 0x3b, 0x07, 0xbf, 0x36, 0x3a, 0xd2, 0x79, 0xed, 0xf8, 0x48, 0xc7, 0x7b, - 0x67, 0x2c, 0x50, 0xe7, 0x7e, 0x2a, 0x73, 0x41, 0x7c, 0xae, 0xf4, 0x47, 0xe3, 0x90, 0xae, 0x7a, - 0xe1, 0x2c, 0x7e, 0x29, 0x85, 0x93, 0x5c, 0xff, 0x83, 0x56, 0xc8, 0x88, 0xa5, 0x76, 0x6f, 0xf8, - 0x4d, 0x6f, 0xbd, 0xb7, 0x90, 0x71, 0xd6, 0x13, 0x9c, 0xbe, 0x45, 0xaf, 0xc0, 0x64, 0xc7, 0xc6, - 0x96, 0xdc, 0xb6, 0x74, 0xd3, 0xd2, 0x1d, 0x76, 0x4e, 0x42, 0x58, 0x16, 0x3f, 0x3a, 0x9c, 0xcf, - 0x6f, 0xd9, 0xd8, 0xda, 0xe4, 0x74, 0x29, 0xdf, 0x09, 0x3c, 0xb9, 0x1f, 0x09, 0x1a, 0x1f, 0xfd, - 0x23, 0x41, 0x6f, 0x81, 0x68, 0x61, 0x45, 0x0b, 0x79, 0x20, 0xec, 0x7a, 0x9d, 0xe8, 0x3e, 0x43, - 0x0f, 0x09, 0xb9, 0x39, 0xe9, 0x35, 0x3b, 0x53, 0x56, 0x98, 0x88, 0x6e, 0xc2, 0xe9, 0x96, 0xb2, - 0x4f, 0x03, 0x17, 0x65, 0xd7, 0xa9, 0xa3, 0xc1, 0x88, 0xec, 0xa3, 0x3c, 0xa8, 0xa5, 0xec, 0xd3, - 0x2f, 0x0e, 0xb1, 0x24, 0xfa, 0xa5, 0x81, 0xcb, 0x50, 0xd0, 0x74, 0xdb, 0xd1, 0x0d, 0xd5, 0xe1, - 0x17, 0xab, 0xb2, 0x9b, 0x4a, 0x27, 0x5d, 0x2a, 0xbb, 0x3d, 0xf5, 0x3a, 0x4c, 0xf3, 0xb8, 0x76, - 0xff, 0x1b, 0x44, 0x14, 0xbe, 0x64, 0x48, 0x29, 0x48, 0x82, 0xff, 0xd5, 0xa9, 0x32, 0x4c, 0x35, - 0x14, 0x07, 0xef, 0x29, 0x07, 0xb2, 0x7b, 0x4e, 0x29, 0x47, 0xef, 0x25, 0x3c, 0x7f, 0x74, 0x38, - 0x3f, 0x79, 0x8f, 0x25, 0xf5, 0x1c, 0x57, 0x9a, 0x6c, 0x04, 0x12, 0x34, 0x74, 0x15, 0xa6, 0x14, - 0xfb, 0xc0, 0x50, 0xa9, 0x7a, 0xb0, 0x61, 0x77, 0x6c, 0x0a, 0x29, 0x32, 0x52, 0x81, 0x92, 0xcb, - 0x2e, 0x15, 0x5d, 0x84, 0x3c, 0x0f, 0xfa, 0x66, 0xdf, 0x1f, 0x9a, 0xa2, 0x55, 0xe5, 0x97, 0xf1, - 0xd3, 0x4f, 0x10, 0xb1, 0x4b, 0x51, 0xef, 0xa7, 0x32, 0x79, 0x71, 0xf2, 0x7e, 0x2a, 0x53, 0x10, - 0xa7, 0x4a, 0xbf, 0x2d, 0x40, 0x3e, 0x74, 0x16, 0xe4, 0x4e, 0xd7, 0x56, 0xec, 0xb9, 0x68, 0xf4, - 0xd3, 0x2f, 0x7a, 0x2b, 0xc3, 0xb5, 0xed, 0xc6, 0xae, 0xcd, 0xf7, 0xf7, 0x9e, 0xe9, 0x5a, 0x80, - 0xbb, 0xff, 0xef, 0xb2, 0xbd, 0x9e, 0xfa, 0xdd, 0x0f, 0xe6, 0xc7, 0x4a, 0x3f, 0x4f, 0xc2, 0x64, - 0xf8, 0xcc, 0xc7, 0x6a, 0x57, 0xb9, 0xa2, 0xac, 0x53, 0x88, 0x63, 0x71, 0xc0, 0x7d, 0x71, 0x59, - 0xff, 0x3a, 0x73, 0x56, 0xcc, 0x85, 0x01, 0x1b, 0xce, 0xc1, 0x72, 0xfa, 0x8c, 0xb3, 0xdf, 0x4f, - 0x78, 0xa3, 0x7c, 0x11, 0xc6, 0xe9, 0x0d, 0x26, 0xbc, 0x68, 0x51, 0x67, 0x70, 0x2b, 0x24, 0x5d, - 0x62, 0xd9, 0x88, 0x55, 0xa8, 0x9f, 0xe8, 0x52, 0x30, 0xff, 0xfe, 0x85, 0xe3, 0x7f, 0x8a, 0x8b, - 0x5f, 0x0d, 0x37, 0x7e, 0xbc, 0xab, 0xe1, 0xd8, 0xbe, 0x72, 0xb3, 0xc9, 0x2c, 0x2e, 0x1b, 0x17, - 0xe9, 0x9e, 0x83, 0xae, 0x54, 0x04, 0xff, 0x44, 0xdb, 0xa2, 0xc4, 0x3f, 0xd1, 0x16, 0x08, 0x27, - 0x2c, 0x78, 0x22, 0xe8, 0x20, 0x62, 0x41, 0xa7, 0xbc, 0xa9, 0xbf, 0x29, 0x80, 0x48, 0x87, 0xcc, - 0x5d, 0x8c, 0xb5, 0x58, 0x7a, 0xa1, 0x1b, 0xe9, 0x98, 0x18, 0x3d, 0x94, 0x3c, 0x74, 0xbd, 0x7c, - 0x32, 0x7c, 0xbd, 0x7c, 0xe9, 0x03, 0x01, 0x0a, 0x5e, 0x09, 0xd9, 0x57, 0x89, 0x06, 0xdc, 0xf8, - 0x76, 0xb2, 0x0f, 0xf5, 0xb8, 0x87, 0xd8, 0x47, 0xfa, 0x3c, 0x52, 0xf0, 0x10, 0x3b, 0xfb, 0xa8, - 0xcc, 0xef, 0x09, 0x30, 0xe3, 0x15, 0xb1, 0xec, 0x1f, 0x50, 0x3e, 0x41, 0x54, 0xbd, 0x44, 0x3f, - 0xd9, 0x46, 0x30, 0x3a, 0xbd, 0x3d, 0x60, 0xa4, 0xee, 0x89, 0x78, 0xfc, 0x04, 0x70, 0xec, 0xaf, - 0xd5, 0x6b, 0xf4, 0x63, 0x6e, 0xec, 0xbf, 0x5d, 0xba, 0x1b, 0x50, 0x20, 0x1d, 0x09, 0x44, 0x4b, - 0x23, 0x0d, 0x19, 0x57, 0x4b, 0x34, 0x73, 0xe9, 0xef, 0x83, 0x2d, 0x51, 0x79, 0x4a, 0x7c, 0xbe, - 0xdb, 0x90, 0x7c, 0xaa, 0x34, 0x07, 0xc5, 0x8d, 0x84, 0x5a, 0x4e, 0x22, 0xb9, 0xd1, 0xdd, 0xd0, - 0xb9, 0xee, 0x44, 0x7f, 0xff, 0xa4, 0x57, 0xa5, 0xa1, 0xf3, 0xdf, 0xaf, 0xba, 0xb5, 0x48, 0x0e, - 0x7f, 0x7d, 0xd0, 0x02, 0xbc, 0x9e, 0xfa, 0xf0, 0x83, 0x79, 0xe1, 0x7a, 0x0d, 0x66, 0x22, 0x66, - 0x33, 0x54, 0x00, 0x08, 0x5c, 0x3a, 0xcf, 0x3f, 0x0a, 0xb7, 0xb4, 0x22, 0x6f, 0x6d, 0x94, 0x1f, - 0xae, 0xaf, 0xaf, 0xd6, 0xeb, 0x95, 0x15, 0x51, 0x40, 0x22, 0xe4, 0x43, 0x57, 0xd6, 0x27, 0xd8, - 0x67, 0xe2, 0xae, 0xff, 0x1f, 0x00, 0xff, 0xb3, 0x15, 0x44, 0xd6, 0x5a, 0xe5, 0x1d, 0xf9, 0xd1, - 0xd2, 0x83, 0xad, 0x4a, 0x4d, 0x1c, 0x43, 0x08, 0x0a, 0xcb, 0x4b, 0xf5, 0x72, 0x55, 0x96, 0x2a, - 0xb5, 0xcd, 0x87, 0x1b, 0xb5, 0x8a, 0xfb, 0x79, 0xb9, 0xeb, 0x2b, 0x90, 0x0f, 0x9e, 0x80, 0x47, - 0x33, 0x30, 0x55, 0xae, 0x56, 0xca, 0x6b, 0xf2, 0xa3, 0xd5, 0x25, 0xf9, 0xad, 0xad, 0xca, 0x56, - 0x45, 0x1c, 0xa3, 0x45, 0xa3, 0xc4, 0xbb, 0x5b, 0x0f, 0x1e, 0x88, 0x02, 0x9a, 0x82, 0x1c, 0x7b, - 0xa6, 0xd7, 0xdb, 0x8b, 0x89, 0xeb, 0xeb, 0x90, 0x0b, 0xdc, 0x7f, 0x47, 0x5e, 0xb7, 0xb9, 0x55, - 0xab, 0xca, 0xf5, 0xd5, 0xf5, 0x4a, 0xad, 0xbe, 0xb4, 0xbe, 0xc9, 0x64, 0x50, 0xda, 0xd2, 0xf2, - 0x43, 0xa9, 0x2e, 0x0a, 0xde, 0x73, 0xfd, 0xe1, 0x56, 0xb9, 0xea, 0x56, 0xa3, 0x94, 0xca, 0x24, - 0xc5, 0xe4, 0xf5, 0x27, 0x70, 0xb6, 0xcf, 0x31, 0x70, 0x94, 0x83, 0x89, 0x2d, 0x83, 0xde, 0xff, - 0x25, 0x8e, 0xa1, 0xc9, 0xc0, 0x49, 0x70, 0x51, 0x40, 0x19, 0x76, 0xc6, 0x57, 0x4c, 0xa0, 0x34, - 0x24, 0x6a, 0xb7, 0xc5, 0x24, 0x29, 0x68, 0xe0, 0x20, 0xb5, 0x98, 0x42, 0x59, 0x7e, 0xca, 0x54, - 0x1c, 0x47, 0x79, 0xff, 0x98, 0xa7, 0x98, 0xbe, 0x7e, 0x11, 0x02, 0x47, 0xda, 0x10, 0x40, 0xfa, - 0x81, 0xe2, 0x60, 0xdb, 0x11, 0xc7, 0xd0, 0x04, 0x24, 0x97, 0x9a, 0x4d, 0x51, 0xb8, 0xf5, 0x67, - 0x02, 0x64, 0xdc, 0x0b, 0xdb, 0xd1, 0x03, 0x18, 0x67, 0xc0, 0x7d, 0xbe, 0xff, 0x8c, 0x44, 0x8d, - 0xda, 0xec, 0xc2, 0xb0, 0x29, 0xab, 0x34, 0x86, 0xde, 0xe6, 0x5f, 0xad, 0x24, 0x3d, 0x06, 0x3d, - 0x3f, 0xa8, 0x3f, 0xb9, 0x52, 0x07, 0x77, 0x3a, 0x32, 0x46, 0x4a, 0x63, 0x2f, 0x0b, 0xcb, 0x2f, - 0x7c, 0xf8, 0xd3, 0xb9, 0xb1, 0x0f, 0x8f, 0xe6, 0x84, 0x1f, 0x1e, 0xcd, 0x09, 0x3f, 0x3e, 0x9a, - 0x13, 0x7e, 0x72, 0x34, 0x27, 0xfc, 0xd6, 0xcf, 0xe6, 0xc6, 0x7e, 0xf8, 0xb3, 0xb9, 0xb1, 0x1f, - 0xff, 0x6c, 0x6e, 0xec, 0xdd, 0x09, 0xce, 0xbd, 0x9d, 0xa6, 0x1f, 0xd0, 0xbc, 0xfd, 0x5f, 0x01, - 0x00, 0x00, 0xff, 0xff, 0x2a, 0x61, 0xab, 0x61, 0x37, 0x74, 0x00, 0x00, +func init() { proto.RegisterFile("roachpb/api.proto", fileDescriptor_api_6ead497ae315f5e8) } + +var fileDescriptor_api_6ead497ae315f5e8 = []byte{ + // 7334 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x5d, 0x6c, 0x23, 0xc9, + 0x75, 0xae, 0x9a, 0xa4, 0x28, 0xf2, 0x90, 0xa2, 0xa8, 0xd2, 0xfc, 0x70, 0x34, 0xb3, 0x92, 0x86, + 0x3b, 0x7f, 0x3b, 0xde, 0x95, 0x76, 0x66, 0xbc, 0x77, 0xd7, 0x3b, 0xeb, 0xb5, 0x25, 0x8a, 0x33, + 0xd4, 0x68, 0xa4, 0xd1, 0x34, 0xa9, 0x59, 0xef, 0xda, 0x8b, 0x76, 0xab, 0xbb, 0x44, 0xb5, 0x45, + 0x76, 0x73, 0xba, 0x9b, 0x92, 0x38, 0xc0, 0xc5, 0xfd, 0x7b, 0xf0, 0x85, 0xef, 0xc5, 0xe2, 0x3e, + 0x5c, 0x5c, 0x5c, 0xd8, 0x09, 0xbc, 0x40, 0x02, 0x38, 0x81, 0xe1, 0x20, 0xc9, 0x5b, 0x02, 0x07, + 0xce, 0x43, 0x02, 0x6c, 0x8c, 0x04, 0x30, 0x02, 0x04, 0x36, 0x02, 0x44, 0xb0, 0xc7, 0x40, 0x60, + 0xf8, 0x21, 0x40, 0x5e, 0x12, 0x60, 0x81, 0x04, 0x41, 0xfd, 0xf4, 0x1f, 0xd9, 0xfc, 0x91, 0xdc, + 0x9b, 0x2c, 0xe0, 0x17, 0x82, 0x7d, 0xaa, 0xce, 0xe9, 0xaa, 0x53, 0x55, 0xa7, 0xce, 0x57, 0x75, + 0xaa, 0x1a, 0xa6, 0x4d, 0x43, 0x56, 0xf6, 0x5a, 0x3b, 0x4b, 0x72, 0x4b, 0x5b, 0x6c, 0x99, 0x86, + 0x6d, 0xa0, 0x69, 0xc5, 0x50, 0xf6, 0x29, 0x79, 0x91, 0x27, 0xce, 0xde, 0xdc, 0x3f, 0x58, 0xda, + 0x3f, 0xb0, 0xb0, 0x79, 0x80, 0xcd, 0x25, 0xc5, 0xd0, 0x95, 0xb6, 0x69, 0x62, 0x5d, 0xe9, 0x2c, + 0x35, 0x0c, 0x65, 0x9f, 0xfe, 0x68, 0x7a, 0x9d, 0xb1, 0xcf, 0x22, 0x47, 0xa2, 0x2a, 0xdb, 0x32, + 0xa7, 0x9d, 0x71, 0x68, 0xd8, 0x34, 0x0d, 0xd3, 0xe2, 0xd4, 0x73, 0x0e, 0xb5, 0x89, 0x6d, 0xd9, + 0x97, 0xfb, 0xa2, 0x65, 0x1b, 0xa6, 0x5c, 0xc7, 0x4b, 0x58, 0xaf, 0x6b, 0x3a, 0x26, 0x19, 0x0e, + 0x14, 0x85, 0x27, 0x5e, 0x0a, 0x4d, 0xbc, 0xc3, 0x53, 0x0b, 0x6d, 0x5b, 0x6b, 0x2c, 0xed, 0x35, + 0x94, 0x25, 0x5b, 0x6b, 0x62, 0xcb, 0x96, 0x9b, 0x2d, 0x9e, 0xb2, 0x40, 0x53, 0x6c, 0x53, 0x56, + 0x34, 0xbd, 0xbe, 0x64, 0x62, 0xc5, 0x30, 0x55, 0xac, 0x4a, 0x56, 0x4b, 0xd6, 0x9d, 0x42, 0xd6, + 0x8d, 0xba, 0x41, 0xff, 0x2e, 0x91, 0x7f, 0x8c, 0x5a, 0xfc, 0x2f, 0x90, 0x16, 0x65, 0xbd, 0x8e, + 0xd7, 0xf4, 0x5d, 0x03, 0xbd, 0x05, 0x09, 0x15, 0x5b, 0x4a, 0x41, 0x58, 0x10, 0x6e, 0x64, 0x6e, + 0x17, 0x17, 0x7b, 0x34, 0xb5, 0x48, 0xf3, 0xae, 0x62, 0x4b, 0x31, 0xb5, 0x96, 0x6d, 0x98, 0x2b, + 0x89, 0x8f, 0x8e, 0xe7, 0xc7, 0x44, 0xca, 0x85, 0x3e, 0x0b, 0xe3, 0x0d, 0x2c, 0x5b, 0xb8, 0x10, + 0xa3, 0xec, 0x85, 0x10, 0xf6, 0x87, 0x24, 0x9d, 0x33, 0xb1, 0xcc, 0xc5, 0xef, 0x0b, 0x30, 0x29, + 0xe2, 0xa7, 0x6d, 0x6c, 0xd9, 0x15, 0x2c, 0xab, 0xd8, 0x44, 0x17, 0x20, 0xbe, 0x8f, 0x3b, 0x85, + 0xf8, 0x82, 0x70, 0x23, 0xbb, 0x32, 0xf1, 0xf1, 0xf1, 0x7c, 0x7c, 0x1d, 0x77, 0x44, 0x42, 0x43, + 0x0b, 0x30, 0x81, 0x75, 0x55, 0x22, 0xc9, 0x89, 0x60, 0x72, 0x12, 0xeb, 0xea, 0x3a, 0xee, 0xa0, + 0xaf, 0x40, 0xca, 0x22, 0xd2, 0x74, 0x05, 0x17, 0xc6, 0x17, 0x84, 0x1b, 0xe3, 0x2b, 0x5f, 0xfc, + 0xf8, 0x78, 0xfe, 0xad, 0xba, 0x66, 0xef, 0xb5, 0x77, 0x16, 0x15, 0xa3, 0xb9, 0xe4, 0x96, 0x4a, + 0xdd, 0xf1, 0xfe, 0x2f, 0xb5, 0xf6, 0xeb, 0x4b, 0xdd, 0xaa, 0x5f, 0xac, 0x1d, 0xe9, 0x55, 0xfc, + 0x54, 0x74, 0x25, 0xbe, 0x99, 0xf8, 0xc5, 0x87, 0xf3, 0xc2, 0x83, 0x44, 0x4a, 0xc8, 0xc7, 0x1e, + 0x24, 0x52, 0xb1, 0x7c, 0xbc, 0xf8, 0x41, 0x1c, 0x72, 0x22, 0xb6, 0x5a, 0x86, 0x6e, 0x61, 0x5e, + 0xfe, 0x57, 0x21, 0x6e, 0x1f, 0xe9, 0xb4, 0xfc, 0x99, 0xdb, 0x73, 0x21, 0x5a, 0xa8, 0x99, 0xb2, + 0x6e, 0xc9, 0x8a, 0xad, 0x19, 0xba, 0x48, 0xb2, 0xa2, 0x37, 0x20, 0x63, 0x62, 0xab, 0xdd, 0xc4, + 0xb4, 0xbd, 0x68, 0xd5, 0x32, 0xb7, 0xcf, 0x87, 0x70, 0x56, 0x5b, 0xb2, 0x2e, 0x02, 0xcb, 0x4b, + 0xfe, 0xa3, 0x0b, 0x90, 0xd2, 0xdb, 0x4d, 0xa2, 0x10, 0x8b, 0x56, 0x37, 0x2e, 0x4e, 0xe8, 0xed, + 0xe6, 0x3a, 0xee, 0x58, 0xa8, 0x04, 0x19, 0x93, 0xb4, 0x96, 0xa4, 0xe9, 0xbb, 0x86, 0x55, 0x48, + 0x2e, 0xc4, 0x6f, 0x64, 0x6e, 0x5f, 0xea, 0xd7, 0xa6, 0xa4, 0xfd, 0x79, 0xc3, 0x80, 0xe9, 0x10, + 0x2c, 0x54, 0x85, 0x49, 0x5e, 0x32, 0x13, 0xcb, 0x96, 0xa1, 0x17, 0x26, 0x16, 0x84, 0x1b, 0xb9, + 0xdb, 0x8b, 0x61, 0x62, 0x02, 0x5a, 0x20, 0x8f, 0xed, 0x26, 0x16, 0x29, 0x97, 0x98, 0x35, 0x7d, + 0x4f, 0xe8, 0x22, 0xa4, 0x49, 0xa1, 0x77, 0x3a, 0x36, 0xb6, 0x0a, 0x29, 0x5a, 0x6a, 0x52, 0x8b, + 0x15, 0xf2, 0x5c, 0x7c, 0x1b, 0xb2, 0x7e, 0x56, 0x84, 0x20, 0x27, 0x96, 0xab, 0xdb, 0x1b, 0x65, + 0x69, 0x7b, 0x73, 0x7d, 0xf3, 0xd1, 0x3b, 0x9b, 0xf9, 0x31, 0x74, 0x06, 0xf2, 0x9c, 0xb6, 0x5e, + 0x7e, 0x57, 0x7a, 0xb8, 0xb6, 0xb1, 0x56, 0xcb, 0x0b, 0xb3, 0x89, 0xff, 0xf9, 0x5b, 0x73, 0x63, + 0xc5, 0x27, 0x00, 0xf7, 0xb1, 0xcd, 0x7b, 0x14, 0x5a, 0x81, 0xe4, 0x1e, 0x2d, 0x0f, 0xef, 0xd3, + 0x0b, 0xa1, 0x05, 0xf7, 0xf5, 0xbe, 0x95, 0x14, 0xd1, 0xc1, 0x8f, 0x8e, 0xe7, 0x05, 0x91, 0x73, + 0xb2, 0x46, 0x2f, 0xfe, 0x40, 0x80, 0x0c, 0x15, 0xcc, 0x6a, 0x89, 0x4a, 0x5d, 0x92, 0x2f, 0x0f, + 0x55, 0x49, 0xaf, 0x68, 0xb4, 0x08, 0xe3, 0x07, 0x72, 0xa3, 0x3d, 0x68, 0xc8, 0x3c, 0x21, 0xe9, + 0x22, 0xcb, 0x86, 0xee, 0x42, 0x56, 0xd3, 0x6d, 0xac, 0xdb, 0x12, 0x63, 0x8b, 0x0f, 0x61, 0xcb, + 0xb0, 0xdc, 0xf4, 0xa1, 0xf8, 0xc7, 0x02, 0xc0, 0x56, 0x3b, 0x4a, 0xd5, 0x90, 0x21, 0x3f, 0x52, + 0xf9, 0x9d, 0x21, 0xcf, 0x6a, 0x71, 0x0e, 0x92, 0x9a, 0xde, 0xd0, 0x74, 0x56, 0xfe, 0x94, 0xc8, + 0x9f, 0xd0, 0x19, 0x18, 0xdf, 0x69, 0x68, 0xba, 0x4a, 0x07, 0x40, 0x4a, 0x64, 0x0f, 0x5c, 0xfd, + 0x22, 0x64, 0x68, 0xd9, 0x23, 0xd4, 0x7e, 0xf1, 0x9b, 0x31, 0x38, 0x5b, 0x32, 0x74, 0x55, 0x23, + 0x23, 0x51, 0x6e, 0x7c, 0x2a, 0x74, 0xf3, 0x1a, 0xa4, 0xf1, 0x51, 0x6b, 0xc4, 0xe6, 0x4d, 0xe1, + 0xa3, 0x16, 0xfd, 0x17, 0xae, 0x3a, 0xf4, 0x59, 0x38, 0x2f, 0x37, 0x1a, 0xc6, 0xa1, 0xa4, 0xed, + 0x4a, 0xaa, 0x81, 0x2d, 0x49, 0x37, 0x6c, 0x09, 0x1f, 0x69, 0x96, 0x4d, 0x8d, 0x45, 0x4a, 0x9c, + 0xa1, 0xc9, 0x6b, 0xbb, 0xab, 0x06, 0xb6, 0x36, 0x0d, 0xbb, 0x4c, 0x92, 0xb8, 0xc2, 0xdf, 0x87, + 0x73, 0xdd, 0xba, 0x89, 0x52, 0xf7, 0x7f, 0x2d, 0x40, 0x6e, 0x4d, 0xd7, 0xec, 0x4f, 0x85, 0xd2, + 0x5d, 0xed, 0xc5, 0xfd, 0xda, 0xbb, 0x09, 0xf9, 0x5d, 0x59, 0x6b, 0x3c, 0xd2, 0x6b, 0x46, 0x73, + 0xc7, 0xb2, 0x0d, 0x1d, 0x5b, 0x5c, 0xbd, 0x3d, 0x74, 0xae, 0xb3, 0x27, 0x30, 0xe5, 0xd6, 0x29, + 0x4a, 0x65, 0x3d, 0x83, 0xfc, 0x9a, 0xae, 0x98, 0xb8, 0x89, 0xf5, 0x48, 0xb5, 0x75, 0x09, 0xd2, + 0x9a, 0x23, 0x97, 0x6a, 0x2c, 0x2e, 0x7a, 0x04, 0x5e, 0xa7, 0x36, 0x4c, 0xfb, 0xde, 0x1d, 0xa5, + 0xf1, 0x23, 0xd3, 0x00, 0x3e, 0x94, 0xbc, 0xf6, 0x22, 0xd3, 0x00, 0x3e, 0x64, 0xc6, 0xea, 0x5d, + 0x98, 0x5c, 0xc5, 0x0d, 0x6c, 0xe3, 0xe8, 0x2d, 0xf9, 0x36, 0xe4, 0x1c, 0xd1, 0x51, 0x36, 0xd2, + 0x6f, 0x0a, 0x80, 0xb8, 0x5c, 0x32, 0x7f, 0x46, 0xd9, 0x4e, 0xf3, 0xc4, 0x3f, 0xb0, 0xdb, 0xa6, + 0xce, 0x26, 0x7a, 0xd6, 0x4b, 0x81, 0x91, 0xe8, 0x5c, 0xef, 0x59, 0xd4, 0x84, 0xdf, 0xa2, 0xba, + 0xfe, 0x0a, 0xf1, 0x54, 0x0e, 0x61, 0x26, 0x50, 0xbc, 0x68, 0x9b, 0x32, 0x41, 0x4b, 0x16, 0x5b, + 0x88, 0xfb, 0x9d, 0x32, 0x4a, 0x2c, 0xbe, 0x0f, 0xd3, 0xa5, 0x06, 0x96, 0xcd, 0xa8, 0xd5, 0xc2, + 0x9b, 0xf3, 0x5d, 0x40, 0x7e, 0xf1, 0x51, 0x36, 0xe9, 0x6f, 0x0b, 0x80, 0x44, 0x7c, 0x80, 0x4d, + 0x3b, 0xf2, 0x26, 0x5d, 0x85, 0x8c, 0x2d, 0x9b, 0x75, 0x6c, 0x4b, 0xc4, 0x93, 0xe7, 0xe6, 0xea, + 0x05, 0x9f, 0x20, 0xe2, 0xcf, 0x2f, 0xee, 0x35, 0x94, 0xc5, 0x9a, 0xe3, 0xe9, 0x3b, 0xee, 0x19, + 0xe3, 0x23, 0x64, 0xae, 0x81, 0xf7, 0x60, 0x26, 0x50, 0xca, 0x28, 0x55, 0xf0, 0x4f, 0x02, 0x64, + 0xaa, 0x8a, 0xac, 0x47, 0x59, 0xf7, 0xb7, 0x21, 0x63, 0x29, 0xb2, 0x2e, 0xed, 0x1a, 0x66, 0x53, + 0xb6, 0x69, 0x97, 0xcd, 0x05, 0xea, 0xee, 0xba, 0xbb, 0x8a, 0xac, 0xdf, 0xa3, 0x99, 0x44, 0xb0, + 0xdc, 0xff, 0xe8, 0x31, 0x64, 0xf6, 0x71, 0x47, 0xe2, 0xb8, 0x8c, 0x4e, 0x65, 0xb9, 0xdb, 0xaf, + 0xfa, 0xf8, 0xf7, 0x0f, 0x16, 0x1d, 0x38, 0xb7, 0xe8, 0x83, 0x73, 0x8b, 0x84, 0x63, 0xb1, 0x6a, + 0x9b, 0x58, 0xaf, 0xdb, 0x7b, 0x22, 0xec, 0xe3, 0xce, 0x43, 0x26, 0xc3, 0x3f, 0x50, 0x1e, 0x24, + 0x52, 0xf1, 0x7c, 0xa2, 0xf8, 0xcf, 0x02, 0x64, 0x59, 0xc5, 0xa3, 0x1c, 0x28, 0xaf, 0x41, 0xc2, + 0x34, 0x0e, 0xd9, 0x40, 0xc9, 0xdc, 0xbe, 0x18, 0x22, 0x62, 0x1d, 0x77, 0xfc, 0x33, 0x14, 0xcd, + 0x8e, 0x56, 0x80, 0x7b, 0x72, 0x12, 0xe5, 0x8e, 0x8f, 0xca, 0x0d, 0x8c, 0x4b, 0x24, 0x32, 0xae, + 0xc3, 0xd4, 0x8e, 0x6c, 0x2b, 0x7b, 0x92, 0xc9, 0x0b, 0x49, 0x66, 0xb3, 0xf8, 0x8d, 0xac, 0x98, + 0xa3, 0x64, 0xa7, 0xe8, 0x56, 0xf1, 0x5f, 0x9c, 0x5e, 0x6f, 0xe1, 0x5f, 0xcb, 0x96, 0xff, 0x57, + 0x81, 0x8f, 0x27, 0xa7, 0xfe, 0xbf, 0x6e, 0x1d, 0xe0, 0xdb, 0x31, 0x38, 0x5f, 0xda, 0xc3, 0xca, + 0x7e, 0xc9, 0xd0, 0x2d, 0xcd, 0xb2, 0x89, 0x06, 0xa3, 0xec, 0x05, 0x17, 0x21, 0x7d, 0xa8, 0xd9, + 0x7b, 0x92, 0xaa, 0xed, 0xee, 0x52, 0xcb, 0x97, 0x12, 0x53, 0x84, 0xb0, 0xaa, 0xed, 0xee, 0xa2, + 0x3b, 0x90, 0x68, 0x1a, 0x2a, 0xf3, 0x7d, 0x73, 0xb7, 0xe7, 0x43, 0xc4, 0xd3, 0xa2, 0x59, 0xed, + 0xe6, 0x86, 0xa1, 0x62, 0x91, 0x66, 0x46, 0x73, 0x00, 0x0a, 0xa1, 0xb6, 0x0c, 0x4d, 0xb7, 0xf9, + 0x1c, 0xe8, 0xa3, 0xa0, 0x0a, 0xa4, 0x6d, 0x6c, 0x36, 0x35, 0x5d, 0xb6, 0x71, 0x61, 0x9c, 0x2a, + 0xef, 0x4a, 0x68, 0xc1, 0x5b, 0x0d, 0x4d, 0x91, 0x7b, 0xd6, 0x37, 0x3c, 0x66, 0x6e, 0x71, 0x3f, + 0x48, 0x40, 0xa1, 0x57, 0x43, 0x51, 0xf6, 0x93, 0x2d, 0x48, 0x12, 0xcc, 0xdc, 0xb0, 0x79, 0x4f, + 0xb9, 0xdd, 0x4f, 0x11, 0x21, 0x25, 0xa0, 0xd8, 0xbb, 0x61, 0xf3, 0xc2, 0x73, 0x39, 0xb3, 0xdf, + 0x17, 0x20, 0xc9, 0x12, 0xd0, 0x2d, 0x48, 0xf1, 0xa5, 0x01, 0x95, 0x96, 0x31, 0xbe, 0x72, 0xee, + 0xf9, 0xf1, 0xfc, 0x04, 0x5b, 0x08, 0x58, 0xfd, 0xd8, 0xfb, 0x2b, 0x4e, 0xb0, 0xb5, 0x00, 0x95, + 0xb4, 0x99, 0x65, 0xcb, 0xa6, 0x4d, 0xd7, 0x5e, 0x48, 0x9b, 0x65, 0xc5, 0x14, 0x25, 0xac, 0xe3, + 0x0e, 0x7a, 0x00, 0x49, 0xcb, 0x96, 0xed, 0xb6, 0xc5, 0x5b, 0xed, 0x44, 0x85, 0xad, 0x52, 0x4e, + 0x91, 0x4b, 0x20, 0xae, 0x8c, 0x8a, 0x6d, 0x59, 0x6b, 0xd0, 0x66, 0x4c, 0x8b, 0xfc, 0xa9, 0xf8, + 0x2d, 0x01, 0x92, 0x2c, 0x2b, 0x3a, 0x0f, 0x33, 0xe2, 0xf2, 0xe6, 0xfd, 0xb2, 0xb4, 0xb6, 0xb9, + 0x5a, 0xae, 0x95, 0xc5, 0x8d, 0xb5, 0xcd, 0xe5, 0x5a, 0x39, 0x3f, 0x86, 0xce, 0x01, 0x72, 0x12, + 0x4a, 0x8f, 0x36, 0xab, 0x6b, 0xd5, 0x5a, 0x79, 0xb3, 0x96, 0x17, 0xe8, 0x7a, 0x01, 0xa5, 0xfb, + 0xa8, 0x31, 0x74, 0x05, 0x16, 0xba, 0xa9, 0x52, 0xb5, 0xb6, 0x5c, 0xab, 0x4a, 0xe5, 0x6a, 0x6d, + 0x6d, 0x63, 0xb9, 0x56, 0x5e, 0xcd, 0xc7, 0x07, 0xe4, 0x22, 0x2f, 0x11, 0xc5, 0x72, 0xa9, 0x96, + 0x4f, 0x14, 0x9f, 0xc1, 0x59, 0x11, 0x2b, 0x46, 0xb3, 0xd5, 0xb6, 0x31, 0x29, 0xa5, 0x15, 0xe5, + 0x78, 0x39, 0x0f, 0x13, 0xaa, 0xd9, 0x91, 0xcc, 0xb6, 0xce, 0x47, 0x4b, 0x52, 0x35, 0x3b, 0x62, + 0x5b, 0xe7, 0x9d, 0xf1, 0xf7, 0x05, 0x38, 0xd7, 0xfd, 0xf2, 0x28, 0xbb, 0xe2, 0x63, 0xc8, 0xc8, + 0xaa, 0x8a, 0x55, 0x49, 0xc5, 0x0d, 0x5b, 0xe6, 0xae, 0xca, 0x4d, 0x9f, 0x24, 0xbe, 0x6e, 0xb6, + 0xe8, 0xae, 0x9b, 0x6d, 0x3c, 0x29, 0x95, 0x68, 0x41, 0x56, 0x09, 0x87, 0x63, 0x8a, 0xa8, 0x10, + 0x4a, 0x29, 0xfe, 0x61, 0x02, 0x26, 0xcb, 0xba, 0x5a, 0x3b, 0x8a, 0x74, 0x76, 0x39, 0x07, 0x49, + 0xc5, 0x68, 0x36, 0x35, 0xdb, 0x51, 0x13, 0x7b, 0x42, 0x9f, 0x83, 0x94, 0x8a, 0x65, 0xd5, 0x5d, + 0x71, 0x18, 0xe6, 0x68, 0x89, 0x6e, 0x76, 0xf4, 0x55, 0x38, 0x4f, 0x2c, 0xa8, 0xa9, 0xcb, 0x0d, + 0x89, 0x49, 0x93, 0x6c, 0x53, 0xab, 0xd7, 0xb1, 0xc9, 0x57, 0xe9, 0x6e, 0x84, 0x94, 0x73, 0x8d, + 0x73, 0x94, 0x28, 0x43, 0x8d, 0xe5, 0x17, 0xcf, 0x6a, 0x61, 0x64, 0xf4, 0x16, 0x00, 0x99, 0x9c, + 0xe8, 0xca, 0x9f, 0xc5, 0x6d, 0x53, 0xbf, 0xa5, 0x3f, 0xc7, 0x1c, 0x11, 0x06, 0xf2, 0x6c, 0xa1, + 0x25, 0x82, 0x0c, 0x9e, 0xb6, 0x35, 0x13, 0x4b, 0xb7, 0x5a, 0x4a, 0x21, 0x49, 0xea, 0xbd, 0x92, + 0x7b, 0x7e, 0x3c, 0x0f, 0x22, 0x23, 0xdf, 0xda, 0x2a, 0x11, 0xa4, 0xc0, 0xfe, 0xb7, 0x14, 0xb4, + 0x02, 0x73, 0x64, 0x02, 0xe6, 0x75, 0x91, 0x6d, 0x69, 0x4f, 0xab, 0xef, 0x61, 0x53, 0x72, 0xd7, + 0x93, 0xe9, 0x82, 0x5c, 0x4a, 0x9c, 0x55, 0x64, 0x9d, 0x15, 0x74, 0xd9, 0xae, 0xd0, 0x2c, 0xae, + 0x7a, 0x88, 0x9e, 0x5b, 0x86, 0x66, 0x19, 0x7a, 0x21, 0xcd, 0xf4, 0xcc, 0x9e, 0xd0, 0x63, 0xc8, + 0x6b, 0xba, 0xb4, 0xdb, 0xd0, 0xea, 0x7b, 0xb6, 0x74, 0x68, 0x6a, 0x36, 0xb6, 0x0a, 0xd3, 0xb4, + 0x42, 0x61, 0xfd, 0xae, 0xca, 0x17, 0x55, 0xd5, 0x77, 0x48, 0x4e, 0x5e, 0xb5, 0x9c, 0xa6, 0xdf, + 0xa3, 0xfc, 0x94, 0x68, 0xb9, 0xb3, 0xf3, 0x44, 0x3e, 0x55, 0xfc, 0x3b, 0x01, 0x72, 0x4e, 0xa7, + 0x89, 0xb2, 0x7f, 0xdf, 0x80, 0xbc, 0xa1, 0x63, 0xa9, 0xb5, 0x27, 0x5b, 0x98, 0x2b, 0x86, 0x4f, + 0x21, 0x39, 0x43, 0xc7, 0x5b, 0x84, 0xcc, 0x34, 0x81, 0xb6, 0x60, 0xda, 0xb2, 0xe5, 0xba, 0xa6, + 0xd7, 0x7d, 0xfa, 0x1a, 0x1f, 0xdd, 0x75, 0xcf, 0x73, 0x6e, 0x97, 0x1e, 0xf0, 0x3b, 0x7e, 0x2c, + 0xc0, 0xf4, 0xb2, 0xda, 0xd4, 0xf4, 0x6a, 0xab, 0xa1, 0x45, 0x8a, 0xf3, 0xaf, 0x40, 0xda, 0x22, + 0x32, 0x3d, 0xe3, 0xed, 0x61, 0xb4, 0x14, 0x4d, 0x21, 0x56, 0xfc, 0x21, 0x4c, 0xe1, 0xa3, 0x96, + 0x66, 0xca, 0xb6, 0x66, 0xe8, 0x0c, 0x96, 0x24, 0x46, 0xaf, 0x5b, 0xce, 0xe3, 0xf5, 0xa0, 0x09, + 0xaf, 0xd9, 0xbb, 0x80, 0xfc, 0x15, 0x8b, 0x12, 0x9f, 0x48, 0x30, 0x43, 0x45, 0x6f, 0xeb, 0x56, + 0xc4, 0x5a, 0xe3, 0xd6, 0xf5, 0xcb, 0x70, 0x26, 0xf8, 0x82, 0x28, 0x4b, 0xff, 0x3e, 0x6f, 0xf1, + 0x0d, 0x6c, 0x7e, 0x42, 0xd0, 0xd8, 0x2f, 0x3e, 0xca, 0x92, 0x7f, 0x43, 0x80, 0x0b, 0x54, 0x36, + 0xdd, 0xcc, 0xd8, 0xc5, 0x26, 0xdd, 0xda, 0x89, 0xb2, 0xd3, 0xbe, 0x08, 0x49, 0x86, 0x74, 0x69, + 0x8f, 0x1d, 0x5f, 0xc9, 0x10, 0xbf, 0xa4, 0x6a, 0x1b, 0x26, 0xf1, 0x4b, 0x78, 0x12, 0xaf, 0xa7, + 0x0c, 0xb3, 0x61, 0x65, 0x89, 0x78, 0x29, 0x60, 0x9a, 0xbb, 0x87, 0xa4, 0x8b, 0x97, 0xf6, 0x88, + 0x5f, 0x84, 0xca, 0x90, 0x51, 0xe8, 0x3f, 0xc9, 0xee, 0xb4, 0x30, 0x95, 0x9f, 0x1b, 0xe4, 0x59, + 0x32, 0xb6, 0x5a, 0xa7, 0x85, 0x89, 0x7b, 0xea, 0xfc, 0x27, 0xea, 0xf2, 0x55, 0x75, 0xa0, 0x6f, + 0x4a, 0xc7, 0x17, 0xcd, 0xeb, 0xb8, 0x77, 0x01, 0x4d, 0xfc, 0x51, 0x9c, 0xab, 0x82, 0xbd, 0x89, + 0x33, 0x45, 0xea, 0x8d, 0xbc, 0x07, 0xe7, 0x54, 0xdc, 0x32, 0xb1, 0x22, 0xdb, 0x58, 0x95, 0xfc, + 0xd5, 0x8f, 0x9d, 0xa0, 0xfa, 0x67, 0x3c, 0x19, 0x1e, 0x15, 0xbd, 0x0b, 0xc8, 0x27, 0x9b, 0xd5, + 0xcc, 0x41, 0x3b, 0x27, 0x51, 0xca, 0xb4, 0x27, 0x85, 0xd1, 0x2d, 0x54, 0x82, 0x14, 0x3e, 0x6a, + 0x49, 0x74, 0x7f, 0x33, 0x71, 0xc2, 0xfd, 0xcd, 0x09, 0x7c, 0xd4, 0x22, 0x44, 0xb4, 0x4d, 0x66, + 0x38, 0xc7, 0x1d, 0xa0, 0xc5, 0xb6, 0x86, 0xc3, 0x09, 0xaf, 0xbf, 0x70, 0x71, 0x53, 0xae, 0x27, + 0xc0, 0x44, 0xf0, 0xb6, 0xfb, 0x50, 0x80, 0x8b, 0xa1, 0x6d, 0x17, 0xe5, 0x64, 0xe7, 0x6c, 0xf1, + 0xc6, 0x4e, 0xb3, 0xc5, 0x5b, 0xfc, 0xae, 0x33, 0xea, 0x45, 0xdc, 0x30, 0x88, 0x7a, 0x3f, 0x81, + 0x75, 0xb1, 0x09, 0xa7, 0xd9, 0x63, 0x27, 0x6e, 0x76, 0x87, 0xb5, 0xcb, 0x2c, 0x74, 0x15, 0x36, + 0x4a, 0xb3, 0xf0, 0xff, 0x04, 0x98, 0xa9, 0x60, 0xd9, 0xb4, 0x77, 0xb0, 0x6c, 0x47, 0xec, 0xce, + 0xbe, 0x06, 0x71, 0xdd, 0x38, 0x3c, 0xc9, 0xd2, 0x20, 0xc9, 0xef, 0x4d, 0x5b, 0xc1, 0x72, 0x45, + 0x59, 0xeb, 0xbf, 0x88, 0x41, 0xfa, 0x7e, 0x29, 0xca, 0xba, 0xbe, 0xc5, 0x17, 0x90, 0xd9, 0x50, + 0x0f, 0xeb, 0x96, 0xee, 0xfb, 0x16, 0xef, 0x97, 0xd6, 0x71, 0xc7, 0xe9, 0x96, 0x84, 0x0b, 0x2d, + 0x43, 0xda, 0xde, 0x33, 0xb1, 0xb5, 0x67, 0x34, 0xd4, 0x93, 0xf8, 0x2c, 0x1e, 0xd7, 0xec, 0x3e, + 0x8c, 0x53, 0xb9, 0x4e, 0xf4, 0x81, 0x10, 0x12, 0x7d, 0x40, 0x5e, 0xe3, 0xba, 0x7d, 0xb1, 0x93, + 0xbc, 0xc6, 0x21, 0xb0, 0xc6, 0x71, 0x7d, 0xa3, 0xf1, 0x7c, 0xb2, 0xf8, 0x18, 0x80, 0x54, 0x2d, + 0xca, 0xe6, 0xf9, 0xdf, 0x71, 0xc8, 0x6d, 0xb5, 0xad, 0xbd, 0x88, 0xfb, 0x63, 0x09, 0xa0, 0xd5, + 0xb6, 0x28, 0x58, 0x38, 0xd2, 0x79, 0xfd, 0x87, 0x84, 0x37, 0x38, 0x0a, 0x60, 0x7c, 0xb5, 0x23, + 0x1d, 0x55, 0xb8, 0x10, 0x2c, 0x79, 0x31, 0x12, 0x2f, 0x0e, 0xc2, 0x92, 0xb5, 0x23, 0x7d, 0x03, + 0xbb, 0x20, 0x92, 0x49, 0xc2, 0x44, 0xd2, 0x5b, 0x30, 0x41, 0x1e, 0x24, 0xdb, 0x38, 0x49, 0x93, + 0x27, 0x09, 0x4f, 0xcd, 0x40, 0x77, 0x21, 0xcd, 0xb8, 0xc9, 0xc4, 0x95, 0xa4, 0x13, 0x57, 0x58, + 0x5d, 0xb8, 0x1a, 0xe9, 0x94, 0x95, 0xa2, 0xac, 0x64, 0x9a, 0x3a, 0x03, 0xe3, 0xbb, 0x86, 0xa9, + 0x60, 0x1a, 0x0d, 0x91, 0x12, 0xd9, 0x83, 0xbf, 0x55, 0x1f, 0x24, 0x52, 0xa9, 0x7c, 0xfa, 0x41, + 0x22, 0x95, 0xce, 0x43, 0xf1, 0x5b, 0x02, 0x4c, 0xb9, 0xcd, 0x11, 0xa5, 0x2d, 0x2f, 0x05, 0x74, + 0x79, 0xf2, 0x06, 0x21, 0x6a, 0x2c, 0xfe, 0x15, 0x75, 0x6c, 0x14, 0xe3, 0x80, 0xb6, 0x4f, 0x94, + 0xfd, 0xe5, 0x2e, 0x8b, 0x83, 0x89, 0x9d, 0xb4, 0x8d, 0x69, 0x48, 0xcc, 0x2d, 0x38, 0xa3, 0x35, + 0x89, 0x95, 0xd7, 0xec, 0x46, 0x87, 0xa3, 0x32, 0x1b, 0x3b, 0x3b, 0xb4, 0x33, 0x5e, 0x5a, 0xc9, + 0x49, 0xe2, 0x86, 0x8f, 0xed, 0xd9, 0x78, 0xf5, 0x89, 0x52, 0xe1, 0x6b, 0x30, 0x69, 0x32, 0xd1, + 0xc4, 0x3b, 0x39, 0xa1, 0xce, 0xb3, 0x2e, 0x2b, 0x51, 0xfb, 0x77, 0x62, 0x30, 0xf5, 0xb8, 0x8d, + 0xcd, 0xce, 0xa7, 0x49, 0xe9, 0xd7, 0x60, 0xea, 0x50, 0xd6, 0x6c, 0x69, 0xd7, 0x30, 0xa5, 0x76, + 0x4b, 0x95, 0x6d, 0x27, 0x42, 0x63, 0x92, 0x90, 0xef, 0x19, 0xe6, 0x36, 0x25, 0x22, 0x0c, 0x68, + 0x5f, 0x37, 0x0e, 0x75, 0x89, 0x90, 0x29, 0x1a, 0x3e, 0xd2, 0xf9, 0x62, 0xf2, 0xca, 0xeb, 0x7f, + 0x7b, 0x3c, 0x7f, 0x67, 0xa4, 0x70, 0x2b, 0x1a, 0xb1, 0xd6, 0x6e, 0x6b, 0xea, 0xe2, 0xf6, 0xf6, + 0xda, 0xaa, 0x98, 0xa7, 0x22, 0xdf, 0x61, 0x12, 0x6b, 0x47, 0xba, 0x33, 0x8b, 0x7f, 0x2c, 0x40, + 0xde, 0xd3, 0x54, 0x94, 0xcd, 0x59, 0x86, 0xcc, 0xd3, 0x36, 0x36, 0xb5, 0x53, 0x34, 0x26, 0x70, + 0x46, 0x62, 0x88, 0xde, 0x83, 0x6c, 0x40, 0x0f, 0xf1, 0x5f, 0x4d, 0x0f, 0x99, 0x43, 0x4f, 0x05, + 0xc5, 0x3f, 0x17, 0x00, 0xd1, 0xca, 0xaf, 0xb1, 0x75, 0xfc, 0x4f, 0x4b, 0x4f, 0xb9, 0x01, 0x79, + 0x1a, 0xeb, 0x28, 0x69, 0xbb, 0x52, 0x53, 0xb3, 0x2c, 0x4d, 0xaf, 0xf3, 0xae, 0x92, 0xa3, 0xf4, + 0xb5, 0xdd, 0x0d, 0x46, 0xe5, 0x8d, 0xf8, 0x9f, 0x61, 0x26, 0x50, 0x8d, 0x28, 0x9b, 0xf1, 0x32, + 0x64, 0x77, 0x8d, 0xb6, 0xae, 0x4a, 0x6c, 0xaf, 0x83, 0x2f, 0xfe, 0x65, 0x28, 0x8d, 0xbd, 0xaf, + 0xf8, 0x8f, 0x31, 0x38, 0x23, 0x62, 0xcb, 0x68, 0x1c, 0xe0, 0xe8, 0x15, 0x59, 0x01, 0xbe, 0xcb, + 0x22, 0x9d, 0x4a, 0x9f, 0x69, 0xc6, 0xcc, 0xa6, 0xb4, 0xe0, 0x3a, 0xfa, 0x95, 0xc1, 0x7d, 0xb1, + 0x77, 0xe5, 0x9c, 0x2f, 0xcb, 0x25, 0x02, 0xcb, 0x72, 0x06, 0x4c, 0x69, 0x75, 0xdd, 0x20, 0x36, + 0xcb, 0xc2, 0x4f, 0xf5, 0x76, 0xd3, 0xc1, 0x2c, 0x8b, 0x83, 0x0a, 0xb9, 0xc6, 0x58, 0xaa, 0xf8, + 0xe9, 0x66, 0xbb, 0x49, 0x3d, 0xe7, 0x95, 0x73, 0xa4, 0xbc, 0xcf, 0x8f, 0xe7, 0x73, 0x81, 0x34, + 0x4b, 0xcc, 0x69, 0xee, 0x33, 0x91, 0xce, 0x9b, 0xfc, 0x2b, 0x70, 0xb6, 0x4b, 0xe5, 0x51, 0xfa, + 0x38, 0x7f, 0x1a, 0x87, 0x0b, 0x41, 0xf1, 0x51, 0x23, 0x91, 0x4f, 0x7b, 0xb3, 0x56, 0x60, 0xb2, + 0xa9, 0xe9, 0xa7, 0x5b, 0x88, 0xcc, 0x36, 0x35, 0xdd, 0x5b, 0xcf, 0x0d, 0xe9, 0x20, 0xc9, 0x7f, + 0x87, 0x0e, 0x22, 0xc3, 0x6c, 0x58, 0x0b, 0x46, 0xd9, 0x4b, 0x3e, 0x10, 0x20, 0x1b, 0xf5, 0xda, + 0xda, 0xe9, 0x62, 0xcc, 0x78, 0x9d, 0x6b, 0x30, 0xf9, 0x09, 0x2c, 0xc6, 0x7d, 0x47, 0x00, 0x54, + 0x33, 0xdb, 0x3a, 0x01, 0xb9, 0x0f, 0x8d, 0x7a, 0x94, 0x95, 0x3d, 0x03, 0xe3, 0x9a, 0xae, 0xe2, + 0x23, 0x5a, 0xd9, 0x84, 0xc8, 0x1e, 0x02, 0x1b, 0x88, 0xf1, 0x91, 0x36, 0x10, 0xbd, 0x50, 0x95, + 0x40, 0x41, 0xa3, 0xd4, 0xc2, 0xef, 0xc5, 0x60, 0x86, 0x57, 0x27, 0xf2, 0xc5, 0xc8, 0x53, 0xc5, + 0xb6, 0xa3, 0xcf, 0x03, 0xb4, 0x4c, 0x7c, 0x20, 0x31, 0xd6, 0xf8, 0x48, 0xac, 0x69, 0xc2, 0x41, + 0x09, 0xe8, 0x4b, 0x30, 0x45, 0x46, 0x78, 0xcb, 0x34, 0x5a, 0x86, 0x45, 0x9c, 0x14, 0x6b, 0x34, + 0xa4, 0x33, 0xfd, 0xfc, 0x78, 0x7e, 0x72, 0x43, 0xd3, 0xb7, 0x38, 0x63, 0xad, 0x2a, 0x12, 0x53, + 0xe1, 0x3e, 0x3a, 0x03, 0xf0, 0x6f, 0x04, 0x38, 0xf3, 0x89, 0x2d, 0xdf, 0xfe, 0x47, 0x68, 0xcc, + 0x9d, 0x79, 0xf2, 0xf4, 0x71, 0x4d, 0xdf, 0x35, 0xa2, 0x5f, 0x54, 0xff, 0x40, 0x80, 0x69, 0x9f, + 0xf8, 0x28, 0x3d, 0x99, 0xd3, 0x9d, 0xa0, 0xf8, 0x32, 0xf1, 0x6d, 0xfc, 0xdd, 0x3e, 0xca, 0x41, + 0xf5, 0x27, 0x31, 0x38, 0x57, 0x62, 0x5b, 0xcb, 0x4e, 0xdc, 0x45, 0x94, 0xbd, 0xa4, 0x00, 0x13, + 0x07, 0xd8, 0xb4, 0x34, 0x83, 0xcd, 0xb0, 0x93, 0xa2, 0xf3, 0x88, 0x66, 0x21, 0x65, 0xe9, 0x72, + 0xcb, 0xda, 0x33, 0x9c, 0xdd, 0x38, 0xf7, 0xd9, 0x8d, 0x11, 0x19, 0x3f, 0x7d, 0x8c, 0x48, 0x72, + 0x70, 0x8c, 0xc8, 0xc4, 0xaf, 0x1c, 0x23, 0xc2, 0xb7, 0xbe, 0x7e, 0x28, 0xc0, 0xf9, 0x1e, 0xfd, + 0x45, 0xd9, 0x67, 0xbe, 0x06, 0x19, 0x85, 0x0b, 0x26, 0xd6, 0x98, 0xed, 0xee, 0xad, 0x91, 0x6c, + 0xa7, 0x04, 0x20, 0xcf, 0x8f, 0xe7, 0xc1, 0x29, 0xea, 0xda, 0x2a, 0x57, 0x11, 0xf9, 0xaf, 0x16, + 0xff, 0x57, 0x06, 0xa6, 0xca, 0x47, 0x6c, 0xed, 0xba, 0xca, 0xfc, 0x01, 0x74, 0x0f, 0x52, 0x2d, + 0xd3, 0x38, 0xd0, 0x9c, 0x6a, 0xe4, 0x02, 0xa1, 0x01, 0x4e, 0x35, 0xba, 0xb8, 0xb6, 0x38, 0x87, + 0xe8, 0xf2, 0xa2, 0x1a, 0xa4, 0x1f, 0x1a, 0x8a, 0xdc, 0xb8, 0xa7, 0x35, 0x9c, 0xfe, 0xff, 0xea, + 0x70, 0x41, 0x8b, 0x2e, 0xcf, 0x96, 0x6c, 0xef, 0x39, 0x4d, 0xe1, 0x12, 0xd1, 0x1a, 0xa4, 0x2a, + 0xb6, 0xdd, 0x22, 0x89, 0xdc, 0x9a, 0x5c, 0x1f, 0x41, 0x28, 0x61, 0xe1, 0xb2, 0x5c, 0x76, 0x54, + 0x83, 0xe9, 0xfb, 0x86, 0x51, 0x6f, 0xe0, 0x52, 0xc3, 0x68, 0xab, 0x25, 0x43, 0xdf, 0xd5, 0xea, + 0xdc, 0x1e, 0x5f, 0x1b, 0x41, 0xe6, 0xfd, 0x52, 0x55, 0xec, 0x15, 0x80, 0x96, 0x21, 0x55, 0xbd, + 0xc3, 0x85, 0x31, 0x07, 0xee, 0xea, 0x08, 0xc2, 0xaa, 0x77, 0x44, 0x97, 0x0d, 0x3d, 0x80, 0xcc, + 0xf2, 0xb3, 0xb6, 0x89, 0xb9, 0x94, 0x64, 0xdf, 0xb8, 0x84, 0x6e, 0x29, 0x94, 0x4b, 0xf4, 0x33, + 0xa3, 0x2a, 0xe4, 0xde, 0x31, 0xcc, 0xfd, 0x86, 0x21, 0x3b, 0x35, 0x9c, 0xa0, 0xe2, 0x3e, 0x33, + 0x82, 0x38, 0x87, 0x51, 0xec, 0x12, 0x31, 0xfb, 0x25, 0x98, 0x0c, 0x34, 0x13, 0x42, 0x90, 0x68, + 0x91, 0x16, 0x11, 0x68, 0x84, 0x0f, 0xfd, 0x8f, 0x5e, 0x81, 0x09, 0xdd, 0x50, 0xb1, 0xd3, 0x87, + 0x27, 0x57, 0xce, 0x3c, 0x3f, 0x9e, 0x4f, 0x6e, 0x1a, 0x2a, 0x73, 0x28, 0xf8, 0x3f, 0x31, 0x49, + 0x32, 0x39, 0xee, 0xc4, 0xec, 0x35, 0x48, 0x90, 0xf6, 0x21, 0x66, 0x64, 0x47, 0xb6, 0xf0, 0xb6, + 0xa9, 0x71, 0x99, 0xce, 0x23, 0xcf, 0xf7, 0x13, 0x01, 0x62, 0xd5, 0x3b, 0xc4, 0x95, 0xde, 0x69, + 0x2b, 0xfb, 0xd8, 0xe6, 0xb9, 0xf8, 0x13, 0x75, 0xb1, 0x4d, 0xbc, 0xab, 0x31, 0x2f, 0x27, 0x2d, + 0xf2, 0x27, 0xf4, 0x02, 0x80, 0xac, 0x28, 0xd8, 0xb2, 0x24, 0xe7, 0x40, 0x5a, 0x5a, 0x4c, 0x33, + 0xca, 0x3a, 0xee, 0x10, 0x36, 0x0b, 0x2b, 0x26, 0xb6, 0x9d, 0x50, 0x25, 0xf6, 0x44, 0xd8, 0x6c, + 0xdc, 0x6c, 0x49, 0xb6, 0xb1, 0x8f, 0x75, 0xda, 0xaa, 0x69, 0x62, 0x1e, 0x9a, 0xad, 0x1a, 0x21, + 0x10, 0xcb, 0x86, 0x75, 0xd5, 0x33, 0x43, 0x69, 0xd1, 0x7d, 0x26, 0x22, 0x4d, 0x5c, 0xd7, 0xf8, + 0x41, 0xab, 0xb4, 0xc8, 0x9f, 0x88, 0xc6, 0xe4, 0xb6, 0xbd, 0x47, 0x83, 0x33, 0xd2, 0x22, 0xfd, + 0xcf, 0xab, 0xf6, 0x4d, 0x01, 0xe2, 0xf7, 0x4b, 0xd5, 0x13, 0xd7, 0xcd, 0x91, 0x18, 0xf7, 0x24, + 0xd2, 0x08, 0x41, 0xad, 0xd1, 0xd0, 0xf4, 0x3a, 0x71, 0x3a, 0xbe, 0x86, 0x15, 0xa7, 0x66, 0x39, + 0x4e, 0xde, 0x62, 0x54, 0xb4, 0x00, 0x19, 0xc5, 0xc4, 0x2a, 0xd6, 0x6d, 0x4d, 0x6e, 0x58, 0xbc, + 0x8a, 0x7e, 0x12, 0x2f, 0xdc, 0xd7, 0x05, 0x18, 0xa7, 0xdd, 0x0b, 0x5d, 0x82, 0xb4, 0x62, 0xe8, + 0xb6, 0xac, 0xe9, 0xdc, 0x4e, 0xa4, 0x45, 0x8f, 0xd0, 0xb7, 0x90, 0x97, 0x21, 0x2b, 0x2b, 0x8a, + 0xd1, 0xd6, 0x6d, 0x49, 0x97, 0x9b, 0x98, 0x17, 0x36, 0xc3, 0x69, 0x9b, 0x72, 0x13, 0xa3, 0x79, + 0x70, 0x1e, 0xdd, 0x63, 0x81, 0x69, 0x11, 0x38, 0x69, 0x1d, 0x77, 0x78, 0x49, 0x7e, 0x28, 0x40, + 0xca, 0xe9, 0x96, 0xa4, 0x30, 0x75, 0xac, 0x63, 0x53, 0xb6, 0x0d, 0xb7, 0x30, 0x2e, 0xa1, 0x7b, + 0x4e, 0x4a, 0x7b, 0x73, 0xd2, 0x19, 0x18, 0xb7, 0xe5, 0x9d, 0x86, 0x53, 0x0e, 0xf6, 0x40, 0x57, + 0x83, 0x1b, 0x72, 0x9d, 0x2d, 0x80, 0xa5, 0x45, 0xf6, 0x40, 0xaa, 0xc4, 0xa3, 0x5c, 0x99, 0x76, + 0xf8, 0x13, 0x29, 0x2f, 0x8b, 0xc2, 0xdc, 0xc1, 0x75, 0x4d, 0xa7, 0x1d, 0x20, 0x2e, 0x02, 0x25, + 0xad, 0x10, 0x0a, 0xba, 0x08, 0x69, 0x96, 0x01, 0xeb, 0x2a, 0xed, 0x05, 0x71, 0x31, 0x45, 0x09, + 0x65, 0xe7, 0x30, 0x14, 0x77, 0x44, 0xbe, 0x27, 0xc0, 0x34, 0x8b, 0x9d, 0x61, 0xe1, 0x9b, 0xd1, + 0xcd, 0xca, 0x6f, 0x42, 0x5a, 0x95, 0x6d, 0x99, 0x9d, 0x46, 0x8c, 0x0d, 0x3c, 0x8d, 0xe8, 0x98, + 0x49, 0x92, 0x9f, 0x9e, 0x48, 0x44, 0x90, 0x20, 0xff, 0xd9, 0xf1, 0x4d, 0x91, 0xfe, 0xf7, 0xa2, + 0x11, 0xfc, 0xc5, 0x8d, 0xd2, 0x4b, 0x59, 0x82, 0xb3, 0xc4, 0xb8, 0x94, 0x75, 0xc5, 0xec, 0xb4, + 0x08, 0x86, 0x7e, 0x44, 0x7f, 0x2d, 0x94, 0xf7, 0xed, 0xe6, 0xd0, 0x4d, 0x1c, 0x5e, 0x96, 0x3f, + 0x4b, 0xc2, 0x64, 0xf9, 0xa8, 0x65, 0x98, 0x91, 0xae, 0x04, 0xad, 0xc0, 0x04, 0x87, 0xc9, 0x03, + 0xf6, 0x57, 0xbb, 0xcc, 0xa6, 0xb3, 0x75, 0xc9, 0x19, 0xd1, 0x0a, 0x00, 0x0b, 0xb4, 0xa4, 0x01, + 0x38, 0xf1, 0x13, 0xec, 0x32, 0x51, 0x36, 0x42, 0x45, 0x9b, 0x90, 0x69, 0x1e, 0x28, 0x8a, 0xb4, + 0xab, 0x35, 0x6c, 0x1e, 0xa9, 0x16, 0x1e, 0x66, 0xbd, 0xf1, 0xa4, 0x54, 0xba, 0x47, 0x33, 0xb1, + 0xa0, 0x31, 0xef, 0x59, 0x04, 0x22, 0x81, 0xfd, 0x47, 0x2f, 0x03, 0x3f, 0x6c, 0x22, 0x59, 0xce, + 0xd1, 0xb1, 0x95, 0xc9, 0xe7, 0xc7, 0xf3, 0x69, 0x91, 0x52, 0xab, 0xd5, 0x9a, 0x98, 0x66, 0x19, + 0xaa, 0x96, 0x8d, 0x5e, 0x84, 0x49, 0xa3, 0xa9, 0xd9, 0x92, 0xe3, 0x38, 0x70, 0x5f, 0x2b, 0x4b, + 0x88, 0x8e, 0x63, 0x81, 0x6a, 0x70, 0x1d, 0xeb, 0x64, 0xf8, 0xd0, 0x7a, 0x4a, 0x3b, 0x6c, 0x01, + 0xcf, 0x66, 0x43, 0x50, 0x32, 0x5a, 0xb6, 0xd6, 0xd4, 0x9e, 0xd1, 0x1d, 0x5e, 0xbe, 0xc9, 0xf2, + 0x22, 0xcb, 0x4e, 0xea, 0xb7, 0x42, 0x57, 0xf6, 0x78, 0xde, 0x47, 0xbe, 0xac, 0xe8, 0xeb, 0x02, + 0x9c, 0xe3, 0x8a, 0x94, 0x76, 0x68, 0x9c, 0xb8, 0xdc, 0xd0, 0xec, 0x8e, 0xb4, 0x7f, 0x50, 0x48, + 0x51, 0x8f, 0xee, 0x73, 0xa1, 0x0d, 0xe2, 0xeb, 0x07, 0x8b, 0x4e, 0xb3, 0x74, 0x1e, 0x72, 0xe6, + 0xf5, 0x83, 0xb2, 0x6e, 0x9b, 0x9d, 0x95, 0xf3, 0xcf, 0x8f, 0xe7, 0x67, 0x7a, 0x53, 0x9f, 0x88, + 0x33, 0x56, 0x2f, 0x0b, 0xaa, 0x00, 0x60, 0xb7, 0x37, 0xd2, 0x38, 0xb9, 0xf0, 0x39, 0x39, 0xb4, + 0xdb, 0x8a, 0x3e, 0x5e, 0x74, 0x03, 0xf2, 0xfc, 0xa4, 0xc8, 0xae, 0xd6, 0xc0, 0x92, 0xa5, 0x3d, + 0xc3, 0x05, 0xa0, 0x66, 0x21, 0xc7, 0xe8, 0x44, 0x44, 0x55, 0x7b, 0x86, 0x67, 0xbf, 0x06, 0x85, + 0x7e, 0xa5, 0xf7, 0x0f, 0x84, 0x34, 0xdb, 0xcd, 0x7c, 0x23, 0xb8, 0x8c, 0x31, 0x42, 0x57, 0x75, + 0x96, 0x32, 0x62, 0x6f, 0x38, 0x26, 0xe8, 0xbb, 0x31, 0x98, 0x5c, 0x69, 0x37, 0xf6, 0x1f, 0xb5, + 0xaa, 0xed, 0x66, 0x53, 0x36, 0x3b, 0xc4, 0x7a, 0x31, 0xd3, 0x41, 0x8a, 0x29, 0x30, 0xeb, 0x45, + 0x6d, 0x83, 0xf6, 0x0c, 0x93, 0xf9, 0xc5, 0x17, 0xde, 0xc1, 0xe3, 0xe0, 0x69, 0x4d, 0x3c, 0x32, + 0x0d, 0x55, 0x7f, 0x03, 0x0a, 0xbe, 0x8c, 0x74, 0xcd, 0x41, 0xc2, 0xba, 0x6d, 0x6a, 0x98, 0xad, + 0xa1, 0xc5, 0x45, 0x5f, 0x0c, 0xca, 0x1a, 0x49, 0x2e, 0xb3, 0x54, 0x54, 0x83, 0x2c, 0xc9, 0xd8, + 0x91, 0xa8, 0xfd, 0x77, 0x56, 0x3a, 0x6f, 0x85, 0x54, 0x2e, 0x50, 0xee, 0x45, 0xaa, 0xa5, 0x12, + 0xe5, 0xa1, 0x7f, 0xc5, 0x0c, 0xf6, 0x28, 0xb3, 0x6f, 0x43, 0xbe, 0x3b, 0x83, 0x5f, 0xa3, 0x09, + 0xa6, 0xd1, 0x33, 0x7e, 0x8d, 0xc6, 0x7d, 0xda, 0x7a, 0x90, 0x48, 0x25, 0xf2, 0xe3, 0xc5, 0x9f, + 0xc5, 0x21, 0xe7, 0x74, 0xb6, 0x28, 0x21, 0xc0, 0x0a, 0x8c, 0x93, 0xae, 0xe1, 0x44, 0x4c, 0x5c, + 0x1b, 0xd0, 0xc7, 0x79, 0xcc, 0x35, 0xe9, 0x32, 0x0e, 0x88, 0xa4, 0xac, 0x51, 0x98, 0x9d, 0xd9, + 0xff, 0x16, 0x83, 0x04, 0xf5, 0xba, 0x6f, 0x41, 0x82, 0x4e, 0x1d, 0xc2, 0x28, 0x53, 0x07, 0xcd, + 0xea, 0xba, 0x84, 0x31, 0x9f, 0x4b, 0x48, 0xfc, 0xab, 0x3d, 0xf9, 0xb5, 0x5b, 0xb7, 0xa9, 0xc9, + 0xc9, 0x8a, 0xfc, 0x09, 0xad, 0xd0, 0x50, 0x1e, 0xc3, 0xb4, 0xb1, 0xca, 0xbd, 0xdd, 0x85, 0x61, + 0xed, 0xeb, 0x4c, 0x53, 0x0e, 0x1f, 0xba, 0x00, 0x71, 0x62, 0xcb, 0x26, 0xd8, 0x36, 0xff, 0xf3, + 0xe3, 0xf9, 0x38, 0xb1, 0x62, 0x84, 0x86, 0x96, 0x20, 0x13, 0x34, 0x1c, 0xc2, 0x8d, 0x34, 0x33, + 0x8f, 0xbe, 0x41, 0x0f, 0x0d, 0x77, 0x80, 0x31, 0xa4, 0xc7, 0xdb, 0xf8, 0xbf, 0x8e, 0xc3, 0xe4, + 0x5a, 0x33, 0xea, 0x89, 0x65, 0x39, 0xd8, 0xc2, 0x61, 0x10, 0x21, 0xf0, 0xd2, 0x90, 0x06, 0x0e, + 0xcc, 0xe9, 0xf1, 0x93, 0xcd, 0xe9, 0x6b, 0xc4, 0x2b, 0xe5, 0x77, 0x0c, 0xc4, 0xfb, 0xa0, 0x81, + 0xe0, 0xfb, 0x6b, 0xc4, 0x56, 0x8b, 0x84, 0xc7, 0x3b, 0x85, 0x40, 0x43, 0x35, 0xde, 0xa6, 0xce, + 0x2f, 0xeb, 0x65, 0xc9, 0xd1, 0x7b, 0xd9, 0x04, 0xd6, 0x55, 0x3a, 0xb5, 0x05, 0xed, 0xea, 0xc4, + 0xe9, 0xed, 0xea, 0xec, 0x33, 0xde, 0x59, 0xdf, 0x84, 0xb8, 0xaa, 0x99, 0x03, 0xee, 0xbc, 0x08, + 0x9f, 0xb0, 0x09, 0xd3, 0x90, 0x5e, 0x9b, 0xf0, 0xf7, 0x5a, 0xff, 0xaa, 0xc0, 0xec, 0x23, 0x00, + 0x4f, 0x43, 0x68, 0x01, 0x92, 0x46, 0x43, 0x75, 0x0e, 0x63, 0x4c, 0xae, 0xa4, 0x9f, 0x1f, 0xcf, + 0x8f, 0x3f, 0x6a, 0xa8, 0x6b, 0xab, 0xe2, 0xb8, 0xd1, 0x50, 0xd7, 0x54, 0x7a, 0xcd, 0x03, 0x3e, + 0x94, 0xdc, 0xc8, 0xad, 0xac, 0x38, 0xa1, 0xe3, 0xc3, 0x55, 0x6c, 0x29, 0x5d, 0x11, 0x25, 0xa4, + 0x0b, 0x7e, 0x5b, 0x80, 0x9c, 0xd3, 0x1a, 0xd1, 0x9a, 0x99, 0x94, 0xd6, 0xe4, 0xc3, 0x2e, 0x7e, + 0xb2, 0x61, 0xe7, 0xf0, 0xf1, 0xa3, 0xa8, 0xdf, 0x10, 0x78, 0xd4, 0x6e, 0x55, 0x91, 0x6d, 0xe2, + 0x6c, 0x44, 0x38, 0x54, 0x5e, 0x82, 0xbc, 0x29, 0xeb, 0xaa, 0xd1, 0xd4, 0x9e, 0x61, 0xb6, 0x8c, + 0x68, 0xf1, 0x1d, 0xc1, 0x29, 0x97, 0x4e, 0xd7, 0xc9, 0x9c, 0x55, 0xd0, 0x5f, 0x0a, 0x3c, 0xc2, + 0xd7, 0x2d, 0x4c, 0x94, 0x4a, 0x5b, 0x87, 0xa4, 0xc9, 0xe2, 0x04, 0xd9, 0xd0, 0x7d, 0x25, 0x44, + 0x48, 0xd8, 0xdb, 0x59, 0x18, 0x9e, 0x3b, 0x78, 0xa8, 0x88, 0xd9, 0x2f, 0xc2, 0x38, 0x25, 0x9f, + 0xc2, 0xc0, 0x72, 0xcd, 0xff, 0x7d, 0x0c, 0xae, 0xd0, 0xd7, 0x3d, 0xc1, 0xa6, 0xb6, 0xdb, 0xd9, + 0x32, 0x0d, 0x1b, 0x2b, 0x36, 0x56, 0xbd, 0xb3, 0x0f, 0x91, 0x5a, 0xad, 0x74, 0xcb, 0x79, 0xc1, + 0x89, 0xe2, 0xa5, 0x5c, 0x2e, 0xb4, 0x0e, 0x53, 0xec, 0x2e, 0x1b, 0x49, 0x6e, 0x68, 0x07, 0x58, + 0x92, 0xed, 0x93, 0xcc, 0x4d, 0x93, 0x8c, 0x77, 0x99, 0xb0, 0x2e, 0xdb, 0x48, 0x85, 0x34, 0x17, + 0xa6, 0xa9, 0xfc, 0xfe, 0x98, 0xfb, 0xbf, 0xda, 0x42, 0x59, 0x4a, 0xa4, 0xf2, 0xd6, 0x56, 0xc5, + 0x14, 0x93, 0xec, 0x6e, 0x74, 0xfc, 0x58, 0x80, 0xab, 0x43, 0x14, 0x1d, 0x65, 0x37, 0x9b, 0x85, + 0xd4, 0x01, 0x79, 0x91, 0xc6, 0x35, 0x9d, 0x12, 0xdd, 0x67, 0xb4, 0x01, 0x93, 0xbb, 0xb2, 0xd6, + 0x20, 0x1e, 0x17, 0xeb, 0x89, 0xfd, 0x83, 0xec, 0xc2, 0x63, 0x3f, 0xb3, 0x8c, 0x9d, 0x26, 0xd2, + 0xd3, 0x81, 0xd3, 0xcb, 0xaa, 0x5a, 0xad, 0x72, 0x0b, 0x16, 0x5d, 0x7f, 0x71, 0xa0, 0x63, 0xcc, + 0x83, 0x8e, 0xe8, 0x15, 0x40, 0xaa, 0x66, 0xb1, 0x5b, 0x2c, 0xac, 0x3d, 0x59, 0x35, 0x0e, 0xbd, + 0x50, 0x83, 0x69, 0x27, 0xa5, 0xea, 0x24, 0xa0, 0x2a, 0x50, 0xdc, 0x22, 0x59, 0xb6, 0xec, 0xee, + 0x96, 0x5c, 0x1d, 0xe9, 0xa8, 0x12, 0x03, 0x34, 0xee, 0xa3, 0x98, 0x26, 0x72, 0xe8, 0x5f, 0xe2, + 0x81, 0x6b, 0xa4, 0xea, 0xb6, 0x24, 0x5b, 0xce, 0xb9, 0x16, 0x76, 0x7f, 0x46, 0x8e, 0xd1, 0x97, + 0x2d, 0xff, 0x71, 0x15, 0x16, 0x76, 0xef, 0x29, 0x28, 0x4a, 0xa0, 0xfb, 0x3b, 0x02, 0xe4, 0x44, + 0xbc, 0x6b, 0x62, 0x2b, 0x52, 0xc0, 0x7f, 0x0f, 0xb2, 0x26, 0x93, 0x2a, 0xed, 0x9a, 0x46, 0xf3, + 0x24, 0x63, 0x2c, 0xc3, 0x19, 0xef, 0x99, 0x46, 0x33, 0x70, 0xdf, 0xc0, 0x13, 0x98, 0x72, 0x4b, + 0x1a, 0xa5, 0x0a, 0xbe, 0x47, 0x8f, 0xe7, 0x32, 0xc1, 0x51, 0xef, 0xf9, 0x7f, 0x12, 0x7a, 0xa0, + 0xdb, 0x33, 0xfe, 0xe2, 0x46, 0xa9, 0x8c, 0x5f, 0x0a, 0x90, 0xab, 0xb6, 0x77, 0xd8, 0x7d, 0x49, + 0xd1, 0xe9, 0xa1, 0x0c, 0xe9, 0x06, 0xde, 0xb5, 0xa5, 0x53, 0x85, 0x8a, 0xa7, 0x08, 0x2b, 0x0d, + 0x97, 0xbf, 0x0f, 0x60, 0xd2, 0xc3, 0x60, 0x54, 0x4e, 0xfc, 0x84, 0x72, 0xd2, 0x94, 0xd7, 0x73, + 0x72, 0x8a, 0xdf, 0x8b, 0xc1, 0x94, 0x5b, 0xd9, 0x28, 0xad, 0xe7, 0x3b, 0x01, 0xab, 0x11, 0x3f, + 0x89, 0xd5, 0x98, 0xe6, 0x21, 0x0f, 0xe1, 0x96, 0x63, 0x11, 0x66, 0xa8, 0x0b, 0x22, 0xc9, 0xad, + 0x56, 0x43, 0x73, 0xa0, 0x2c, 0xb5, 0x4b, 0x09, 0x71, 0x9a, 0x26, 0x2d, 0xb3, 0x14, 0x0a, 0x62, + 0x49, 0xff, 0xdb, 0x35, 0x31, 0x7e, 0x86, 0x25, 0x8a, 0xaa, 0x4e, 0x12, 0xd2, 0x91, 0x61, 0x8c, + 0x55, 0xc2, 0xc7, 0x7b, 0xde, 0xfb, 0x30, 0x4d, 0x35, 0x1b, 0xf5, 0x81, 0x54, 0xde, 0x1c, 0x3f, + 0x15, 0x00, 0xf9, 0xe5, 0x7f, 0x72, 0x2d, 0x12, 0x8b, 0xae, 0x45, 0x5e, 0x06, 0xc4, 0x42, 0xf7, + 0x2c, 0xa9, 0x85, 0x4d, 0xc9, 0xc2, 0x8a, 0xc1, 0xef, 0xfd, 0x11, 0xc4, 0x3c, 0x4f, 0xd9, 0xc2, + 0x66, 0x95, 0xd2, 0x8b, 0x1f, 0xcc, 0x42, 0x96, 0x2b, 0x63, 0x5b, 0xd7, 0x0c, 0x1d, 0xdd, 0x82, + 0x78, 0x9d, 0x2f, 0xb1, 0x67, 0x42, 0x57, 0xd4, 0xbc, 0xbb, 0xc7, 0x2a, 0x63, 0x22, 0xc9, 0x4b, + 0x58, 0x5a, 0x6d, 0x3b, 0xc4, 0xff, 0xf1, 0x62, 0x8c, 0xfd, 0x2c, 0xad, 0xb6, 0x8d, 0xaa, 0x30, + 0xa5, 0x78, 0x77, 0x2f, 0x49, 0x84, 0x3d, 0xde, 0x17, 0xe9, 0x84, 0xde, 0x60, 0x55, 0x19, 0x13, + 0x73, 0x4a, 0x20, 0x01, 0x95, 0xfc, 0x97, 0xfd, 0x24, 0x7a, 0xc2, 0x99, 0xbc, 0xc3, 0xab, 0xc1, + 0x8b, 0x86, 0x2a, 0x63, 0xbe, 0x3b, 0x81, 0xd0, 0x9b, 0x90, 0x54, 0xe9, 0x25, 0x32, 0xbc, 0x6b, + 0x86, 0xf5, 0x9e, 0xc0, 0xbd, 0x3d, 0x95, 0x31, 0x91, 0x73, 0xa0, 0x07, 0x90, 0x65, 0xff, 0x98, + 0x1f, 0xc2, 0xe1, 0xdf, 0xd5, 0xfe, 0x12, 0x7c, 0xd6, 0xbd, 0x32, 0x26, 0x66, 0x54, 0x8f, 0x8a, + 0x3e, 0x0b, 0x09, 0x4b, 0x91, 0x1d, 0x00, 0x38, 0xd7, 0xe7, 0x06, 0x09, 0x8f, 0x99, 0xe6, 0x46, + 0x77, 0xd9, 0xf5, 0x81, 0xf6, 0x91, 0xb3, 0x22, 0x17, 0x56, 0xfc, 0xc0, 0xb9, 0x64, 0x52, 0x7c, + 0x4c, 0x09, 0xe8, 0x3e, 0x64, 0x64, 0xe2, 0xd0, 0x49, 0xf4, 0x1c, 0x20, 0x5d, 0x82, 0x0b, 0xdf, + 0x21, 0xee, 0x39, 0xc3, 0x59, 0xa1, 0x87, 0x9f, 0x1d, 0xa2, 0x27, 0xa8, 0x89, 0xcd, 0x3a, 0x2e, + 0x64, 0x06, 0x0b, 0xf2, 0x87, 0x2f, 0xb9, 0x82, 0x28, 0x91, 0x38, 0x76, 0x7b, 0xce, 0x19, 0x0f, + 0x5a, 0xa9, 0x6c, 0xdf, 0xdd, 0xc8, 0x90, 0x33, 0x2a, 0x95, 0x31, 0x31, 0xbb, 0xe7, 0x23, 0xa3, + 0x45, 0x88, 0xd5, 0x95, 0xc2, 0x24, 0x95, 0x71, 0x69, 0xd0, 0x09, 0x8c, 0xca, 0x98, 0x18, 0xab, + 0x2b, 0x04, 0xca, 0xb3, 0x10, 0xfa, 0x23, 0xbd, 0x90, 0xeb, 0x3b, 0xd4, 0x83, 0x07, 0x11, 0x2a, + 0x63, 0x22, 0x8d, 0xda, 0x27, 0xef, 0xdb, 0x82, 0x9c, 0xc9, 0xe2, 0xbf, 0x9c, 0xc8, 0xcd, 0x7c, + 0xdf, 0x1d, 0xda, 0xb0, 0xe0, 0xcd, 0x0a, 0x75, 0xf0, 0x7d, 0x74, 0xf4, 0x55, 0x38, 0x13, 0x94, + 0xc8, 0x7b, 0xda, 0x34, 0x95, 0xfb, 0xf2, 0x50, 0xb9, 0xc1, 0x0e, 0x87, 0xcc, 0x9e, 0x44, 0xf4, + 0x3a, 0x8c, 0xb3, 0x56, 0x43, 0x54, 0x64, 0x58, 0xe8, 0x41, 0x57, 0x83, 0xb1, 0xfc, 0xa4, 0xf3, + 0xdb, 0x3c, 0xf0, 0x49, 0x6a, 0x18, 0xf5, 0xc2, 0x4c, 0xdf, 0xce, 0xdf, 0x1b, 0xc8, 0x45, 0x3a, + 0xbf, 0xed, 0x51, 0x49, 0xbb, 0x9b, 0x2c, 0x85, 0xc7, 0xc9, 0x9c, 0xe9, 0xdb, 0xee, 0x21, 0xf1, + 0x50, 0x15, 0x1a, 0x8a, 0xee, 0x91, 0x49, 0xd1, 0x4c, 0x76, 0xdd, 0x89, 0x44, 0xc7, 0xd4, 0xd9, + 0xbe, 0x45, 0xeb, 0xbd, 0x15, 0xa6, 0x42, 0x1d, 0x1f, 0x97, 0x8a, 0x9e, 0x40, 0x9e, 0x5f, 0x44, + 0xe0, 0x2d, 0xff, 0x9f, 0xa3, 0xf2, 0x5e, 0x0a, 0x35, 0x5d, 0x61, 0x81, 0x25, 0x95, 0x31, 0x71, + 0x4a, 0x09, 0xa6, 0xa0, 0x77, 0x61, 0x9a, 0xca, 0x93, 0x14, 0xef, 0x06, 0x89, 0x42, 0xa1, 0xe7, + 0x26, 0x82, 0xfe, 0x97, 0x4d, 0x38, 0x92, 0xf3, 0x4a, 0x57, 0x12, 0xe9, 0xc6, 0x9a, 0xae, 0xd9, + 0xd4, 0xca, 0xce, 0xf6, 0xed, 0xc6, 0xc1, 0xbb, 0xea, 0x48, 0x37, 0xd6, 0x18, 0x85, 0x74, 0x63, + 0x9b, 0x07, 0x51, 0xf1, 0xe6, 0xb8, 0xd4, 0xb7, 0x1b, 0x87, 0x45, 0x5b, 0x91, 0x6e, 0x6c, 0xfb, + 0xe9, 0xa4, 0x1b, 0x33, 0x03, 0xd1, 0x25, 0xf7, 0x85, 0xbe, 0xdd, 0xb8, 0xef, 0x49, 0x5c, 0xd2, + 0x8d, 0xe5, 0x9e, 0x44, 0xb4, 0x0a, 0xc0, 0xfc, 0x12, 0x4d, 0xdf, 0x35, 0x0a, 0x73, 0x7d, 0x27, + 0x83, 0xee, 0x30, 0x2a, 0x32, 0x19, 0x34, 0x1c, 0x1a, 0x31, 0x64, 0x14, 0x0d, 0x49, 0x74, 0x7b, + 0xb2, 0x30, 0xdf, 0xd7, 0x90, 0xf5, 0xec, 0x52, 0x12, 0x43, 0x76, 0xe8, 0x12, 0xc9, 0xac, 0xc2, + 0x16, 0x66, 0x0b, 0x0b, 0xfd, 0xcd, 0xb2, 0x7f, 0x97, 0x86, 0x9a, 0x65, 0x4a, 0x40, 0xcb, 0x90, + 0x26, 0xd3, 0x76, 0x87, 0x9a, 0xa1, 0xcb, 0x7d, 0x5d, 0xcc, 0xae, 0xb3, 0x16, 0x95, 0x31, 0x31, + 0xf5, 0x94, 0x93, 0xc8, 0xeb, 0xd9, 0x02, 0x55, 0xa1, 0xd8, 0xf7, 0xf5, 0x81, 0xe5, 0x4d, 0xf2, + 0x7a, 0xc6, 0x81, 0x14, 0x38, 0xcb, 0xda, 0x8a, 0x1f, 0x84, 0x35, 0xf9, 0xa9, 0xcd, 0xc2, 0x8b, + 0x54, 0x54, 0xdf, 0xe5, 0x9e, 0xd0, 0xf3, 0xb9, 0x95, 0x31, 0x71, 0x46, 0xee, 0x4d, 0x25, 0x03, + 0x9e, 0x4f, 0x3d, 0x6c, 0x91, 0xa8, 0x70, 0xa5, 0xef, 0x80, 0x0f, 0x59, 0x56, 0x23, 0x03, 0x5e, + 0xf6, 0x91, 0xd9, 0x04, 0xa4, 0x4a, 0x96, 0xc5, 0x36, 0xb3, 0xaf, 0x0e, 0x98, 0x80, 0xba, 0x60, + 0x3e, 0x9b, 0x80, 0xd4, 0x2a, 0xe3, 0x24, 0x82, 0x94, 0x06, 0x96, 0x4d, 0x6e, 0x66, 0xaf, 0xf5, + 0x15, 0xd4, 0x73, 0xff, 0x1b, 0x11, 0xa4, 0xb8, 0x44, 0xe2, 0xf0, 0x98, 0xce, 0x0d, 0x26, 0xdc, + 0xe7, 0xbb, 0xde, 0xd7, 0xe1, 0x09, 0xbd, 0x68, 0x85, 0x38, 0x3c, 0x66, 0x20, 0x01, 0x7d, 0x1e, + 0x26, 0x38, 0x26, 0x2b, 0xdc, 0x18, 0xe0, 0x89, 0xfa, 0xc1, 0x34, 0x19, 0xd7, 0x9c, 0x87, 0x59, + 0x59, 0x86, 0x05, 0x59, 0xf5, 0x5e, 0x1a, 0x60, 0x65, 0x7b, 0xe0, 0x28, 0xb3, 0xb2, 0x1e, 0x99, + 0x58, 0x59, 0xd6, 0x4f, 0xf9, 0x5c, 0x77, 0xb3, 0xaf, 0x95, 0xed, 0x3d, 0xef, 0x41, 0xac, 0xec, + 0x53, 0x8f, 0x4a, 0x6a, 0x66, 0x31, 0x1c, 0x54, 0xf8, 0x4c, 0xdf, 0x9a, 0x05, 0x61, 0x21, 0xa9, + 0x19, 0xe7, 0x21, 0xcd, 0xc6, 0xa2, 0x77, 0x99, 0xa6, 0x5f, 0xee, 0x7f, 0xe6, 0xbc, 0x1b, 0x3d, + 0x54, 0x9c, 0xdb, 0x81, 0x99, 0x86, 0x5d, 0x43, 0x65, 0xf2, 0x13, 0xb6, 0x5c, 0x53, 0xaf, 0x0c, + 0x36, 0x54, 0x61, 0x87, 0x87, 0x5d, 0x43, 0x15, 0x48, 0xa4, 0x45, 0x65, 0xc7, 0xa6, 0xe8, 0xf8, + 0x5e, 0x1c, 0x70, 0x3c, 0xbe, 0xeb, 0x08, 0x1b, 0x2d, 0xaa, 0x4b, 0xf4, 0x86, 0x50, 0x9b, 0xdd, + 0xe3, 0x50, 0x58, 0x1a, 0x3c, 0x84, 0x82, 0xf7, 0x49, 0xb8, 0x43, 0x88, 0x93, 0xdd, 0x39, 0xd3, + 0xf1, 0x30, 0x5e, 0x1d, 0x3c, 0x67, 0x76, 0xbb, 0x16, 0x6c, 0xce, 0xe4, 0x3e, 0xc5, 0x7f, 0x17, + 0x60, 0x81, 0x95, 0x8d, 0x2e, 0xd9, 0x75, 0x24, 0x77, 0xf9, 0xd3, 0x17, 0xdc, 0x7f, 0x8b, 0xbe, + 0xe0, 0xf5, 0x7e, 0xc5, 0x1d, 0xb2, 0x9c, 0x5b, 0x19, 0x13, 0x5f, 0x90, 0x07, 0xe5, 0x5b, 0x99, + 0xe0, 0x7b, 0x97, 0xee, 0xc9, 0xc5, 0xa9, 0x7c, 0xfe, 0x41, 0x22, 0x75, 0x3e, 0x5f, 0x78, 0x90, + 0x48, 0x5d, 0xc8, 0xcf, 0x3e, 0x48, 0xa4, 0x2e, 0xe6, 0x2f, 0x15, 0xff, 0xe1, 0x02, 0x4c, 0x3a, + 0xe0, 0x8d, 0x21, 0xa2, 0xdb, 0x7e, 0x44, 0x34, 0xd7, 0x0f, 0x11, 0x71, 0xb8, 0xc7, 0x21, 0xd1, + 0x6d, 0x3f, 0x24, 0x9a, 0xeb, 0x07, 0x89, 0x3c, 0x1e, 0x82, 0x89, 0x6a, 0xfd, 0x30, 0xd1, 0x4b, + 0x23, 0x60, 0x22, 0x57, 0x54, 0x37, 0x28, 0x5a, 0xed, 0x05, 0x45, 0x57, 0x06, 0x83, 0x22, 0x57, + 0x94, 0x0f, 0x15, 0xdd, 0xed, 0x42, 0x45, 0x97, 0x07, 0xa0, 0x22, 0x97, 0xdf, 0x81, 0x45, 0xeb, + 0xa1, 0xb0, 0xe8, 0xda, 0x30, 0x58, 0xe4, 0xca, 0x09, 0xe0, 0xa2, 0xd7, 0x02, 0xb8, 0x68, 0xbe, + 0x2f, 0x2e, 0x72, 0xb9, 0x19, 0x30, 0x7a, 0xab, 0x1b, 0x18, 0x5d, 0x1e, 0x00, 0x8c, 0xbc, 0x1a, + 0x70, 0x64, 0x54, 0x09, 0x43, 0x46, 0x57, 0x87, 0x20, 0x23, 0x57, 0x8a, 0x1f, 0x1a, 0x55, 0xc2, + 0xa0, 0xd1, 0xd5, 0x21, 0xd0, 0xa8, 0x4b, 0x12, 0xc3, 0x46, 0x9b, 0xe1, 0xd8, 0xe8, 0xfa, 0x50, + 0x6c, 0xe4, 0x4a, 0x0b, 0x82, 0xa3, 0x25, 0x1f, 0x38, 0x7a, 0xa1, 0x0f, 0x38, 0x72, 0x59, 0x09, + 0x3a, 0xfa, 0x42, 0x0f, 0x3a, 0x2a, 0x0e, 0x42, 0x47, 0x2e, 0xaf, 0x0b, 0x8f, 0x1e, 0xf7, 0x81, + 0x47, 0x37, 0x86, 0xc3, 0x23, 0x57, 0x58, 0x17, 0x3e, 0x92, 0x07, 0xe2, 0xa3, 0x57, 0x46, 0xc4, + 0x47, 0xae, 0xf4, 0x30, 0x80, 0xf4, 0x46, 0x10, 0x20, 0x2d, 0xf4, 0x07, 0x48, 0xae, 0x18, 0x8e, + 0x90, 0xd6, 0x43, 0x11, 0xd2, 0xb5, 0x61, 0x08, 0xc9, 0x1b, 0x07, 0x7e, 0x88, 0xb4, 0x19, 0x0e, + 0x91, 0xae, 0x0f, 0x85, 0x48, 0x5e, 0xf3, 0x07, 0x30, 0xd2, 0x7a, 0x28, 0x46, 0xba, 0x36, 0x0c, + 0x23, 0x79, 0x85, 0xf3, 0x83, 0xa4, 0x77, 0xfa, 0x82, 0xa4, 0x9b, 0xa3, 0x80, 0x24, 0x57, 0x68, + 0x0f, 0x4a, 0x7a, 0xaf, 0x3f, 0x4a, 0xfa, 0xcc, 0x09, 0xae, 0xe4, 0x0b, 0x85, 0x49, 0x5f, 0xe8, + 0x81, 0x49, 0xc5, 0x41, 0x30, 0xc9, 0xeb, 0xcf, 0x0e, 0x4e, 0x92, 0x07, 0xa2, 0x9a, 0x57, 0x46, + 0x44, 0x35, 0x5e, 0xe7, 0x0b, 0x81, 0x35, 0xe5, 0x10, 0x58, 0x73, 0x65, 0x30, 0xac, 0xf1, 0xcc, + 0xb9, 0x87, 0x6b, 0x2a, 0x61, 0xb8, 0xe6, 0xea, 0x10, 0x5c, 0xe3, 0x59, 0x21, 0x1f, 0xb0, 0xb9, + 0xdb, 0x05, 0x6c, 0x2e, 0x0f, 0x0d, 0xcd, 0xf1, 0x21, 0x9b, 0x95, 0x5e, 0x64, 0xf3, 0xe2, 0x40, + 0x64, 0xe3, 0x4a, 0xf0, 0xa0, 0xcd, 0xdd, 0x2e, 0x68, 0x73, 0x79, 0x00, 0xb4, 0xf1, 0x0a, 0xc0, + 0xb1, 0x8d, 0x3a, 0x18, 0xdb, 0x2c, 0x8e, 0x8a, 0x6d, 0x5c, 0xc1, 0xa1, 0xe0, 0x66, 0x33, 0x1c, + 0xdc, 0x5c, 0x1f, 0x71, 0xa3, 0xbc, 0x07, 0xdd, 0x54, 0xc2, 0xd0, 0xcd, 0xd5, 0x21, 0xe8, 0xc6, + 0x3f, 0x87, 0xb8, 0xf0, 0xa6, 0x12, 0x06, 0x6f, 0xae, 0x0e, 0x81, 0x37, 0x9e, 0x24, 0x1f, 0xbe, + 0xa9, 0xf5, 0xc3, 0x37, 0x2f, 0x8d, 0x80, 0x6f, 0x3c, 0xe7, 0xa5, 0x0b, 0xe0, 0xbc, 0xdd, 0x0d, + 0x70, 0x8a, 0x83, 0x00, 0x8e, 0x37, 0x22, 0x1d, 0x84, 0xb3, 0x19, 0x8e, 0x70, 0xae, 0x0f, 0x45, + 0x38, 0x7e, 0x23, 0xe9, 0x83, 0x38, 0xeb, 0xa1, 0x10, 0xe7, 0xda, 0x30, 0x88, 0xe3, 0x19, 0x49, + 0x3f, 0xc6, 0x79, 0xbb, 0x1b, 0xe3, 0x14, 0x07, 0x61, 0x1c, 0xaf, 0x72, 0x0e, 0xc8, 0xa9, 0x84, + 0x81, 0x9c, 0xab, 0x43, 0x40, 0x8e, 0xd7, 0x78, 0x3e, 0x94, 0x23, 0x0f, 0x44, 0x39, 0xaf, 0x8c, + 0x88, 0x72, 0xba, 0x0c, 0x57, 0x10, 0xe6, 0x54, 0xc2, 0x60, 0xce, 0xd5, 0x21, 0x30, 0xc7, 0x57, + 0x58, 0x0f, 0xe7, 0x6c, 0x86, 0xe3, 0x9c, 0xeb, 0x43, 0x71, 0x4e, 0xd7, 0x68, 0x72, 0x80, 0xce, + 0x7a, 0x28, 0xd0, 0xb9, 0x36, 0x0c, 0xe8, 0x74, 0x4d, 0x7c, 0xdc, 0x39, 0xf8, 0x1f, 0xa3, 0x23, + 0x9d, 0x37, 0x4e, 0x8e, 0x74, 0xdc, 0x77, 0x46, 0x02, 0x75, 0x1e, 0x24, 0x52, 0x97, 0xf2, 0x2f, + 0x14, 0x7f, 0x77, 0x1c, 0x92, 0x15, 0x37, 0x9c, 0xc5, 0x2b, 0xa5, 0x70, 0x9a, 0xeb, 0x7f, 0xd0, + 0x2a, 0x19, 0xb1, 0xd4, 0xee, 0x0d, 0xbf, 0xe9, 0xad, 0xf7, 0x16, 0x32, 0xce, 0x7a, 0x8a, 0xd3, + 0xb7, 0xe8, 0x35, 0x98, 0x6c, 0x5b, 0xd8, 0x94, 0x5a, 0xa6, 0x66, 0x98, 0x9a, 0xcd, 0xce, 0x49, + 0x08, 0x2b, 0xf9, 0x8f, 0x8f, 0xe7, 0xb3, 0xdb, 0x16, 0x36, 0xb7, 0x38, 0x5d, 0xcc, 0xb6, 0x7d, + 0x4f, 0xce, 0xa7, 0x8c, 0xc6, 0x47, 0xff, 0x94, 0xd1, 0x63, 0xc8, 0x9b, 0x58, 0x56, 0x03, 0x1e, + 0x08, 0xbb, 0x5e, 0x27, 0xbc, 0xcf, 0xd0, 0x43, 0x42, 0x4e, 0x4e, 0x7a, 0xcd, 0xce, 0x94, 0x19, + 0x24, 0xa2, 0x5b, 0x70, 0xb6, 0x29, 0x1f, 0xd1, 0xc0, 0x45, 0xc9, 0x71, 0xea, 0x68, 0x30, 0x22, + 0xfb, 0x74, 0x10, 0x6a, 0xca, 0x47, 0xf4, 0xbb, 0x48, 0x2c, 0x89, 0x7e, 0x0f, 0xe1, 0x2a, 0xe4, + 0x54, 0xcd, 0xb2, 0x35, 0x5d, 0xb1, 0xf9, 0xc5, 0xaa, 0xec, 0xa6, 0xd2, 0x49, 0x87, 0xca, 0x6e, + 0x4f, 0xbd, 0x09, 0xd3, 0x3c, 0xae, 0xdd, 0xfb, 0x52, 0x12, 0x85, 0x2f, 0x29, 0x52, 0x0a, 0x92, + 0xe0, 0x7d, 0x1b, 0xab, 0x04, 0x53, 0x75, 0xd9, 0xc6, 0x87, 0x72, 0x47, 0x72, 0xce, 0x29, 0x65, + 0xe8, 0xbd, 0x84, 0x17, 0x9f, 0x1f, 0xcf, 0x4f, 0xde, 0x67, 0x49, 0x3d, 0xc7, 0x95, 0x26, 0xeb, + 0xbe, 0x04, 0x15, 0x5d, 0x87, 0x29, 0xd9, 0xea, 0xe8, 0x0a, 0x55, 0x0f, 0xd6, 0xad, 0xb6, 0x45, + 0x21, 0x45, 0x4a, 0xcc, 0x51, 0x72, 0xc9, 0xa1, 0xa2, 0xcb, 0x90, 0xe5, 0x41, 0xdf, 0xec, 0x2b, + 0x49, 0x53, 0xb4, 0xaa, 0xfc, 0x93, 0x01, 0xf4, 0x43, 0x49, 0xec, 0x52, 0xd4, 0x07, 0x89, 0x54, + 0x36, 0x3f, 0xf9, 0x20, 0x91, 0xca, 0xe5, 0xa7, 0x8a, 0xff, 0x57, 0x80, 0x6c, 0xe0, 0x2c, 0xc8, + 0xdd, 0xae, 0xad, 0xd8, 0x0b, 0xe1, 0xe8, 0xa7, 0x5f, 0xf4, 0x56, 0x8a, 0x6b, 0xdb, 0x89, 0x5d, + 0x9b, 0xef, 0xef, 0x3d, 0xd3, 0xb5, 0x00, 0x67, 0xff, 0xdf, 0x61, 0x7b, 0x33, 0xf1, 0xff, 0x3f, + 0x9c, 0x1f, 0x2b, 0xfe, 0x22, 0x0e, 0x93, 0xc1, 0x33, 0x1f, 0x6b, 0x5d, 0xe5, 0x0a, 0xb3, 0x4e, + 0x01, 0x8e, 0xc5, 0x01, 0xf7, 0xc5, 0xa5, 0xbd, 0xeb, 0xcc, 0x59, 0x31, 0x17, 0x06, 0x6c, 0x38, + 0xfb, 0xcb, 0xe9, 0x31, 0xce, 0xfe, 0x20, 0xe6, 0x8e, 0xf2, 0x45, 0x18, 0xa7, 0x37, 0x98, 0xf0, + 0xa2, 0x85, 0x9d, 0xc1, 0x2d, 0x93, 0x74, 0x91, 0x65, 0x23, 0x56, 0xa1, 0x76, 0xaa, 0x4b, 0xc1, + 0xbc, 0xfb, 0x17, 0x4e, 0xfe, 0xc1, 0x30, 0x7e, 0x35, 0xdc, 0xf8, 0xc9, 0xae, 0x86, 0x63, 0xfb, + 0xca, 0x8d, 0x06, 0xb3, 0xb8, 0x6c, 0x5c, 0x24, 0x7b, 0x0e, 0xba, 0x52, 0x11, 0xfc, 0x43, 0x72, + 0x8b, 0x22, 0xff, 0x90, 0x9c, 0x2f, 0x9c, 0x30, 0xe7, 0x8a, 0xa0, 0x83, 0x88, 0x05, 0x9d, 0xf2, + 0xa6, 0xfe, 0xb6, 0x00, 0x79, 0x3a, 0x64, 0xee, 0x61, 0xac, 0x46, 0xd2, 0x0b, 0x9d, 0x48, 0xc7, + 0xd8, 0xe8, 0xa1, 0xe4, 0x81, 0xeb, 0xe5, 0xe3, 0xc1, 0xeb, 0xe5, 0x8b, 0x1f, 0x0a, 0x90, 0x73, + 0x4b, 0xc8, 0xbe, 0x9d, 0x34, 0xe0, 0xc6, 0xb7, 0xd3, 0x7d, 0x4e, 0xc8, 0x39, 0xc4, 0x3e, 0xd2, + 0x47, 0x9c, 0xfc, 0x87, 0xd8, 0xd9, 0xa7, 0x6f, 0x7e, 0x43, 0x80, 0x19, 0xb7, 0x88, 0x25, 0xef, + 0x80, 0xf2, 0x29, 0xa2, 0xea, 0x45, 0xfa, 0x61, 0x39, 0x82, 0xd1, 0xe9, 0xed, 0x01, 0x23, 0x75, + 0x4f, 0xc4, 0xe3, 0x27, 0x80, 0x63, 0x7f, 0xb5, 0x56, 0xa5, 0x9f, 0x9c, 0x63, 0xff, 0xad, 0xe2, + 0x3d, 0x9f, 0x02, 0xe9, 0x48, 0x20, 0x5a, 0x1a, 0x69, 0xc8, 0x38, 0x5a, 0xa2, 0x99, 0x8b, 0x7f, + 0xe9, 0x6f, 0x89, 0xf2, 0x01, 0xf1, 0xf9, 0xee, 0x40, 0xfc, 0x40, 0x6e, 0x0c, 0x8a, 0x1b, 0x09, + 0xb4, 0x9c, 0x48, 0x72, 0xa3, 0x7b, 0x81, 0x73, 0xdd, 0xb1, 0xfe, 0xfe, 0x49, 0xaf, 0x4a, 0x03, + 0xe7, 0xbf, 0x5f, 0x77, 0x6a, 0x11, 0x1f, 0xfe, 0x7a, 0xbf, 0x05, 0x78, 0x33, 0xf1, 0xd1, 0x87, + 0xf3, 0xc2, 0xcd, 0x2a, 0xcc, 0x84, 0xcc, 0x66, 0x28, 0x07, 0xe0, 0xbb, 0x74, 0x9e, 0x7f, 0xba, + 0x6e, 0x79, 0x55, 0xda, 0xde, 0x2c, 0x3d, 0xda, 0xd8, 0x58, 0xab, 0xd5, 0xca, 0xab, 0x79, 0x01, + 0xe5, 0x21, 0x1b, 0xb8, 0xb2, 0x3e, 0xc6, 0x3e, 0x66, 0x77, 0xf3, 0x3f, 0x01, 0x78, 0x5f, 0xc2, + 0x20, 0xb2, 0xd6, 0xcb, 0xef, 0x4a, 0x4f, 0x96, 0x1f, 0x6e, 0x97, 0xab, 0xf9, 0x31, 0x84, 0x20, + 0xb7, 0xb2, 0x5c, 0x2b, 0x55, 0x24, 0xb1, 0x5c, 0xdd, 0x7a, 0xb4, 0x59, 0x2d, 0x3b, 0x1f, 0xc1, + 0xbb, 0xb9, 0x0a, 0x59, 0xff, 0x09, 0x78, 0x34, 0x03, 0x53, 0xa5, 0x4a, 0xb9, 0xb4, 0x2e, 0x3d, + 0x59, 0x5b, 0x96, 0x1e, 0x6f, 0x97, 0xb7, 0xcb, 0xf9, 0x31, 0x5a, 0x34, 0x4a, 0xbc, 0xb7, 0xfd, + 0xf0, 0x61, 0x5e, 0x40, 0x53, 0x90, 0x61, 0xcf, 0xf4, 0x7a, 0xfb, 0x7c, 0xec, 0xe6, 0x06, 0x64, + 0x7c, 0xf7, 0xdf, 0x91, 0xd7, 0x6d, 0x6d, 0x57, 0x2b, 0x52, 0x6d, 0x6d, 0xa3, 0x5c, 0xad, 0x2d, + 0x6f, 0x6c, 0x31, 0x19, 0x94, 0xb6, 0xbc, 0xf2, 0x48, 0xac, 0xe5, 0x05, 0xf7, 0xb9, 0xf6, 0x68, + 0xbb, 0x54, 0x71, 0xaa, 0x51, 0x4c, 0xa4, 0xe2, 0xf9, 0xf8, 0xcd, 0xa7, 0x70, 0xbe, 0xcf, 0x31, + 0x70, 0x94, 0x81, 0x89, 0x6d, 0x9d, 0xde, 0xff, 0x95, 0x1f, 0x43, 0x93, 0xbe, 0x93, 0xe0, 0x79, + 0x01, 0xa5, 0xd8, 0x19, 0xdf, 0x7c, 0x0c, 0x25, 0x21, 0x56, 0xbd, 0x93, 0x8f, 0x93, 0x82, 0xfa, + 0x0e, 0x52, 0xe7, 0x13, 0x28, 0xcd, 0x4f, 0x99, 0xe6, 0xc7, 0x51, 0xd6, 0x3b, 0xe6, 0x99, 0x4f, + 0xde, 0xbc, 0x0c, 0xbe, 0x23, 0x6d, 0x08, 0x20, 0xf9, 0x50, 0xb6, 0xb1, 0x65, 0xe7, 0xc7, 0xd0, + 0x04, 0xc4, 0x97, 0x1b, 0x8d, 0xbc, 0x70, 0xfb, 0x0f, 0x04, 0x48, 0x39, 0x17, 0xb6, 0xa3, 0x87, + 0x30, 0xce, 0x80, 0xfb, 0x7c, 0xff, 0x19, 0x89, 0x1a, 0xb5, 0xd9, 0x85, 0x61, 0x53, 0x56, 0x71, + 0x0c, 0xbd, 0xc3, 0xbf, 0xad, 0x49, 0x7a, 0x0c, 0x7a, 0x71, 0x50, 0x7f, 0x72, 0xa4, 0x0e, 0xee, + 0x74, 0x64, 0x8c, 0x14, 0xc7, 0x5e, 0x15, 0x56, 0x5e, 0xfa, 0xe8, 0x67, 0x73, 0x63, 0x1f, 0x3d, + 0x9f, 0x13, 0x7e, 0xf4, 0x7c, 0x4e, 0xf8, 0xc9, 0xf3, 0x39, 0xe1, 0xa7, 0xcf, 0xe7, 0x84, 0xff, + 0xf3, 0xf3, 0xb9, 0xb1, 0x1f, 0xfd, 0x7c, 0x6e, 0xec, 0x27, 0x3f, 0x9f, 0x1b, 0x7b, 0x6f, 0x82, + 0x73, 0xef, 0x24, 0xe9, 0x67, 0x3e, 0xef, 0xfc, 0x5b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe1, 0x41, + 0x40, 0x59, 0x09, 0x75, 0x00, 0x00, } diff --git a/pkg/roachpb/api.proto b/pkg/roachpb/api.proto index dddbc3e9768a..7f22258152ab 100644 --- a/pkg/roachpb/api.proto +++ b/pkg/roachpb/api.proto @@ -12,6 +12,7 @@ syntax = "proto3"; package cockroach.roachpb; option go_package = "roachpb"; +import "kv/kvserver/concurrency/lock/locking.proto"; import "roachpb/data.proto"; import "roachpb/errors.proto"; import "roachpb/metadata.proto"; @@ -349,6 +350,18 @@ message ScanRequest { // will set the batch_responses field in the ScanResponse instead of the rows // field. ScanFormat scan_format = 4; + + // The desired key-level locking mode used during this scan. When set to None + // (the default), no key-level locking mode is used - meaning that the scan + // does not acquire any locks. When set to any other strength, a lock of that + // strength is acquired with the Unreplicated durability (i.e. best-effort) on + // each of the keys scanned by the request, subject to any key limit applied + // to the batch which limits the number of keys returned. + // + // NOTE: the locks acquire with this strength are point locks on each of the + // keys returned by the request, not a single range lock over the entire span + // scanned by the request. + kv.kvserver.concurrency.lock.Strength key_locking = 5; } // A ScanResponse is the return value from the Scan() method. @@ -384,6 +397,18 @@ message ReverseScanRequest { // will set the batch_responses field in the ScanResponse instead of the rows // field. ScanFormat scan_format = 4; + + // The desired key-level locking mode used during this scan. When set to None + // (the default), no key-level locking mode is used - meaning that the scan + // does not acquire any locks. When set to any other strength, a lock of that + // strength is acquired with the Unreplicated durability (i.e. best-effort) on + // each of the keys scanned by the request, subject to any key limit applied + // to the batch which limits the number of keys returned. + // + // NOTE: the locks acquire with this strength are point locks on each of the + // keys returned by the request, not a single range lock over the entire span + // scanned by the request. + kv.kvserver.concurrency.lock.Strength key_locking = 5; } // A ReverseScanResponse is the return value from the ReverseScan() method. diff --git a/pkg/roachpb/batch_test.go b/pkg/roachpb/batch_test.go index be3729284243..0d44a64c61b2 100644 --- a/pkg/roachpb/batch_test.go +++ b/pkg/roachpb/batch_test.go @@ -229,9 +229,8 @@ func TestLockSpanIterate(t *testing.T) { {&ReverseScanRequest{}, &ReverseScanResponse{}, sp("d", "f"), sp("d", "e")}, {&PutRequest{}, &PutResponse{}, sp("m", ""), sp("", "")}, {&DeleteRangeRequest{}, &DeleteRangeResponse{}, sp("n", "p"), sp("o", "p")}, - // TODO(nvanbenschoten): uncomment in the next commit. - // {&ScanRequest{KeyLocking: lock.Exclusive}, &ScanResponse{}, sp("g", "i"), sp("h", "i")}, - // {&ReverseScanRequest{KeyLocking: lock.Exclusive}, &ReverseScanResponse{}, sp("j", "l"), sp("k", "l")}, + {&ScanRequest{KeyLocking: lock.Exclusive}, &ScanResponse{}, sp("g", "i"), sp("h", "i")}, + {&ReverseScanRequest{KeyLocking: lock.Exclusive}, &ReverseScanResponse{}, sp("j", "l"), sp("k", "l")}, } // NB: can't import testutils for RunTrueAndFalse. @@ -271,8 +270,7 @@ func TestLockSpanIterate(t *testing.T) { require.Equal(t, toExpSpans(testReqs[2], testReqs[3]), spans[lock.Replicated]) // The scans with KeyLocking are unreplicated locking requests. - require.Nil(t, nil, spans[lock.Unreplicated]) - // require.Equal(t, toExpSpans(testReqs[4], testReqs[5]), spans[lock.Unreplicated]) + require.Equal(t, toExpSpans(testReqs[4], testReqs[5]), spans[lock.Unreplicated]) }) } } diff --git a/pkg/roachpb/data.pb.go b/pkg/roachpb/data.pb.go index f3d74be4057a..47b88baf3314 100644 --- a/pkg/roachpb/data.pb.go +++ b/pkg/roachpb/data.pb.go @@ -91,7 +91,7 @@ func (x ValueType) String() string { return proto.EnumName(ValueType_name, int32(x)) } func (ValueType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{0} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{0} } // ReplicaChangeType is a parameter of ChangeReplicasTrigger. @@ -115,7 +115,7 @@ func (x ReplicaChangeType) String() string { return proto.EnumName(ReplicaChangeType_name, int32(x)) } func (ReplicaChangeType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{1} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{1} } // TransactionStatus specifies possible states for a transaction. @@ -167,7 +167,7 @@ func (x TransactionStatus) String() string { return proto.EnumName(TransactionStatus_name, int32(x)) } func (TransactionStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{2} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{2} } // Span is a key range with an inclusive start Key and an exclusive end Key. @@ -184,7 +184,7 @@ type Span struct { func (m *Span) Reset() { *m = Span{} } func (*Span) ProtoMessage() {} func (*Span) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{0} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{0} } func (m *Span) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -236,7 +236,7 @@ func (m *Value) Reset() { *m = Value{} } func (m *Value) String() string { return proto.CompactTextString(m) } func (*Value) ProtoMessage() {} func (*Value) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{1} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{1} } func (m *Value) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -272,7 +272,7 @@ func (m *KeyValue) Reset() { *m = KeyValue{} } func (m *KeyValue) String() string { return proto.CompactTextString(m) } func (*KeyValue) ProtoMessage() {} func (*KeyValue) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{2} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{2} } func (m *KeyValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -310,7 +310,7 @@ func (m *StoreIdent) Reset() { *m = StoreIdent{} } func (m *StoreIdent) String() string { return proto.CompactTextString(m) } func (*StoreIdent) ProtoMessage() {} func (*StoreIdent) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{3} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{3} } func (m *StoreIdent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -350,7 +350,7 @@ func (m *SplitTrigger) Reset() { *m = SplitTrigger{} } func (m *SplitTrigger) String() string { return proto.CompactTextString(m) } func (*SplitTrigger) ProtoMessage() {} func (*SplitTrigger) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{4} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{4} } func (m *SplitTrigger) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -398,7 +398,7 @@ func (m *MergeTrigger) Reset() { *m = MergeTrigger{} } func (m *MergeTrigger) String() string { return proto.CompactTextString(m) } func (*MergeTrigger) ProtoMessage() {} func (*MergeTrigger) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{5} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{5} } func (m *MergeTrigger) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -468,7 +468,7 @@ type ChangeReplicasTrigger struct { func (m *ChangeReplicasTrigger) Reset() { *m = ChangeReplicasTrigger{} } func (*ChangeReplicasTrigger) ProtoMessage() {} func (*ChangeReplicasTrigger) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{6} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{6} } func (m *ChangeReplicasTrigger) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -510,7 +510,7 @@ func (m *ModifiedSpanTrigger) Reset() { *m = ModifiedSpanTrigger{} } func (m *ModifiedSpanTrigger) String() string { return proto.CompactTextString(m) } func (*ModifiedSpanTrigger) ProtoMessage() {} func (*ModifiedSpanTrigger) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{7} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{7} } func (m *ModifiedSpanTrigger) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -556,7 +556,7 @@ func (m *StickyBitTrigger) Reset() { *m = StickyBitTrigger{} } func (m *StickyBitTrigger) String() string { return proto.CompactTextString(m) } func (*StickyBitTrigger) ProtoMessage() {} func (*StickyBitTrigger) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{8} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{8} } func (m *StickyBitTrigger) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -595,7 +595,7 @@ func (m *InternalCommitTrigger) Reset() { *m = InternalCommitTrigger{} } func (m *InternalCommitTrigger) String() string { return proto.CompactTextString(m) } func (*InternalCommitTrigger) ProtoMessage() {} func (*InternalCommitTrigger) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{9} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{9} } func (m *InternalCommitTrigger) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -664,7 +664,7 @@ func (m *ObservedTimestamp) Reset() { *m = ObservedTimestamp{} } func (m *ObservedTimestamp) String() string { return proto.CompactTextString(m) } func (*ObservedTimestamp) ProtoMessage() {} func (*ObservedTimestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{10} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{10} } func (m *ObservedTimestamp) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -899,7 +899,7 @@ type Transaction struct { func (m *Transaction) Reset() { *m = Transaction{} } func (*Transaction) ProtoMessage() {} func (*Transaction) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{11} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{11} } func (m *Transaction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -950,7 +950,7 @@ func (m *TransactionRecord) Reset() { *m = TransactionRecord{} } func (m *TransactionRecord) String() string { return proto.CompactTextString(m) } func (*TransactionRecord) ProtoMessage() {} func (*TransactionRecord) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{12} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{12} } func (m *TransactionRecord) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -990,7 +990,7 @@ func (m *Intent) Reset() { *m = Intent{} } func (m *Intent) String() string { return proto.CompactTextString(m) } func (*Intent) ProtoMessage() {} func (*Intent) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{13} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{13} } func (m *Intent) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1027,7 +1027,7 @@ func (m *Intent_SingleKeySpan) Reset() { *m = Intent_SingleKeySpan{} } func (m *Intent_SingleKeySpan) String() string { return proto.CompactTextString(m) } func (*Intent_SingleKeySpan) ProtoMessage() {} func (*Intent_SingleKeySpan) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{13, 0} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{13, 0} } func (m *Intent_SingleKeySpan) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1069,7 +1069,7 @@ func (m *LockUpdate) Reset() { *m = LockUpdate{} } func (m *LockUpdate) String() string { return proto.CompactTextString(m) } func (*LockUpdate) ProtoMessage() {} func (*LockUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{14} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{14} } func (m *LockUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1106,7 +1106,7 @@ func (m *SequencedWrite) Reset() { *m = SequencedWrite{} } func (m *SequencedWrite) String() string { return proto.CompactTextString(m) } func (*SequencedWrite) ProtoMessage() {} func (*SequencedWrite) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{15} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{15} } func (m *SequencedWrite) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1170,7 +1170,7 @@ type Lease struct { func (m *Lease) Reset() { *m = Lease{} } func (*Lease) ProtoMessage() {} func (*Lease) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{16} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{16} } func (m *Lease) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1215,7 +1215,7 @@ func (m *AbortSpanEntry) Reset() { *m = AbortSpanEntry{} } func (m *AbortSpanEntry) String() string { return proto.CompactTextString(m) } func (*AbortSpanEntry) ProtoMessage() {} func (*AbortSpanEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{17} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{17} } func (m *AbortSpanEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1272,7 +1272,7 @@ func (m *LeafTxnInputState) Reset() { *m = LeafTxnInputState{} } func (m *LeafTxnInputState) String() string { return proto.CompactTextString(m) } func (*LeafTxnInputState) ProtoMessage() {} func (*LeafTxnInputState) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{18} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{18} } func (m *LeafTxnInputState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1325,7 +1325,7 @@ func (m *LeafTxnFinalState) Reset() { *m = LeafTxnFinalState{} } func (m *LeafTxnFinalState) String() string { return proto.CompactTextString(m) } func (*LeafTxnFinalState) ProtoMessage() {} func (*LeafTxnFinalState) Descriptor() ([]byte, []int) { - return fileDescriptor_data_424e0a1744dc1634, []int{19} + return fileDescriptor_data_89213d6ce1c1cfb8, []int{19} } func (m *LeafTxnFinalState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7107,10 +7107,10 @@ var ( ErrIntOverflowData = fmt.Errorf("proto: integer overflow") ) -func init() { proto.RegisterFile("roachpb/data.proto", fileDescriptor_data_424e0a1744dc1634) } +func init() { proto.RegisterFile("roachpb/data.proto", fileDescriptor_data_89213d6ce1c1cfb8) } -var fileDescriptor_data_424e0a1744dc1634 = []byte{ - // 2360 bytes of a gzipped FileDescriptorProto +var fileDescriptor_data_89213d6ce1c1cfb8 = []byte{ + // 2361 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xcd, 0x6f, 0xdb, 0xc8, 0x15, 0x37, 0x2d, 0x4a, 0xa2, 0x9e, 0x3e, 0x4c, 0x4f, 0xe2, 0x44, 0xeb, 0xb4, 0x56, 0xaa, 0x6d, 0xbb, 0x69, 0xd0, 0x95, 0x51, 0x67, 0xbb, 0x68, 0xd3, 0xa0, 0xa8, 0x64, 0x29, 0x89, 0x14, 0x4b, @@ -7120,143 +7120,143 @@ var fileDescriptor_data_424e0a1744dc1634 = []byte{ 0x50, 0xa0, 0x98, 0x19, 0x7e, 0x39, 0x56, 0x0c, 0x79, 0x9d, 0x02, 0x8b, 0x5e, 0x64, 0x72, 0xde, 0x7b, 0xbf, 0x37, 0xf3, 0xbe, 0x39, 0x06, 0xe4, 0x3a, 0x9a, 0xbe, 0x37, 0xea, 0xaf, 0x1b, 0x9a, 0xa7, 0x55, 0x46, 0xae, 0xe3, 0x39, 0x68, 0x59, 0x77, 0xf4, 0x7d, 0xb6, 0x5e, 0xf1, 0xa9, 0xab, - 0x97, 0x02, 0x36, 0x0b, 0x7b, 0x5a, 0xc4, 0xba, 0x7a, 0x7d, 0xff, 0x60, 0x7d, 0xff, 0x80, 0x60, - 0xf7, 0x00, 0xbb, 0xeb, 0xba, 0x63, 0xeb, 0x63, 0xd7, 0xc5, 0xb6, 0x3e, 0x59, 0x1f, 0x3a, 0xfa, - 0x3e, 0xfb, 0x31, 0xed, 0x81, 0xcf, 0x7b, 0x85, 0x78, 0x8e, 0xab, 0x0d, 0xf0, 0x3a, 0xb6, 0x07, - 0xa6, 0x8d, 0x29, 0xd8, 0x81, 0xae, 0xfb, 0xc4, 0xaf, 0xcd, 0x24, 0xde, 0xf0, 0xa9, 0xc5, 0xb1, - 0x67, 0x0e, 0xd7, 0xf7, 0x86, 0xfa, 0xba, 0x67, 0x5a, 0x98, 0x78, 0x9a, 0x35, 0xf2, 0x29, 0x17, - 0x07, 0xce, 0xc0, 0x61, 0x8f, 0xeb, 0xf4, 0x89, 0xaf, 0x96, 0x3f, 0x01, 0xb1, 0x3b, 0xd2, 0x6c, - 0xf4, 0x16, 0x24, 0xf6, 0xf1, 0xa4, 0x98, 0xb8, 0x2a, 0x5c, 0xcb, 0xd5, 0xd2, 0x2f, 0xa7, 0xa5, - 0xc4, 0x3d, 0x3c, 0x51, 0xe8, 0x1a, 0xba, 0x0a, 0x69, 0x6c, 0x1b, 0x2a, 0x25, 0x8b, 0xc7, 0xc9, - 0x29, 0x6c, 0x1b, 0xf7, 0xf0, 0xe4, 0x66, 0xee, 0x37, 0x4f, 0x4b, 0x0b, 0x7f, 0x7c, 0x5a, 0x12, - 0xfe, 0xf9, 0xb4, 0x24, 0xb4, 0x44, 0x49, 0x90, 0x17, 0x5b, 0xa2, 0xb4, 0x28, 0x27, 0xca, 0x16, - 0x24, 0x1f, 0x68, 0xc3, 0x31, 0x46, 0x57, 0x20, 0xe3, 0x6a, 0x4f, 0xd4, 0xfe, 0xc4, 0xc3, 0xa4, - 0x28, 0x50, 0x18, 0x45, 0x72, 0xb5, 0x27, 0x35, 0xfa, 0x8e, 0xaa, 0x90, 0x09, 0x77, 0x5b, 0x5c, - 0xbc, 0x2a, 0x5c, 0xcb, 0x6e, 0x7c, 0xbd, 0x12, 0x99, 0x96, 0x1e, 0xa9, 0xb2, 0x37, 0xd4, 0x2b, - 0xbd, 0x80, 0xa9, 0x26, 0x3e, 0x9b, 0x96, 0x16, 0x94, 0x48, 0xea, 0xa6, 0x48, 0x55, 0x97, 0x3f, - 0x02, 0xe9, 0x1e, 0x9e, 0x70, 0x8d, 0xfe, 0x89, 0x84, 0x19, 0x27, 0x7a, 0x0f, 0x92, 0x07, 0x94, - 0xc7, 0xd7, 0x55, 0xac, 0x9c, 0x70, 0x63, 0x85, 0x61, 0xf8, 0x6a, 0x38, 0x73, 0xf9, 0xaf, 0x02, - 0x40, 0xd7, 0x73, 0x5c, 0xdc, 0x34, 0xb0, 0xed, 0xa1, 0x01, 0x80, 0x3e, 0x1c, 0x13, 0x0f, 0xbb, - 0xaa, 0x69, 0xf8, 0x6a, 0xee, 0x52, 0xfe, 0xbf, 0x4d, 0x4b, 0x37, 0x06, 0xa6, 0xb7, 0x37, 0xee, - 0x57, 0x74, 0xc7, 0x5a, 0x0f, 0xb1, 0x8d, 0x7e, 0xf4, 0xbc, 0x3e, 0xda, 0x1f, 0xac, 0x33, 0x57, - 0x8d, 0xc7, 0xa6, 0x51, 0xd9, 0xd9, 0x69, 0xd6, 0x8f, 0xa6, 0xa5, 0xcc, 0x26, 0x07, 0x6c, 0xd6, - 0x95, 0x8c, 0x8f, 0xdd, 0x34, 0xd0, 0xbb, 0x90, 0xb6, 0x1d, 0x03, 0x53, 0x2d, 0x74, 0xbf, 0xc9, - 0xda, 0xc5, 0xa3, 0x69, 0x29, 0xd5, 0x71, 0x0c, 0xdc, 0xac, 0xbf, 0x0c, 0x9f, 0x94, 0x14, 0x65, - 0x6a, 0x1a, 0xe8, 0x7b, 0x20, 0xd1, 0x08, 0x61, 0xfc, 0x09, 0xc6, 0x7f, 0xe9, 0x68, 0x5a, 0x4a, - 0xf3, 0x9d, 0x53, 0x81, 0xe0, 0x51, 0x49, 0x13, 0x7e, 0x9a, 0xf2, 0xef, 0x04, 0xc8, 0x75, 0x47, - 0x43, 0xd3, 0xeb, 0xb9, 0xe6, 0x60, 0x80, 0x5d, 0xd4, 0x80, 0xcc, 0x10, 0xef, 0x7a, 0xaa, 0x81, - 0x89, 0xce, 0x8e, 0x96, 0xdd, 0x28, 0xcf, 0x30, 0x92, 0xa2, 0xd9, 0x03, 0x5c, 0xc7, 0x44, 0x77, - 0xcd, 0x91, 0xe7, 0xb8, 0xbe, 0xb9, 0x24, 0x2a, 0x4a, 0x57, 0xd1, 0x1d, 0x00, 0xd7, 0x1c, 0xec, - 0xf9, 0x38, 0x8b, 0x67, 0xc4, 0xc9, 0x30, 0x59, 0xba, 0xcc, 0xbd, 0xdb, 0x12, 0xa5, 0x84, 0x2c, - 0x96, 0xbf, 0x58, 0x84, 0x5c, 0x1b, 0xbb, 0x03, 0xfc, 0x15, 0xdd, 0x2c, 0x1a, 0x80, 0xcc, 0x81, - 0x68, 0x5e, 0xaa, 0xc4, 0xd3, 0x3c, 0xc2, 0x12, 0x27, 0xbb, 0xf1, 0xad, 0x18, 0x9c, 0x9f, 0xc5, - 0x95, 0x20, 0x8b, 0x2b, 0xed, 0x07, 0x9b, 0x9b, 0x5d, 0xca, 0x5c, 0xbb, 0x44, 0x11, 0x8f, 0xa6, - 0xa5, 0x82, 0x42, 0x61, 0xc2, 0x75, 0xa5, 0xc0, 0x60, 0xdb, 0x07, 0xba, 0xce, 0xde, 0xd1, 0x6d, - 0xc8, 0xed, 0xba, 0x18, 0xff, 0x1c, 0x53, 0x25, 0xae, 0x57, 0x4c, 0xce, 0x9f, 0x39, 0x59, 0x2e, - 0xd8, 0xa5, 0x72, 0xc7, 0xac, 0xfb, 0xfb, 0x24, 0xac, 0x6c, 0xee, 0xd1, 0x23, 0x2a, 0x78, 0x34, - 0x34, 0x75, 0x8d, 0x04, 0x66, 0x7e, 0x04, 0x97, 0x0c, 0x3c, 0x72, 0xb1, 0xae, 0x79, 0xd8, 0x50, - 0x75, 0xc6, 0xa3, 0x7a, 0x93, 0x11, 0x66, 0x36, 0x2f, 0x6c, 0x7c, 0x73, 0x96, 0xad, 0x38, 0x06, - 0x07, 0xec, 0x4d, 0x46, 0x58, 0xb9, 0x18, 0x61, 0x44, 0xab, 0xe8, 0x21, 0xa0, 0x18, 0xb6, 0xcb, - 0xa5, 0x7c, 0x1f, 0x9c, 0x82, 0x7b, 0xc2, 0x0b, 0xcb, 0x11, 0x8a, 0xcf, 0x82, 0x7e, 0x06, 0x57, - 0x62, 0xd0, 0xe3, 0x91, 0x11, 0x57, 0x41, 0x8a, 0x89, 0xab, 0x89, 0x33, 0xea, 0x78, 0x2b, 0x82, - 0xdb, 0xe1, 0x68, 0x81, 0xa5, 0x10, 0x86, 0xd5, 0x98, 0x2e, 0x1b, 0x1f, 0x7a, 0x81, 0x22, 0x9a, - 0x8c, 0x22, 0x4b, 0xc6, 0x6b, 0x47, 0xd3, 0xd2, 0xe5, 0x7a, 0xc8, 0xd5, 0xc1, 0x87, 0x9e, 0x2f, - 0xcf, 0x92, 0x33, 0x13, 0xbe, 0x28, 0x97, 0x8d, 0x99, 0x5c, 0x06, 0x7a, 0x1f, 0x44, 0x16, 0xa3, - 0xc9, 0x79, 0x63, 0x54, 0x61, 0xfc, 0xa8, 0x0f, 0x97, 0x4d, 0xdb, 0xc3, 0xae, 0xad, 0x0d, 0x55, - 0xcd, 0x30, 0xe2, 0x66, 0x48, 0x9d, 0xd9, 0x0c, 0x2b, 0x01, 0x54, 0x95, 0x22, 0x85, 0x26, 0xd8, - 0x85, 0xb7, 0x42, 0x1d, 0x2e, 0xb6, 0x9c, 0x83, 0xb8, 0x96, 0xf4, 0x99, 0xb5, 0x84, 0x1b, 0x56, - 0x38, 0x56, 0xa0, 0xe7, 0xa6, 0x44, 0x5b, 0x0e, 0xab, 0xf9, 0x9f, 0x09, 0x70, 0xa1, 0xed, 0x18, - 0xe6, 0xae, 0x89, 0x0d, 0xda, 0xca, 0x82, 0x78, 0xfd, 0x2e, 0x20, 0x32, 0x21, 0x1e, 0xb6, 0x54, - 0xdd, 0xb1, 0x77, 0xcd, 0x81, 0x4a, 0x46, 0x9a, 0xcd, 0x62, 0x55, 0x52, 0x64, 0x4e, 0xd9, 0x64, - 0x04, 0xd6, 0xff, 0x1a, 0x80, 0x58, 0x91, 0x1d, 0x9a, 0x07, 0xd8, 0xc6, 0x84, 0x70, 0x6e, 0x1e, - 0x81, 0x97, 0x67, 0x6c, 0x98, 0x0a, 0x29, 0x32, 0x15, 0xd9, 0xf2, 0x25, 0xe8, 0x8a, 0xdf, 0x86, - 0x3e, 0x06, 0xb9, 0xeb, 0x99, 0xfa, 0xfe, 0xa4, 0x16, 0x95, 0xd4, 0x1a, 0x00, 0x61, 0x6b, 0x6a, - 0xdf, 0xf4, 0xfc, 0x32, 0x35, 0x5f, 0x93, 0x23, 0x01, 0x94, 0x8f, 0xfe, 0xa7, 0x04, 0xac, 0x34, - 0x7d, 0xb3, 0x6c, 0x3a, 0x96, 0x15, 0xe9, 0xa8, 0x43, 0x9e, 0xd0, 0x32, 0xae, 0x7a, 0x7c, 0xc1, - 0x57, 0x53, 0x9a, 0xb9, 0xff, 0xa8, 0xdc, 0x2b, 0x39, 0x12, 0x2f, 0xfe, 0x75, 0xc8, 0x5b, 0xb4, - 0xbe, 0x86, 0x28, 0x8b, 0xaf, 0x45, 0x89, 0xd7, 0x61, 0x25, 0x67, 0xc5, 0xab, 0xf2, 0x4f, 0xe1, - 0xb2, 0x5f, 0x23, 0x02, 0xf7, 0x87, 0x78, 0x09, 0x86, 0x77, 0x6d, 0x06, 0xde, 0xcc, 0xca, 0xa3, - 0xac, 0xe8, 0xaf, 0x29, 0x48, 0x2b, 0x96, 0xef, 0x77, 0xe6, 0xad, 0x10, 0x9f, 0x17, 0xdb, 0x6f, - 0xcf, 0xda, 0xef, 0xc9, 0x38, 0x51, 0x2e, 0x58, 0x33, 0x82, 0xe7, 0x03, 0x40, 0x91, 0xb7, 0x42, - 0x60, 0x9e, 0x70, 0x6f, 0xcf, 0x32, 0xe7, 0x2b, 0xee, 0x56, 0x64, 0xf2, 0xca, 0xca, 0x4d, 0xe9, - 0x53, 0x7f, 0x40, 0x2a, 0xff, 0x4a, 0x80, 0xe5, 0xed, 0x3e, 0x1b, 0x05, 0x8d, 0xd0, 0xdb, 0xf1, - 0x36, 0x2f, 0xcc, 0xd1, 0xe6, 0xdf, 0xc0, 0xcc, 0x24, 0x05, 0x23, 0x5b, 0xf9, 0x2f, 0x69, 0xc8, - 0xf6, 0x5c, 0xcd, 0x26, 0x9a, 0xee, 0x99, 0x8e, 0x8d, 0xaa, 0x20, 0xd2, 0xf1, 0xd5, 0x8f, 0x9f, - 0xb7, 0x4f, 0x6b, 0x5b, 0xbd, 0x43, 0xbb, 0x8d, 0x3d, 0xad, 0x26, 0x51, 0xf4, 0xe7, 0xd3, 0x92, - 0xa0, 0x30, 0x51, 0x84, 0x40, 0xb4, 0x35, 0x8b, 0x8f, 0x58, 0x19, 0x85, 0x3d, 0xa3, 0x5b, 0x90, - 0xa2, 0xed, 0x70, 0xcc, 0xfb, 0xe1, 0xec, 0x96, 0x11, 0xdb, 0x46, 0x97, 0xf1, 0x2a, 0xbe, 0x0c, - 0x6a, 0x41, 0x61, 0xa8, 0x11, 0x4f, 0xdd, 0xc3, 0x9a, 0xeb, 0xf5, 0xb1, 0x76, 0xa6, 0x86, 0x97, - 0xa7, 0xa2, 0x77, 0x03, 0x49, 0xa4, 0x42, 0xac, 0x8c, 0xab, 0x8e, 0x6b, 0x0e, 0xd4, 0xc8, 0x9a, - 0xa9, 0xf9, 0x61, 0x63, 0x35, 0x7a, 0xdb, 0x35, 0x07, 0x91, 0x37, 0xef, 0x42, 0xde, 0xd2, 0x0e, - 0x63, 0xa0, 0xe9, 0xf9, 0x41, 0x73, 0x96, 0x76, 0x18, 0x21, 0x7d, 0x04, 0x17, 0x1c, 0x3f, 0x58, - 0x22, 0x38, 0x52, 0x94, 0x5e, 0x5b, 0x4b, 0x4f, 0x84, 0x96, 0x0f, 0x8b, 0x9c, 0x57, 0x09, 0x04, - 0xdd, 0x02, 0xa0, 0x9f, 0x1e, 0x2c, 0x7f, 0x48, 0x31, 0xcb, 0x30, 0x5f, 0x57, 0xee, 0x82, 0x00, - 0xa2, 0x02, 0xf4, 0x9d, 0xa0, 0x32, 0xe4, 0x9f, 0xb8, 0xa6, 0x87, 0x55, 0xcf, 0x71, 0x54, 0x67, - 0x68, 0x14, 0x73, 0xac, 0xba, 0x66, 0xd9, 0x62, 0xcf, 0x71, 0xb6, 0x87, 0x06, 0xf5, 0x9a, 0x8b, - 0xb5, 0xd8, 0xd6, 0x8b, 0x4b, 0x67, 0xf0, 0x1a, 0x15, 0x8d, 0x4c, 0xf1, 0x1e, 0x5c, 0xd2, 0x59, - 0xc1, 0x8b, 0xd0, 0xd4, 0x5d, 0xf3, 0x10, 0x1b, 0x45, 0x99, 0x29, 0xbe, 0xc8, 0xa9, 0xa1, 0xc0, - 0x6d, 0x4a, 0x43, 0x1f, 0x80, 0x6c, 0xda, 0xea, 0xee, 0x90, 0xcd, 0x64, 0x6c, 0x6b, 0xa4, 0xb8, - 0xcc, 0x4e, 0xfa, 0x8d, 0x59, 0x27, 0xc5, 0x8f, 0xc7, 0xd8, 0xd6, 0xb1, 0xf1, 0x21, 0xe5, 0xf4, - 0xf7, 0x51, 0x30, 0xed, 0xdb, 0x4c, 0x9e, 0x2d, 0x12, 0xe4, 0xc0, 0x92, 0x39, 0xb0, 0x1d, 0x97, - 0x56, 0x1e, 0xfc, 0xd8, 0x1e, 0x5b, 0xa4, 0x88, 0x18, 0x62, 0xe5, 0xb4, 0x54, 0x69, 0x72, 0x91, - 0x2e, 0x7e, 0xdc, 0x19, 0x5b, 0xac, 0x45, 0x47, 0xa3, 0xde, 0x31, 0x1a, 0x51, 0x0a, 0x66, 0xf8, - 0x4e, 0xd1, 0x4f, 0x7c, 0x61, 0x25, 0x64, 0xb1, 0x25, 0x4a, 0x19, 0x19, 0x5a, 0xa2, 0x94, 0x97, - 0x0b, 0x2d, 0x51, 0x2a, 0xc8, 0x4b, 0xe5, 0x3f, 0x88, 0xb0, 0x1c, 0xcb, 0x1f, 0x05, 0xeb, 0x8e, - 0x6b, 0xbc, 0x89, 0x64, 0xfe, 0xea, 0x24, 0xee, 0xf9, 0x02, 0xf6, 0xff, 0x21, 0x14, 0xa4, 0x58, - 0x18, 0x2c, 0xca, 0x89, 0x30, 0x18, 0x52, 0x72, 0xba, 0x25, 0x4a, 0x69, 0x59, 0x6a, 0x89, 0x92, - 0x24, 0x67, 0xc2, 0xf0, 0x00, 0x39, 0xdb, 0x12, 0xa5, 0x9c, 0x9c, 0x8f, 0x87, 0x4a, 0x4b, 0x94, - 0x96, 0x64, 0xb9, 0x25, 0x4a, 0xb2, 0xbc, 0x5c, 0xfe, 0x97, 0x00, 0x29, 0x3a, 0x50, 0xd8, 0x1e, - 0x7a, 0x08, 0x4b, 0xc4, 0xb4, 0x07, 0x43, 0x4c, 0x3f, 0xf7, 0xa3, 0x89, 0x29, 0xbb, 0xf1, 0xce, - 0x0c, 0xfb, 0x70, 0x99, 0x4a, 0x97, 0x09, 0xdc, 0xc3, 0x13, 0x66, 0xf3, 0x28, 0x74, 0xf2, 0x24, - 0x4e, 0x40, 0x3f, 0x82, 0x84, 0x77, 0x18, 0x8c, 0x54, 0x73, 0x45, 0x21, 0x37, 0x38, 0x95, 0x5a, - 0xad, 0x41, 0xfe, 0x98, 0x9a, 0x53, 0xee, 0x2b, 0xc2, 0xcf, 0x99, 0xf0, 0x16, 0xa2, 0x25, 0x4a, - 0xa2, 0x9c, 0xf4, 0xa7, 0xa7, 0x5f, 0x24, 0x00, 0xb6, 0x1c, 0x7d, 0x9f, 0xcf, 0xee, 0xe8, 0xfb, - 0x20, 0xc6, 0x4e, 0xf9, 0xda, 0x48, 0x8a, 0x25, 0x04, 0x39, 0xef, 0x61, 0x62, 0xd9, 0x94, 0xf8, - 0x12, 0xd9, 0x34, 0x23, 0xe0, 0xc4, 0xff, 0x65, 0xc0, 0x21, 0x05, 0xc0, 0x18, 0xbb, 0x5a, 0xdf, - 0x1c, 0x9a, 0xde, 0x84, 0xa5, 0x6e, 0x61, 0x63, 0x23, 0xa6, 0x6b, 0xff, 0xa0, 0x12, 0x5c, 0x6c, - 0x55, 0x62, 0x17, 0x5b, 0x15, 0x9a, 0x76, 0x95, 0x7a, 0x28, 0xa9, 0xc4, 0x50, 0x7c, 0x5f, 0xfc, - 0x5a, 0x80, 0xc2, 0xf1, 0x24, 0x3b, 0xed, 0xd6, 0xe6, 0x63, 0x90, 0x88, 0xcf, 0xec, 0x5f, 0x84, - 0xfc, 0xe4, 0xe5, 0xb4, 0x74, 0x6b, 0xae, 0xab, 0x96, 0x57, 0xef, 0xcc, 0xa8, 0x5b, 0xba, 0xf8, - 0xb1, 0x12, 0x22, 0xc6, 0x86, 0xa1, 0xff, 0x24, 0x20, 0xb9, 0x85, 0x35, 0x82, 0xd1, 0x0f, 0x21, - 0xc9, 0xbf, 0xac, 0xcf, 0x30, 0xae, 0x73, 0x09, 0xf4, 0x09, 0x00, 0x3e, 0x1c, 0x99, 0xae, 0x46, - 0x3d, 0x38, 0xdf, 0x7c, 0xb6, 0xf6, 0xef, 0x69, 0x69, 0x35, 0x76, 0x84, 0x9b, 0x65, 0x57, 0xb3, - 0x0d, 0x7b, 0x3c, 0x1c, 0x6a, 0xfd, 0x21, 0x2e, 0x2b, 0x31, 0x40, 0x54, 0x87, 0x74, 0xf0, 0x95, - 0x9c, 0x38, 0xf3, 0x57, 0x72, 0x20, 0x8a, 0xc6, 0x10, 0x9b, 0x5f, 0xf8, 0x25, 0x02, 0xfd, 0x25, - 0x66, 0x70, 0x61, 0x71, 0xce, 0x1d, 0xaf, 0x44, 0xe8, 0xec, 0xa6, 0xa1, 0xcb, 0xb0, 0x51, 0x07, - 0xb2, 0x23, 0xd7, 0x19, 0x39, 0x84, 0x4e, 0x34, 0x64, 0xbe, 0x66, 0x50, 0x38, 0x9a, 0x96, 0xe0, - 0xbe, 0x2f, 0xd5, 0xeb, 0x2a, 0x10, 0x20, 0xf4, 0x08, 0xba, 0x08, 0x49, 0x3c, 0x72, 0xf4, 0x3d, - 0x36, 0xb8, 0x25, 0x14, 0xfe, 0x82, 0xde, 0x8d, 0x85, 0x0b, 0x1d, 0xbe, 0x12, 0xb5, 0xe5, 0x97, - 0xd3, 0x52, 0x9e, 0x79, 0x36, 0x08, 0xba, 0xb8, 0xff, 0x83, 0x0e, 0x5b, 0xfe, 0x42, 0x80, 0x42, - 0xb5, 0xef, 0xb8, 0x1e, 0xcd, 0xfc, 0x86, 0xed, 0xb9, 0x93, 0xd3, 0xa2, 0xf2, 0xfc, 0x73, 0x38, - 0xd2, 0x40, 0x1a, 0xb9, 0xa6, 0xe3, 0xd2, 0xf4, 0xe2, 0x37, 0x76, 0x8d, 0x97, 0xd3, 0x52, 0xf5, - 0x4b, 0x07, 0xf6, 0x7d, 0x1f, 0x4c, 0x09, 0x61, 0xe3, 0xd1, 0xbd, 0x08, 0xcb, 0x5b, 0x58, 0xdb, - 0xed, 0x1d, 0xda, 0x4d, 0x7b, 0x34, 0xa6, 0x3e, 0xf1, 0x30, 0x7a, 0x9f, 0xd7, 0x33, 0x1e, 0xe7, - 0x6b, 0xa7, 0xd7, 0xa3, 0x78, 0x29, 0x7b, 0x07, 0x96, 0x5c, 0xbc, 0xeb, 0x62, 0xb2, 0xa7, 0x9a, - 0xf6, 0x81, 0x36, 0x34, 0x0d, 0x66, 0x6b, 0x49, 0x29, 0xf8, 0xcb, 0x4d, 0xbe, 0x3a, 0xb3, 0xf3, - 0x4a, 0xe7, 0xeb, 0xbc, 0x1b, 0xb0, 0x42, 0x3c, 0x3c, 0x1a, 0x99, 0xf6, 0x40, 0xb5, 0xe8, 0x97, - 0x13, 0xb6, 0x69, 0xd8, 0x19, 0xc5, 0x0c, 0xdb, 0xc1, 0x85, 0x80, 0xd8, 0x76, 0x0c, 0xdc, 0xe0, - 0x24, 0xd4, 0x87, 0x1c, 0x9b, 0x46, 0x09, 0x7e, 0xac, 0xda, 0x63, 0xab, 0x08, 0x6f, 0xa8, 0x8e, - 0x00, 0x45, 0xe5, 0x05, 0xf4, 0x95, 0xb6, 0x2c, 0xca, 0xc9, 0x96, 0x28, 0x25, 0xe5, 0x14, 0x6f, - 0xd1, 0xe5, 0x5f, 0x46, 0xf6, 0xbf, 0x6d, 0xda, 0xda, 0xf0, 0x7c, 0xf6, 0xff, 0x01, 0x14, 0xe3, - 0x97, 0x72, 0x8e, 0x65, 0x69, 0x36, 0xfd, 0x3b, 0xb6, 0x3d, 0x1e, 0x4a, 0x4a, 0xec, 0xd2, 0x6e, - 0x93, 0x93, 0x37, 0x29, 0x15, 0xd5, 0x20, 0x1f, 0x78, 0x8e, 0xcf, 0x52, 0xe2, 0x3c, 0xb3, 0x54, - 0xce, 0x97, 0xe1, 0xe3, 0xd4, 0xbc, 0xde, 0x0f, 0x4d, 0x12, 0x9a, 0x81, 0xcf, 0x28, 0xd7, 0xff, - 0x2c, 0x40, 0x86, 0xdd, 0xb4, 0xb3, 0x5b, 0xc0, 0x2c, 0xa4, 0x77, 0x3a, 0xf7, 0x3a, 0xdb, 0x1f, - 0x76, 0xe4, 0x05, 0x94, 0x86, 0x44, 0xb3, 0xd3, 0x93, 0x05, 0x94, 0x81, 0xe4, 0xed, 0xad, 0xed, - 0x6a, 0x4f, 0x5e, 0xa4, 0x8f, 0xb5, 0x87, 0xbd, 0x46, 0x57, 0x4e, 0xa0, 0x0b, 0xb0, 0x54, 0x6f, - 0x6c, 0x35, 0xdb, 0xcd, 0x5e, 0xa3, 0xae, 0xf2, 0x45, 0x09, 0x49, 0x20, 0xf6, 0x9a, 0xed, 0x86, - 0x2c, 0x52, 0xa8, 0x7a, 0x63, 0xb3, 0xd9, 0xae, 0x6e, 0xc9, 0x49, 0xb4, 0x02, 0xcb, 0x11, 0x6f, - 0xb0, 0x9c, 0x41, 0x39, 0x90, 0xea, 0x3b, 0x4a, 0xb5, 0xd7, 0xdc, 0xee, 0xc8, 0x29, 0x04, 0x90, - 0xa2, 0xb2, 0xbd, 0x47, 0x72, 0x8e, 0xea, 0xe9, 0xed, 0xdc, 0xdf, 0x6a, 0xc8, 0x40, 0x99, 0x6a, - 0xcd, 0x5e, 0x55, 0x51, 0xaa, 0x0f, 0xe5, 0x2c, 0x2a, 0x00, 0x50, 0xa6, 0x6e, 0x43, 0x69, 0x36, - 0xba, 0xb2, 0x51, 0xa6, 0xf3, 0x56, 0xfa, 0xfa, 0x8f, 0x61, 0xf9, 0xc4, 0x45, 0x27, 0x5a, 0x82, - 0x6c, 0xb5, 0x5e, 0x57, 0x95, 0xc6, 0xfd, 0xad, 0xe6, 0x66, 0x55, 0x5e, 0x40, 0x08, 0x0a, 0x4a, - 0xa3, 0xbd, 0xfd, 0xa0, 0x11, 0xae, 0x09, 0xab, 0xe2, 0xa7, 0xbf, 0x5d, 0x5b, 0xb8, 0xbe, 0x7d, - 0x6c, 0x6a, 0xe7, 0xed, 0x9e, 0x9e, 0xe0, 0x7e, 0xa3, 0x53, 0x6f, 0x76, 0xee, 0xc8, 0x0b, 0xf4, - 0xa5, 0xdb, 0xab, 0xde, 0xa1, 0x2f, 0x09, 0x94, 0x87, 0xcc, 0xe6, 0x76, 0xbb, 0xdd, 0xec, 0xf5, - 0x1a, 0x75, 0x59, 0xa0, 0xb4, 0x6a, 0x6d, 0x5b, 0xa1, 0x2f, 0x8b, 0x1c, 0xb0, 0xf6, 0x9d, 0x67, - 0xff, 0x58, 0x5b, 0x78, 0x76, 0xb4, 0x26, 0x3c, 0x3f, 0x5a, 0x13, 0x3e, 0x3f, 0x5a, 0x13, 0xfe, - 0x7e, 0xb4, 0x26, 0x7c, 0xf6, 0x62, 0x6d, 0xe1, 0xf9, 0x8b, 0xb5, 0x85, 0xcf, 0x5f, 0xac, 0x2d, - 0x3c, 0x4a, 0xfb, 0xbe, 0xed, 0xa7, 0xd8, 0xbf, 0x81, 0x6e, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, - 0xd3, 0x3a, 0xbf, 0xab, 0xde, 0x1a, 0x00, 0x00, + 0xd7, 0xf7, 0x0f, 0xd6, 0xf7, 0x0f, 0x08, 0x76, 0x0f, 0xb0, 0xbb, 0xae, 0x3b, 0xb6, 0x3e, 0x76, + 0x5d, 0x6c, 0xeb, 0x93, 0xf5, 0xa1, 0xa3, 0xef, 0xb3, 0x1f, 0xd3, 0x1e, 0x70, 0xf1, 0xd5, 0x4b, + 0x01, 0xa4, 0x85, 0x3d, 0x2d, 0x82, 0x5d, 0xbd, 0x42, 0x3c, 0xc7, 0xd5, 0x06, 0x78, 0x1d, 0xdb, + 0x03, 0xd3, 0xc6, 0x94, 0xe1, 0x40, 0xd7, 0x7d, 0xe2, 0xd7, 0x66, 0x12, 0x6f, 0xf8, 0xd4, 0xe2, + 0xd8, 0x33, 0x87, 0xeb, 0x7b, 0x43, 0x7d, 0xdd, 0x33, 0x2d, 0x4c, 0x3c, 0xcd, 0x1a, 0xf9, 0x94, + 0x8b, 0x03, 0x67, 0xe0, 0xb0, 0xc7, 0x75, 0xfa, 0xc4, 0x57, 0xcb, 0x9f, 0x80, 0xd8, 0x1d, 0x69, + 0x36, 0x7a, 0x0b, 0x12, 0xfb, 0x78, 0x52, 0x4c, 0x5c, 0x15, 0xae, 0xe5, 0x6a, 0xe9, 0x97, 0xd3, + 0x52, 0xe2, 0x1e, 0x9e, 0x28, 0x74, 0x0d, 0x5d, 0x85, 0x34, 0xb6, 0x0d, 0x95, 0x92, 0xc5, 0xe3, + 0xe4, 0x14, 0xb6, 0x8d, 0x7b, 0x78, 0x72, 0x33, 0xf7, 0x9b, 0xa7, 0xa5, 0x85, 0x3f, 0x3e, 0x2d, + 0x09, 0xff, 0x7c, 0x5a, 0x12, 0x5a, 0xa2, 0x24, 0xc8, 0x8b, 0x2d, 0x51, 0x5a, 0x94, 0x13, 0x65, + 0x0b, 0x92, 0x0f, 0xb4, 0xe1, 0x18, 0xa3, 0x2b, 0x90, 0x71, 0xb5, 0x27, 0x6a, 0x7f, 0xe2, 0x61, + 0x52, 0x14, 0x28, 0x8c, 0x22, 0xb9, 0xda, 0x93, 0x1a, 0x7d, 0x47, 0x55, 0xc8, 0x84, 0xbb, 0x2d, + 0x2e, 0x5e, 0x15, 0xae, 0x65, 0x37, 0xbe, 0x5e, 0x89, 0x4c, 0x4b, 0x8f, 0x54, 0xd9, 0x1b, 0xea, + 0x95, 0x5e, 0xc0, 0x54, 0x13, 0x9f, 0x4d, 0x4b, 0x0b, 0x4a, 0x24, 0x75, 0x53, 0xa4, 0xaa, 0xcb, + 0x1f, 0x81, 0x74, 0x0f, 0x4f, 0xb8, 0x46, 0xff, 0x44, 0xc2, 0x8c, 0x13, 0xbd, 0x07, 0xc9, 0x03, + 0xca, 0xe3, 0xeb, 0x2a, 0x56, 0x4e, 0xb8, 0xb1, 0xc2, 0x30, 0x7c, 0x35, 0x9c, 0xb9, 0xfc, 0x57, + 0x01, 0xa0, 0xeb, 0x39, 0x2e, 0x6e, 0x1a, 0xd8, 0xf6, 0xd0, 0x00, 0x40, 0x1f, 0x8e, 0x89, 0x87, + 0x5d, 0xd5, 0x34, 0x7c, 0x35, 0x77, 0x29, 0xff, 0xdf, 0xa6, 0xa5, 0x1b, 0x03, 0xd3, 0xdb, 0x1b, + 0xf7, 0x2b, 0xba, 0x63, 0xad, 0x87, 0xd8, 0x46, 0x3f, 0x7a, 0x5e, 0x1f, 0xed, 0x0f, 0xd6, 0x99, + 0xab, 0xc6, 0x63, 0xd3, 0xa8, 0xec, 0xec, 0x34, 0xeb, 0x47, 0xd3, 0x52, 0x66, 0x93, 0x03, 0x36, + 0xeb, 0x4a, 0xc6, 0xc7, 0x6e, 0x1a, 0xe8, 0x5d, 0x48, 0xdb, 0x8e, 0x81, 0xa9, 0x16, 0xba, 0xdf, + 0x64, 0xed, 0xe2, 0xd1, 0xb4, 0x94, 0xea, 0x38, 0x06, 0x6e, 0xd6, 0x5f, 0x86, 0x4f, 0x4a, 0x8a, + 0x32, 0x35, 0x0d, 0xf4, 0x3d, 0x90, 0x68, 0x84, 0x30, 0xfe, 0x04, 0xe3, 0xbf, 0x74, 0x34, 0x2d, + 0xa5, 0xf9, 0xce, 0xa9, 0x40, 0xf0, 0xa8, 0xa4, 0x09, 0x3f, 0x4d, 0xf9, 0x77, 0x02, 0xe4, 0xba, + 0xa3, 0xa1, 0xe9, 0xf5, 0x5c, 0x73, 0x30, 0xc0, 0x2e, 0x6a, 0x40, 0x66, 0x88, 0x77, 0x3d, 0xd5, + 0xc0, 0x44, 0x67, 0x47, 0xcb, 0x6e, 0x94, 0x67, 0x18, 0x49, 0xd1, 0xec, 0x01, 0xae, 0x63, 0xa2, + 0xbb, 0xe6, 0xc8, 0x73, 0x5c, 0xdf, 0x5c, 0x12, 0x15, 0xa5, 0xab, 0xe8, 0x0e, 0x80, 0x6b, 0x0e, + 0xf6, 0x7c, 0x9c, 0xc5, 0x33, 0xe2, 0x64, 0x98, 0x2c, 0x5d, 0xe6, 0xde, 0x6d, 0x89, 0x52, 0x42, + 0x16, 0xcb, 0x5f, 0x2c, 0x42, 0xae, 0x8d, 0xdd, 0x01, 0xfe, 0x8a, 0x6e, 0x16, 0x0d, 0x40, 0xe6, + 0x40, 0x34, 0x2f, 0x55, 0xe2, 0x69, 0x1e, 0x61, 0x89, 0x93, 0xdd, 0xf8, 0x56, 0x0c, 0xce, 0xcf, + 0xe2, 0x4a, 0x90, 0xc5, 0x95, 0xf6, 0x83, 0xcd, 0xcd, 0x2e, 0x65, 0xae, 0x5d, 0xa2, 0x88, 0x47, + 0xd3, 0x52, 0x41, 0xa1, 0x30, 0xe1, 0xba, 0x52, 0x60, 0xb0, 0xed, 0x03, 0x5d, 0x67, 0xef, 0xe8, + 0x36, 0xe4, 0x76, 0x5d, 0x8c, 0x7f, 0x8e, 0xa9, 0x12, 0xd7, 0x2b, 0x26, 0xe7, 0xcf, 0x9c, 0x2c, + 0x17, 0xec, 0x52, 0xb9, 0x63, 0xd6, 0xfd, 0x7d, 0x12, 0x56, 0x36, 0xf7, 0xe8, 0x11, 0x15, 0x3c, + 0x1a, 0x9a, 0xba, 0x46, 0x02, 0x33, 0x3f, 0x82, 0x4b, 0x06, 0x1e, 0xb9, 0x58, 0xd7, 0x3c, 0x6c, + 0xa8, 0x3a, 0xe3, 0x51, 0xbd, 0xc9, 0x08, 0x33, 0x9b, 0x17, 0x36, 0xbe, 0x39, 0xcb, 0x56, 0x1c, + 0x83, 0x03, 0xf6, 0x26, 0x23, 0xac, 0x5c, 0x8c, 0x30, 0xa2, 0x55, 0xf4, 0x10, 0x50, 0x0c, 0xdb, + 0xe5, 0x52, 0xbe, 0x0f, 0x4e, 0xc1, 0x3d, 0xe1, 0x85, 0xe5, 0x08, 0xc5, 0x67, 0x41, 0x3f, 0x83, + 0x2b, 0x31, 0xe8, 0xf1, 0xc8, 0x88, 0xab, 0x20, 0xc5, 0xc4, 0xd5, 0xc4, 0x19, 0x75, 0xbc, 0x15, + 0xc1, 0xed, 0x70, 0xb4, 0xc0, 0x52, 0x08, 0xc3, 0x6a, 0x4c, 0x97, 0x8d, 0x0f, 0xbd, 0x40, 0x11, + 0x4d, 0x46, 0x91, 0x25, 0xe3, 0xb5, 0xa3, 0x69, 0xe9, 0x72, 0x3d, 0xe4, 0xea, 0xe0, 0x43, 0xcf, + 0x97, 0x67, 0xc9, 0x99, 0x09, 0x5f, 0x94, 0xcb, 0xc6, 0x4c, 0x2e, 0x03, 0xbd, 0x0f, 0x22, 0x8b, + 0xd1, 0xe4, 0xbc, 0x31, 0xaa, 0x30, 0x7e, 0xd4, 0x87, 0xcb, 0xa6, 0xed, 0x61, 0xd7, 0xd6, 0x86, + 0xaa, 0x66, 0x18, 0x71, 0x33, 0xa4, 0xce, 0x6c, 0x86, 0x95, 0x00, 0xaa, 0x4a, 0x91, 0x42, 0x13, + 0xec, 0xc2, 0x5b, 0xa1, 0x0e, 0x17, 0x5b, 0xce, 0x41, 0x5c, 0x4b, 0xfa, 0xcc, 0x5a, 0xc2, 0x0d, + 0x2b, 0x1c, 0x2b, 0xd0, 0x73, 0x53, 0xa2, 0x2d, 0x87, 0xd5, 0xfc, 0xcf, 0x04, 0xb8, 0xd0, 0x76, + 0x0c, 0x73, 0xd7, 0xc4, 0x06, 0x6d, 0x65, 0x41, 0xbc, 0x7e, 0x17, 0x10, 0x99, 0x10, 0x0f, 0x5b, + 0xaa, 0xee, 0xd8, 0xbb, 0xe6, 0x40, 0x25, 0x23, 0xcd, 0x66, 0xb1, 0x2a, 0x29, 0x32, 0xa7, 0x6c, + 0x32, 0x02, 0xeb, 0x7f, 0x0d, 0x40, 0xac, 0xc8, 0x0e, 0xcd, 0x03, 0x6c, 0x63, 0x42, 0x38, 0x37, + 0x8f, 0xc0, 0xcb, 0x33, 0x36, 0x4c, 0x85, 0x14, 0x99, 0x8a, 0x6c, 0xf9, 0x12, 0x74, 0xc5, 0x6f, + 0x43, 0x1f, 0x83, 0xdc, 0xf5, 0x4c, 0x7d, 0x7f, 0x52, 0x8b, 0x4a, 0x6a, 0x0d, 0x80, 0xb0, 0x35, + 0xb5, 0x6f, 0x7a, 0x7e, 0x99, 0x9a, 0xaf, 0xc9, 0x91, 0x00, 0xca, 0x47, 0xff, 0x53, 0x02, 0x56, + 0x9a, 0xbe, 0x59, 0x36, 0x1d, 0xcb, 0x8a, 0x74, 0xd4, 0x21, 0x4f, 0x68, 0x19, 0x57, 0x3d, 0xbe, + 0xe0, 0xab, 0x29, 0xcd, 0xdc, 0x7f, 0x54, 0xee, 0x95, 0x1c, 0x89, 0x17, 0xff, 0x3a, 0xe4, 0x2d, + 0x5a, 0x5f, 0x43, 0x94, 0xc5, 0xd7, 0xa2, 0xc4, 0xeb, 0xb0, 0x92, 0xb3, 0xe2, 0x55, 0xf9, 0xa7, + 0x70, 0xd9, 0xaf, 0x11, 0x81, 0xfb, 0x43, 0xbc, 0x04, 0xc3, 0xbb, 0x36, 0x03, 0x6f, 0x66, 0xe5, + 0x51, 0x56, 0xf4, 0xd7, 0x14, 0xa4, 0x15, 0xcb, 0xf7, 0x3b, 0xf3, 0x56, 0x88, 0xcf, 0x8b, 0xed, + 0xb7, 0x67, 0xed, 0xf7, 0x64, 0x9c, 0x28, 0x17, 0xac, 0x19, 0xc1, 0xf3, 0x01, 0xa0, 0xc8, 0x5b, + 0x21, 0x30, 0x4f, 0xb8, 0xb7, 0x67, 0x99, 0xf3, 0x15, 0x77, 0x2b, 0x32, 0x79, 0x65, 0xe5, 0xa6, + 0xf4, 0xa9, 0x3f, 0x20, 0x95, 0x7f, 0x25, 0xc0, 0xf2, 0x76, 0x9f, 0x8d, 0x88, 0x46, 0xe8, 0xed, + 0x78, 0x9b, 0x17, 0xe6, 0x68, 0xf3, 0x6f, 0x60, 0x66, 0x92, 0x82, 0x91, 0xad, 0xfc, 0x97, 0x34, + 0x64, 0x7b, 0xae, 0x66, 0x13, 0x4d, 0xf7, 0x4c, 0xc7, 0x46, 0x55, 0x10, 0xe9, 0x48, 0xea, 0xc7, + 0xcf, 0xdb, 0xa7, 0xb5, 0xad, 0xde, 0xa1, 0xdd, 0xc6, 0x9e, 0x56, 0x93, 0x28, 0xfa, 0xf3, 0x69, + 0x49, 0x50, 0x98, 0x28, 0x42, 0x20, 0xda, 0x9a, 0xc5, 0x47, 0xac, 0x8c, 0xc2, 0x9e, 0xd1, 0x2d, + 0x48, 0xd1, 0x76, 0x38, 0xe6, 0xfd, 0x70, 0x76, 0xcb, 0x88, 0x6d, 0xa3, 0xcb, 0x78, 0x15, 0x5f, + 0x06, 0xb5, 0xa0, 0x30, 0xd4, 0x88, 0xa7, 0xee, 0x61, 0xcd, 0xf5, 0xfa, 0x58, 0x3b, 0x53, 0xc3, + 0xcb, 0x53, 0xd1, 0xbb, 0x81, 0x24, 0x52, 0x21, 0x56, 0xc6, 0x55, 0xc7, 0x35, 0x07, 0x6a, 0x64, + 0xcd, 0xd4, 0xfc, 0xb0, 0xb1, 0x1a, 0xbd, 0xed, 0x9a, 0x83, 0xc8, 0x9b, 0x77, 0x21, 0x6f, 0x69, + 0x87, 0x31, 0xd0, 0xf4, 0xfc, 0xa0, 0x39, 0x4b, 0x3b, 0x8c, 0x90, 0x3e, 0x82, 0x0b, 0x8e, 0x1f, + 0x2c, 0x11, 0x1c, 0x29, 0x4a, 0xaf, 0xad, 0xa5, 0x27, 0x42, 0xcb, 0x87, 0x45, 0xce, 0xab, 0x04, + 0x82, 0x6e, 0x01, 0xd0, 0x4f, 0x12, 0x96, 0x3f, 0xa4, 0x98, 0x65, 0x98, 0xaf, 0x2b, 0x77, 0x41, + 0x00, 0x51, 0x01, 0xfa, 0x4e, 0x50, 0x19, 0xf2, 0x4f, 0x5c, 0xd3, 0xc3, 0xaa, 0xe7, 0x38, 0xaa, + 0x33, 0x34, 0x8a, 0x39, 0x56, 0x5d, 0xb3, 0x6c, 0xb1, 0xe7, 0x38, 0xdb, 0x43, 0x83, 0x7a, 0xcd, + 0xc5, 0x5a, 0x6c, 0xeb, 0xc5, 0xa5, 0x33, 0x78, 0x8d, 0x8a, 0x46, 0xa6, 0x78, 0x0f, 0x2e, 0xe9, + 0xac, 0xe0, 0x45, 0x68, 0xea, 0xae, 0x79, 0x88, 0x8d, 0xa2, 0xcc, 0x14, 0x5f, 0xe4, 0xd4, 0x50, + 0xe0, 0x36, 0xa5, 0xa1, 0x0f, 0x40, 0x36, 0x6d, 0x75, 0x77, 0xc8, 0x66, 0x32, 0xb6, 0x35, 0x52, + 0x5c, 0x66, 0x27, 0xfd, 0xc6, 0xac, 0x93, 0xe2, 0xc7, 0x63, 0x6c, 0xeb, 0xd8, 0xf8, 0x90, 0x72, + 0xfa, 0xfb, 0x28, 0x98, 0xf6, 0x6d, 0x26, 0xcf, 0x16, 0x09, 0x72, 0x60, 0xc9, 0x1c, 0xd8, 0x8e, + 0x4b, 0x2b, 0x0f, 0x7e, 0x6c, 0x8f, 0x2d, 0x52, 0x44, 0x0c, 0xb1, 0x72, 0x5a, 0xaa, 0x34, 0xb9, + 0x48, 0x17, 0x3f, 0xee, 0x8c, 0x2d, 0xd6, 0xa2, 0xa3, 0x51, 0xef, 0x18, 0x8d, 0x28, 0x05, 0x33, + 0x7c, 0xa7, 0xe8, 0x27, 0xbe, 0xb0, 0x12, 0xb2, 0xd8, 0x12, 0xa5, 0x8c, 0x0c, 0x2d, 0x51, 0xca, + 0xcb, 0x85, 0x96, 0x28, 0x15, 0xe4, 0xa5, 0xf2, 0x1f, 0x44, 0x58, 0x8e, 0xe5, 0x8f, 0x82, 0x75, + 0xc7, 0x35, 0xde, 0x44, 0x32, 0x7f, 0x75, 0x12, 0xf7, 0x7c, 0x01, 0xfb, 0xff, 0x10, 0x0a, 0x52, + 0x2c, 0x0c, 0x16, 0xe5, 0x44, 0x18, 0x0c, 0x29, 0x39, 0xdd, 0x12, 0xa5, 0xb4, 0x2c, 0xb5, 0x44, + 0x49, 0x92, 0x33, 0x61, 0x78, 0x80, 0x9c, 0x6d, 0x89, 0x52, 0x4e, 0xce, 0xc7, 0x43, 0xa5, 0x25, + 0x4a, 0x4b, 0xb2, 0xdc, 0x12, 0x25, 0x59, 0x5e, 0x2e, 0xff, 0x4b, 0x80, 0x14, 0x1d, 0x28, 0x6c, + 0x0f, 0x3d, 0x84, 0x25, 0x62, 0xda, 0x83, 0x21, 0xa6, 0x9f, 0xfb, 0xd1, 0xc4, 0x94, 0xdd, 0x78, + 0x67, 0x86, 0x7d, 0xb8, 0x4c, 0xa5, 0xcb, 0x04, 0xee, 0xe1, 0x09, 0xb3, 0x79, 0x14, 0x3a, 0x79, + 0x12, 0x27, 0xa0, 0x1f, 0x41, 0xc2, 0x3b, 0x0c, 0x46, 0xaa, 0xb9, 0xa2, 0x90, 0x1b, 0x9c, 0x4a, + 0xad, 0xd6, 0x20, 0x7f, 0x4c, 0xcd, 0x29, 0xf7, 0x15, 0xe1, 0xe7, 0x4c, 0x78, 0x0b, 0xd1, 0x12, + 0x25, 0x51, 0x4e, 0xfa, 0xd3, 0xd3, 0x2f, 0x12, 0x00, 0x5b, 0x8e, 0xbe, 0xcf, 0x67, 0x77, 0xf4, + 0x7d, 0x10, 0x63, 0xa7, 0x7c, 0x6d, 0x24, 0xc5, 0x12, 0x82, 0x9c, 0xf7, 0x30, 0xb1, 0x6c, 0x4a, + 0x7c, 0x89, 0x6c, 0x9a, 0x11, 0x70, 0xe2, 0xff, 0x32, 0xe0, 0x90, 0x02, 0x60, 0x8c, 0x5d, 0xad, + 0x6f, 0x0e, 0x4d, 0x6f, 0xc2, 0x52, 0xb7, 0xb0, 0xb1, 0x11, 0xd3, 0xb5, 0x7f, 0x50, 0x09, 0x2e, + 0xbc, 0x2a, 0xb1, 0x0b, 0xaf, 0x0a, 0x4d, 0xbb, 0x4a, 0x3d, 0x94, 0x54, 0x62, 0x28, 0xbe, 0x2f, + 0x7e, 0x2d, 0x40, 0xe1, 0x78, 0x92, 0x9d, 0x76, 0x6b, 0xf3, 0x31, 0x48, 0xc4, 0x67, 0xf6, 0x2f, + 0x42, 0x7e, 0xf2, 0x72, 0x5a, 0xba, 0x35, 0xd7, 0x55, 0xcb, 0xab, 0x77, 0x66, 0xd4, 0x2d, 0x5d, + 0xfc, 0x58, 0x09, 0x11, 0x63, 0xc3, 0xd0, 0x7f, 0x12, 0x90, 0xdc, 0xc2, 0x1a, 0xc1, 0xe8, 0x87, + 0x90, 0xe4, 0x5f, 0xd6, 0x67, 0x18, 0xd7, 0xb9, 0x04, 0xfa, 0x04, 0x00, 0x1f, 0x8e, 0x4c, 0x57, + 0xa3, 0x1e, 0x9c, 0x6f, 0x3e, 0x5b, 0xfb, 0xf7, 0xb4, 0xb4, 0x1a, 0x3b, 0xc2, 0xcd, 0xb2, 0xab, + 0xd9, 0x86, 0x3d, 0x1e, 0x0e, 0xb5, 0xfe, 0x10, 0x97, 0x95, 0x18, 0x20, 0xaa, 0x43, 0x3a, 0xf8, + 0x4a, 0x4e, 0x9c, 0xf9, 0x2b, 0x39, 0x10, 0x45, 0x63, 0x88, 0xcd, 0x2f, 0xfc, 0x12, 0x81, 0xfe, + 0x12, 0x33, 0xb8, 0xb0, 0x38, 0xe7, 0x8e, 0x57, 0x22, 0x74, 0x76, 0xd3, 0xd0, 0x65, 0xd8, 0xa8, + 0x03, 0xd9, 0x91, 0xeb, 0x8c, 0x1c, 0x42, 0x27, 0x1a, 0x32, 0x5f, 0x33, 0x28, 0x1c, 0x4d, 0x4b, + 0x70, 0xdf, 0x97, 0xea, 0x75, 0x15, 0x08, 0x10, 0x7a, 0x04, 0x5d, 0x84, 0x24, 0x1e, 0x39, 0xfa, + 0x1e, 0x1b, 0xdc, 0x12, 0x0a, 0x7f, 0x41, 0xef, 0xc6, 0xc2, 0x85, 0x0e, 0x5f, 0x89, 0xda, 0xf2, + 0xcb, 0x69, 0x29, 0xcf, 0x3c, 0x1b, 0x04, 0x5d, 0xdc, 0xff, 0x41, 0x87, 0x2d, 0x7f, 0x21, 0x40, + 0xa1, 0xda, 0x77, 0x5c, 0x8f, 0x66, 0x7e, 0xc3, 0xf6, 0xdc, 0xc9, 0x69, 0x51, 0x79, 0xfe, 0x39, + 0x1c, 0x69, 0x20, 0x8d, 0x5c, 0xd3, 0x71, 0x69, 0x7a, 0xf1, 0x1b, 0xbb, 0xc6, 0xcb, 0x69, 0xa9, + 0xfa, 0xa5, 0x03, 0xfb, 0xbe, 0x0f, 0xa6, 0x84, 0xb0, 0xf1, 0xe8, 0x5e, 0x84, 0xe5, 0x2d, 0xac, + 0xed, 0xf6, 0x0e, 0xed, 0xa6, 0x3d, 0x1a, 0x53, 0x9f, 0x78, 0x18, 0xbd, 0xcf, 0xeb, 0x19, 0x8f, + 0xf3, 0xb5, 0xd3, 0xeb, 0x51, 0xbc, 0x94, 0xbd, 0x03, 0x4b, 0x2e, 0xde, 0x75, 0x31, 0xd9, 0x53, + 0x4d, 0xfb, 0x40, 0x1b, 0x9a, 0x06, 0xb3, 0xb5, 0xa4, 0x14, 0xfc, 0xe5, 0x26, 0x5f, 0x9d, 0xd9, + 0x79, 0xa5, 0xf3, 0x75, 0xde, 0x0d, 0x58, 0x21, 0x1e, 0x1e, 0x8d, 0x4c, 0x7b, 0xa0, 0x5a, 0xf4, + 0xcb, 0x09, 0xdb, 0x34, 0xec, 0x8c, 0x62, 0x86, 0xed, 0xe0, 0x42, 0x40, 0x6c, 0x3b, 0x06, 0x6e, + 0x70, 0x12, 0xea, 0x43, 0x8e, 0x4d, 0xa3, 0x04, 0x3f, 0x56, 0xed, 0xb1, 0x55, 0x84, 0x37, 0x54, + 0x47, 0x80, 0xa2, 0xf2, 0x02, 0xfa, 0x4a, 0x5b, 0x16, 0xe5, 0x64, 0x4b, 0x94, 0x92, 0x72, 0x8a, + 0xb7, 0xe8, 0xf2, 0x2f, 0x23, 0xfb, 0xdf, 0x36, 0x6d, 0x6d, 0x78, 0x3e, 0xfb, 0xff, 0x00, 0x8a, + 0xf1, 0x4b, 0x39, 0xc7, 0xb2, 0x34, 0x9b, 0xfe, 0x1d, 0xdb, 0x1e, 0x0f, 0x25, 0x25, 0x76, 0x69, + 0xb7, 0xc9, 0xc9, 0x9b, 0x94, 0x8a, 0x6a, 0x90, 0x0f, 0x3c, 0xc7, 0x67, 0x29, 0x71, 0x9e, 0x59, + 0x2a, 0xe7, 0xcb, 0xf0, 0x71, 0x6a, 0x5e, 0xef, 0x87, 0x26, 0x09, 0xcd, 0xc0, 0x67, 0x94, 0xeb, + 0x7f, 0x16, 0x20, 0xc3, 0x6e, 0xda, 0xd9, 0x2d, 0x60, 0x16, 0xd2, 0x3b, 0x9d, 0x7b, 0x9d, 0xed, + 0x0f, 0x3b, 0xf2, 0x02, 0x4a, 0x43, 0xa2, 0xd9, 0xe9, 0xc9, 0x02, 0xca, 0x40, 0xf2, 0xf6, 0xd6, + 0x76, 0xb5, 0x27, 0x2f, 0xd2, 0xc7, 0xda, 0xc3, 0x5e, 0xa3, 0x2b, 0x27, 0xd0, 0x05, 0x58, 0xaa, + 0x37, 0xb6, 0x9a, 0xed, 0x66, 0xaf, 0x51, 0x57, 0xf9, 0xa2, 0x84, 0x24, 0x10, 0x7b, 0xcd, 0x76, + 0x43, 0x16, 0x29, 0x54, 0xbd, 0xb1, 0xd9, 0x6c, 0x57, 0xb7, 0xe4, 0x24, 0x5a, 0x81, 0xe5, 0x88, + 0x37, 0x58, 0xce, 0xa0, 0x1c, 0x48, 0xf5, 0x1d, 0xa5, 0xda, 0x6b, 0x6e, 0x77, 0xe4, 0x14, 0x02, + 0x48, 0x51, 0xd9, 0xde, 0x23, 0x39, 0x47, 0xf5, 0xf4, 0x76, 0xee, 0x6f, 0x35, 0x64, 0xa0, 0x4c, + 0xb5, 0x66, 0xaf, 0xaa, 0x28, 0xd5, 0x87, 0x72, 0x16, 0x15, 0x00, 0x28, 0x53, 0xb7, 0xa1, 0x34, + 0x1b, 0x5d, 0xd9, 0x28, 0xd3, 0x79, 0x2b, 0x7d, 0xfd, 0xc7, 0xb0, 0x7c, 0xe2, 0xa2, 0x13, 0x2d, + 0x41, 0xb6, 0x5a, 0xaf, 0xab, 0x4a, 0xe3, 0xfe, 0x56, 0x73, 0xb3, 0x2a, 0x2f, 0x20, 0x04, 0x05, + 0xa5, 0xd1, 0xde, 0x7e, 0xd0, 0x08, 0xd7, 0x84, 0x55, 0xf1, 0xd3, 0xdf, 0xae, 0x2d, 0x5c, 0xdf, + 0x3e, 0x36, 0xb5, 0xf3, 0x76, 0x4f, 0x4f, 0x70, 0xbf, 0xd1, 0xa9, 0x37, 0x3b, 0x77, 0xe4, 0x05, + 0xfa, 0xd2, 0xed, 0x55, 0xef, 0xd0, 0x97, 0x04, 0xca, 0x43, 0x66, 0x73, 0xbb, 0xdd, 0x6e, 0xf6, + 0x7a, 0x8d, 0xba, 0x2c, 0x50, 0x5a, 0xb5, 0xb6, 0xad, 0xd0, 0x97, 0x45, 0x0e, 0x58, 0xfb, 0xce, + 0xb3, 0x7f, 0xac, 0x2d, 0x3c, 0x3b, 0x5a, 0x13, 0x9e, 0x1f, 0xad, 0x09, 0x9f, 0x1f, 0xad, 0x09, + 0x7f, 0x3f, 0x5a, 0x13, 0x3e, 0x7b, 0xb1, 0xb6, 0xf0, 0xfc, 0xc5, 0xda, 0xc2, 0xe7, 0x2f, 0xd6, + 0x16, 0x1e, 0xa5, 0x7d, 0xdf, 0xf6, 0x53, 0xec, 0xdf, 0x40, 0x37, 0xfe, 0x1b, 0x00, 0x00, 0xff, + 0xff, 0xe0, 0xdb, 0x59, 0xc0, 0xde, 0x1a, 0x00, 0x00, } diff --git a/pkg/roachpb/data.proto b/pkg/roachpb/data.proto index 59536d971545..c26a335f4c75 100644 --- a/pkg/roachpb/data.proto +++ b/pkg/roachpb/data.proto @@ -12,8 +12,8 @@ syntax = "proto3"; package cockroach.roachpb; option go_package = "roachpb"; -import "roachpb/metadata.proto"; import "kv/kvserver/concurrency/lock/locking.proto"; +import "roachpb/metadata.proto"; import "storage/enginepb/mvcc.proto"; import "storage/enginepb/mvcc3.proto"; import "util/hlc/timestamp.proto"; diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index 696d43d4ffb3..5b1a92dc93a6 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -359,7 +359,7 @@ func TestMultiRangeScanDeleteRange(t *testing.T) { if _, err := client.SendWrapped(ctx, tds, put); err != nil { t.Fatal(err) } - scan := roachpb.NewScan(writes[0], writes[len(writes)-1].Next()) + scan := roachpb.NewScan(writes[0], writes[len(writes)-1].Next(), false) reply, err := client.SendWrapped(ctx, tds, scan) if err != nil { t.Fatal(err) @@ -398,7 +398,7 @@ func TestMultiRangeScanDeleteRange(t *testing.T) { txnProto := roachpb.MakeTransaction("MyTxn", nil, 0, now, 0) txn := client.NewTxnFromProto(ctx, db, s.NodeID(), now, client.RootTxn, &txnProto) - scan := roachpb.NewScan(writes[0], writes[len(writes)-1].Next()) + scan := roachpb.NewScan(writes[0], writes[len(writes)-1].Next(), false) ba := roachpb.BatchRequest{} ba.Header = roachpb.Header{Txn: &txnProto} ba.Add(scan) @@ -458,7 +458,8 @@ func TestMultiRangeScanWithPagination(t *testing.T) { // happens above this. var maxTargetBytes int64 { - resp, pErr := client.SendWrapped(ctx, tds, roachpb.NewScan(tc.keys[0], tc.keys[len(tc.keys)-1].Next())) + scan := roachpb.NewScan(tc.keys[0], tc.keys[len(tc.keys)-1].Next(), false) + resp, pErr := client.SendWrapped(ctx, tds, scan) require.Nil(t, pErr) maxTargetBytes = resp.Header().NumBytes } @@ -478,9 +479,9 @@ func TestMultiRangeScanWithPagination(t *testing.T) { t.Run(fmt.Sprintf("targetBytes=%d,maxSpanRequestKeys=%d", targetBytes, msrq), func(t *testing.T) { req := func(span roachpb.Span) roachpb.Request { if reverse { - return roachpb.NewReverseScan(span.Key, span.EndKey) + return roachpb.NewReverseScan(span.Key, span.EndKey, false) } - return roachpb.NewScan(span.Key, span.EndKey) + return roachpb.NewScan(span.Key, span.EndKey, false) } // Paginate. resumeSpan := &roachpb.Span{Key: tc.keys[0], EndKey: tc.keys[len(tc.keys)-1].Next()} diff --git a/pkg/sql/logictest/testdata/logic_test/fk b/pkg/sql/logictest/testdata/logic_test/fk index ce87b491c23e..b91f10d6c8de 100644 --- a/pkg/sql/logictest/testdata/logic_test/fk +++ b/pkg/sql/logictest/testdata/logic_test/fk @@ -2628,7 +2628,7 @@ statement ok CREATE TABLE fam_parent ( k INT PRIMARY KEY, a INT, - b INT, + b INT NOT NULL, FAMILY (k, a), FAMILY (b) ) @@ -2657,7 +2657,9 @@ user testuser # Run an INSERT which needs to check existence of the row. If we try to scan # the entire row, this blocks on the other transaction. We should only be -# scanning the primary column family. +# scanning the primary column family. A critical reason why this works is +# because column b is NOT NULL, so the UPDATE statement does not acquire +# FOR UPDATE locks on the primary column family. statement ok INSERT INTO fam_child VALUES (1, 1) diff --git a/pkg/sql/logictest/testdata/logic_test/fk_opt b/pkg/sql/logictest/testdata/logic_test/fk_opt index 1529d69a80a0..b520c3b9525c 100644 --- a/pkg/sql/logictest/testdata/logic_test/fk_opt +++ b/pkg/sql/logictest/testdata/logic_test/fk_opt @@ -2988,7 +2988,7 @@ statement ok CREATE TABLE fam_parent ( k INT PRIMARY KEY, a INT, - b INT, + b INT NOT NULL, FAMILY (k, a), FAMILY (b) ) @@ -3017,7 +3017,9 @@ user testuser # Run an INSERT which needs to check existence of the row. If we try to scan # the entire row, this blocks on the other transaction. We should only be -# scanning the primary column family. +# scanning the primary column family. A critical reason why this works is +# because column b is NOT NULL, so the UPDATE statement does not acquire +# FOR UPDATE locks on the primary column family. statement ok INSERT INTO fam_child VALUES (1, 1) diff --git a/pkg/sql/row/kv_batch_fetcher.go b/pkg/sql/row/kv_batch_fetcher.go index 6348e0fa3c4f..4b5ab8bc9790 100644 --- a/pkg/sql/row/kv_batch_fetcher.go +++ b/pkg/sql/row/kv_batch_fetcher.go @@ -13,8 +13,10 @@ package row import ( "bytes" "context" + "fmt" "github.com/cockroachdb/cockroach/pkg/internal/client" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency/lock" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" "github.com/cockroachdb/cockroach/pkg/util" @@ -134,6 +136,34 @@ func (f *txnKVFetcher) getBatchSizeForIdx(batchIdx int) int64 { } } +// getKeyLockingStrength returns the configured per-key locking strength to use +// for key-value scans. +func (f *txnKVFetcher) getKeyLockingStrength() lock.Strength { + switch f.lockStr { + case sqlbase.ScanLockingStrength_FOR_NONE: + return lock.None + + case sqlbase.ScanLockingStrength_FOR_KEY_SHARE: + // Promote to FOR_SHARE. + fallthrough + case sqlbase.ScanLockingStrength_FOR_SHARE: + // We currently perform no per-key locking when FOR_SHARE is used + // because Shared locks have not yet been implemented. + return lock.None + + case sqlbase.ScanLockingStrength_FOR_NO_KEY_UPDATE: + // Promote to FOR_UPDATE. + fallthrough + case sqlbase.ScanLockingStrength_FOR_UPDATE: + // We currently perform exclusive per-key locking when FOR_UPDATE is + // used because Upgrade locks have not yet been implemented. + return lock.Exclusive + + default: + panic(fmt.Sprintf("unknown locking strength %s", f.lockStr)) + } +} + // makeKVBatchFetcher initializes a kvBatchFetcher for the given spans. // // If useBatchLimit is true, batches are limited to kvBatchSize. If @@ -243,20 +273,21 @@ func (f *txnKVFetcher) fetch(ctx context.Context) error { } ba.Header.ReturnRangeInfo = f.returnRangeInfo ba.Requests = make([]roachpb.RequestUnion, len(f.spans)) + keyLocking := f.getKeyLockingStrength() if f.reverse { scans := make([]roachpb.ReverseScanRequest, len(f.spans)) for i := range f.spans { - scans[i].ScanFormat = roachpb.BATCH_RESPONSE scans[i].SetSpan(f.spans[i]) - // TODO(nvanbenschoten): use f.lockStr here. + scans[i].ScanFormat = roachpb.BATCH_RESPONSE + scans[i].KeyLocking = keyLocking ba.Requests[i].MustSetInner(&scans[i]) } } else { scans := make([]roachpb.ScanRequest, len(f.spans)) for i := range f.spans { - scans[i].ScanFormat = roachpb.BATCH_RESPONSE scans[i].SetSpan(f.spans[i]) - // TODO(nvanbenschoten): use f.lockStr here. + scans[i].ScanFormat = roachpb.BATCH_RESPONSE + scans[i].KeyLocking = keyLocking ba.Requests[i].MustSetInner(&scans[i]) } } diff --git a/pkg/storage/mvcc.go b/pkg/storage/mvcc.go index 62069203588e..a3da214c2aec 100644 --- a/pkg/storage/mvcc.go +++ b/pkg/storage/mvcc.go @@ -2651,9 +2651,7 @@ func MVCCResolveWriteIntentUsingIter( if len(intent.EndKey) > 0 { return false, errors.Errorf("can't resolve range intent as point intent") } - return mvccResolveWriteIntent( - ctx, rw, iterAndBuf.iter, ms, intent, iterAndBuf.buf, false, /* forRange */ - ) + return mvccResolveWriteIntent(ctx, rw, iterAndBuf.iter, ms, intent, iterAndBuf.buf) } // unsafeNextVersion positions the iterator at the successor to latestKey. If this value @@ -2675,9 +2673,6 @@ func unsafeNextVersion(iter Iterator, latestKey MVCCKey) (MVCCKey, []byte, bool, } // mvccResolveWriteIntent is the core logic for resolving an intent. -// The forRange parameter specifies whether the intent is part of a -// range of write intents. In this case, checks which make sense only -// in the context of resolving a specific point intent are skipped. // Returns whether an intent was found and resolved, false otherwise. func mvccResolveWriteIntent( ctx context.Context, @@ -2686,7 +2681,6 @@ func mvccResolveWriteIntent( ms *enginepb.MVCCStats, intent roachpb.LockUpdate, buf *putBuffer, - forRange bool, ) (bool, error) { metaKey := MakeMVCCMetadataKey(intent.Key) meta := &buf.meta @@ -2694,60 +2688,7 @@ func mvccResolveWriteIntent( if err != nil { return false, err } - // For cases where there's no value corresponding to the key we're - // resolving, and this is a committed transaction, log a warning if - // the intent txn is epoch=0. For non-zero epoch transactions, this - // is a common occurrence for intents written only be earlier epochs - // which were resolved by concurrent actors, and does not benefit - // from a warning. See #9399 for details. - expVal := intent.Status == roachpb.COMMITTED && intent.Txn.Epoch == 0 - if !ok { - if expVal { - log.Warningf(ctx, "unable to find value for %s (%+v)", - intent.Key, intent.Txn) - } - return false, nil - } - if meta.Txn == nil || intent.Txn.ID != meta.Txn.ID { - // For the ranged case, this key isn't within our remit. Bail early. - if forRange { - return false, nil - } - if expVal { - // The intent is being committed. Verify that it was already committed by - // looking for a value at the transaction timestamp. Note that this check - // has false positives due to MVCC GC, but such false positives should be - // very rare. - // - // Note that we hit this code path relatively frequently when doing end - // transaction processing for locally resolved intents. In those cases, - // meta.Txn == nil but the subsequent call to mvccGetInternal will avoid - // any additional seeks because the iterator is already positioned - // correctly. - gbuf := newGetBuffer() - defer gbuf.release() - gbuf.meta = buf.meta - - v, _, _, err := mvccGetInternal(ctx, iter, metaKey, - intent.Txn.WriteTimestamp, false, unsafeValue, nil, gbuf) - if err != nil { - log.Warningf(ctx, "unable to find value for %s @ %s: %v ", - intent.Key, intent.Txn.WriteTimestamp, err) - } else if v == nil { - // This can happen if the committed value was already GCed. - log.Warningf(ctx, "unable to find value for %s @ %s (%+v vs %+v)", - intent.Key, intent.Txn.WriteTimestamp, meta, intent.Txn) - } else if v.Timestamp != intent.Txn.WriteTimestamp { - // This should never happen. If we find a value when seeking - // to the intent's commit timestamp then that value should - // always have the correct timestamp. Finding a value without - // a matching timestamp rules out the possibility that our - // committed value was already GCed, because we now found a - // version with an even lower timestamp. - log.Warningf(ctx, "unable to find value for %s @ %s: %s (txn=%+v)", - intent.Key, intent.Txn.WriteTimestamp, v.Timestamp, intent.Txn) - } - } + if !ok || meta.Txn == nil || intent.Txn.ID != meta.Txn.ID { return false, nil } @@ -3130,9 +3071,7 @@ func MVCCResolveWriteIntentRangeUsingIter( var ok bool if !key.IsValue() { intent.Key = key.Key - ok, err = mvccResolveWriteIntent( - ctx, rw, iterAndBuf.iter, ms, intent, iterAndBuf.buf, true, /* forRange */ - ) + ok, err = mvccResolveWriteIntent(ctx, rw, iterAndBuf.iter, ms, intent, iterAndBuf.buf) } if err != nil { log.Warningf(ctx, "failed to resolve intent for key %q: %+v", key.Key, err)