Full Code of pingcap/talent-plan for AI

master 18d81c90e403 cached
195 files
1.6 MB
674.3k tokens
869 symbols
1 requests
Download .txt
Showing preview only (1,706K chars total). Download the full file or copy to clipboard to get everything.
Repository: pingcap/talent-plan
Branch: master
Commit: 18d81c90e403
Files: 195
Total size: 1.6 MB

Directory structure:
gitextract_2klmrfgy/

├── .circleci/
│   └── config.yml
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.md
│   │   ├── feature-requirement.md
│   │   └── question.md
│   └── pull_request_template.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── README.md
├── courses/
│   ├── README.md
│   ├── dss/
│   │   ├── .gitignore
│   │   ├── Cargo.toml
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── labcodec/
│   │   │   ├── Cargo.toml
│   │   │   ├── build.rs
│   │   │   ├── demonstration/
│   │   │   │   ├── README.md
│   │   │   │   └── expanded_fixture.rs
│   │   │   ├── proto/
│   │   │   │   └── fixture.proto
│   │   │   └── src/
│   │   │       └── lib.rs
│   │   ├── labrpc/
│   │   │   ├── Cargo.toml
│   │   │   ├── benches/
│   │   │   │   └── rpc.rs
│   │   │   ├── examples/
│   │   │   │   └── echo.rs
│   │   │   └── src/
│   │   │       ├── client.rs
│   │   │       ├── error.rs
│   │   │       ├── lib.rs
│   │   │       ├── macros.rs
│   │   │       ├── network.rs
│   │   │       └── server.rs
│   │   ├── linearizability/
│   │   │   ├── Cargo.toml
│   │   │   ├── src/
│   │   │   │   ├── bitset.rs
│   │   │   │   ├── lib.rs
│   │   │   │   ├── model.rs
│   │   │   │   └── models.rs
│   │   │   └── test_data/
│   │   │       ├── c01-bad.txt
│   │   │       ├── c01-ok.txt
│   │   │       ├── c10-bad.txt
│   │   │       ├── c10-ok.txt
│   │   │       ├── c50-bad.txt
│   │   │       └── c50-ok.txt
│   │   ├── percolator/
│   │   │   ├── Cargo.toml
│   │   │   ├── README.md
│   │   │   ├── build.rs
│   │   │   ├── proto/
│   │   │   │   └── msg.proto
│   │   │   └── src/
│   │   │       ├── client.rs
│   │   │       ├── lib.rs
│   │   │       ├── server.rs
│   │   │       ├── service.rs
│   │   │       └── tests.rs
│   │   └── raft/
│   │       ├── Cargo.toml
│   │       ├── README.md
│   │       ├── build.rs
│   │       └── src/
│   │           ├── kvraft/
│   │           │   ├── client.rs
│   │           │   ├── config.rs
│   │           │   ├── errors.rs
│   │           │   ├── mod.rs
│   │           │   ├── server.rs
│   │           │   └── tests.rs
│   │           ├── lib.rs
│   │           ├── proto/
│   │           │   ├── kvraft.proto
│   │           │   ├── mod.rs
│   │           │   └── raft.proto
│   │           └── raft/
│   │               ├── config.rs
│   │               ├── errors.rs
│   │               ├── mod.rs
│   │               ├── persister.rs
│   │               └── tests.rs
│   ├── rust/
│   │   ├── .gitignore
│   │   ├── CONTRIBUTING.md
│   │   ├── README.md
│   │   ├── building-blocks/
│   │   │   ├── bb-1.md
│   │   │   ├── bb-2.md
│   │   │   ├── bb-3.md
│   │   │   ├── bb-4.md
│   │   │   └── bb-5.md
│   │   ├── docs/
│   │   │   ├── etc/
│   │   │   │   ├── notes.md
│   │   │   │   └── parallel-diagrams.txt
│   │   │   ├── lesson-plan.md
│   │   │   ├── prerequisites.md
│   │   │   ├── roadmap.md
│   │   │   └── what-next.md
│   │   └── projects/
│   │       ├── project-1/
│   │       │   ├── Cargo.toml
│   │       │   ├── README.md
│   │       │   ├── src/
│   │       │   │   ├── bin/
│   │       │   │   │   └── kvs.rs
│   │       │   │   ├── kv.rs
│   │       │   │   └── lib.rs
│   │       │   └── tests/
│   │       │       └── tests.rs
│   │       ├── project-2/
│   │       │   ├── Cargo.toml
│   │       │   ├── README.md
│   │       │   ├── src/
│   │       │   │   ├── bin/
│   │       │   │   │   └── kvs.rs
│   │       │   │   ├── error.rs
│   │       │   │   ├── kv.rs
│   │       │   │   └── lib.rs
│   │       │   └── tests/
│   │       │       └── tests.rs
│   │       ├── project-3/
│   │       │   ├── Cargo.toml
│   │       │   ├── README.md
│   │       │   ├── benches/
│   │       │   │   └── engine_bench.rs
│   │       │   ├── src/
│   │       │   │   ├── bin/
│   │       │   │   │   ├── kvs-client.rs
│   │       │   │   │   └── kvs-server.rs
│   │       │   │   ├── client.rs
│   │       │   │   ├── common.rs
│   │       │   │   ├── engines/
│   │       │   │   │   ├── kvs.rs
│   │       │   │   │   ├── mod.rs
│   │       │   │   │   └── sled.rs
│   │       │   │   ├── error.rs
│   │       │   │   ├── lib.rs
│   │       │   │   └── server.rs
│   │       │   └── tests/
│   │       │       ├── cli.rs
│   │       │       └── kv_store.rs
│   │       ├── project-4/
│   │       │   ├── Cargo.toml
│   │       │   ├── README.md
│   │       │   ├── src/
│   │       │   │   ├── bin/
│   │       │   │   │   ├── kvs-client.rs
│   │       │   │   │   └── kvs-server.rs
│   │       │   │   ├── client.rs
│   │       │   │   ├── common.rs
│   │       │   │   ├── engines/
│   │       │   │   │   ├── kvs.rs
│   │       │   │   │   ├── mod.rs
│   │       │   │   │   └── sled.rs
│   │       │   │   ├── error.rs
│   │       │   │   ├── lib.rs
│   │       │   │   ├── server.rs
│   │       │   │   └── thread_pool/
│   │       │   │       ├── mod.rs
│   │       │   │       ├── naive.rs
│   │       │   │       ├── rayon.rs
│   │       │   │       └── shared_queue.rs
│   │       │   └── tests/
│   │       │       ├── cli.rs
│   │       │       ├── kv_store.rs
│   │       │       └── thread_pool.rs
│   │       └── project-5/
│   │           ├── Cargo.toml
│   │           ├── README.md
│   │           ├── src/
│   │           │   ├── bin/
│   │           │   │   ├── kvs-client.rs
│   │           │   │   └── kvs-server.rs
│   │           │   ├── client.rs
│   │           │   ├── common.rs
│   │           │   ├── engines/
│   │           │   │   ├── kvs.rs
│   │           │   │   ├── mod.rs
│   │           │   │   └── sled.rs
│   │           │   ├── error.rs
│   │           │   ├── lib.rs
│   │           │   ├── server.rs
│   │           │   └── thread_pool/
│   │           │       ├── mod.rs
│   │           │       ├── naive.rs
│   │           │       ├── rayon.rs
│   │           │       └── shared_queue.rs
│   │           └── tests/
│   │               ├── cli.rs
│   │               ├── kv_store.rs
│   │               └── thread_pool.rs
│   ├── tp101-intro-to-oss.md
│   ├── tp102-how-to-use-git-github.md
│   └── tp103-open-source-community.md
├── talent-challenge-program/
│   ├── MENTEE_APPLY_TEMPLATE.md
│   ├── PROJECT_IDEA_TEMPLATE.md
│   ├── README.md
│   ├── project-ideas.md
│   ├── s1.md
│   └── selected-projects.md
├── talent-challenge-program2021/
│   ├── MENTEE_APPLY_TEMPLATE.md
│   ├── PROJECT_IDEA_TEMPLATE.md
│   ├── README.md
│   ├── project-ideas.md
│   ├── schedule.md
│   └── selected-projects.md
├── talent-plan-1.0/
│   ├── 1.0-lp-tidb.md
│   ├── 1.0-lp-tikv.md
│   └── README-CN.md
└── tidb/
    ├── .gitignore
    ├── README.md
    ├── join/
    │   ├── Makefile
    │   ├── README.md
    │   ├── benchmark_test.go
    │   ├── go.mod
    │   ├── go.sum
    │   ├── join.go
    │   ├── join_example.go
    │   ├── join_test.go
    │   └── t/
    │       ├── r0.tbl
    │       ├── r1.tbl
    │       └── r2.tbl
    ├── mapreduce/
    │   ├── .gitignore
    │   ├── Makefile
    │   ├── README.md
    │   ├── casegen.go
    │   ├── go.mod
    │   ├── go.sum
    │   ├── mapreduce.go
    │   ├── urltop10.go
    │   ├── urltop10_example.go
    │   ├── urltop10_test.go
    │   └── utils.go
    └── mergesort/
        ├── Makefile
        ├── README.md
        ├── bench_test.go
        ├── go.mod
        ├── go.sum
        ├── mergesort.go
        └── mergesort_test.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .circleci/config.yml
================================================
version: 2.1
jobs:
  dss:
    docker:
      - image: circleci/rust:stretch
    environment:
      RUST_BACKTRACE: "1"
      RUSTFLAGS: "-Dwarnings"
    working_directory: ~/talent-plan/courses/dss
    steps:
      - checkout:
          path: ~/talent-plan
      - run: rustup component add clippy-preview rustfmt-preview
      - run: cargo fmt --all -- --check
      - run: cargo clippy --all --tests -- -D clippy::all
      - run: cargo test -p labcodec -p labrpc
      - run: cargo test -p raft -- --test raft::persister
      - run:
          command: cargo test -p linearizability
          no_output_timeout: 30m

workflows:
  version: 2
  ci-test:
    jobs:
      - dss


================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.md
================================================
---
name: "\U0001F41B Bug Report"
about: something isn't working as expected
labels: type/bug
---

## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. What did you do? <!-- provide a recipe for reproducing -->

### 2. What did you expect to see?

### 3. What did you see instead?


================================================
FILE: .github/ISSUE_TEMPLATE/feature-requirement.md
================================================
---
name: "\U0001F680 Feature Request"
about: I have a suggestion!
labels: type/enhancement
---

## Feature Request

please make a clear and concise description for the following questions.

### Is your feature request related to a problem?
<!-- what the problem is -->

### Describe the feature you'd like
<!-- what you want to happen. -->

### Describe alternatives you've considered


================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: "\U0001F914 Question"
about: I have a question!
labels: type/question
---

## General Question

## Tips

Expect for asking questions on Github, you can also discuss it in the channel
**#wg-talent-plan-courses**. of
[tidbcommunity](https://join.slack.com/t/tidbcommunity/shared_invite/enQtNzc0MzI4ODExMDc4LWYwYmIzMjZkYzJiNDUxMmZlN2FiMGJkZjAyMzQ5NGU0NGY0NzI3NTYwMjAyNGQ1N2I2ZjAxNzc1OGUwYWM0NzE)
slack workspace.


================================================
FILE: .github/pull_request_template.md
================================================
<!-- Thank you for contributing to talent-plan!

PR Title Format:
1. pkg [, pkg2, pkg3]: what's changed
2. *: what's changed

-->

### What problem does this PR solve?

- Issue number: close #xxx <!-- remove this line if no issue to close -->
- Breif description of the problem:

### What is changed and how it works?

### Check List <!--REMOVE the items that are not applicable-->

Tests <!-- At least one of them must be included. -->

 - Unit test
 - Integration test
 - Manual test (add detailed scripts or steps below)
 - No code

Side effects

 - Possible performance regression
 - Increased code complexity

Related changes

 - Need to update the documentation


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
 advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
 address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
 professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [ts-team@pingcap.com](mailto:ts-team@pingcap.com). All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing Guide

Thanks for taking the time to contribute to Talent Plan! Contributions of any kind are welcome.

## Ways to contribute

We love contributions from the community. Here are just a few of the ways you can contribute:

- **Report bugs:** if you find a bug while taking courses, you may want to do a quick check of past issues to see if you can find any help there. Otherwise, create a new bug issue in the course repository using the provided template.
- **Answer questions:** check out the open issues to see if you can help answer learner questions.
- **Suggest changes:** this could come in the form of a new learning outcome, updates to the content, updates to the bot responses, or the logic of the course. If you'd like, you can fork the course and suggest the change that way, but most people like to talk about it first in an issue.
- **Tackle an issue:** if you see an issue you would like to resolve, please feel free to fork the course and submit a PR (check out the instructions below).
- **Translate a course:** if you have the ability to translate a course, we'd love to see it. Please fork the course and submit a PR. We'll need a second native speaker to confirm the translation so if you have anyone in mind, please @ mention them in your PR for a review.


## How to Contribute

1. Check out which [contributions](#ways-to-contribute) above you are willing to make
1. Fork this repository.
2. Commit your changes to your branch
3. Open a pull request to upstream
4. Request a review from the reviewers

Want to konw more about how to use Git & GitHub to make contributions? Click [how to use Git & GitHub](courses/tp102-how-to-use-git-github.md) courses for more help


================================================
FILE: README.md
================================================
# Welcome to learn Talent Plan Courses!

![Talent Plan Logo](media/talent-plan-logo.png)

Talent Plan is an open source training program initiated by PingCAP. It aims to create or combine some open source learning materials for people interested in open source, distributed systems, Rust, Golang, and other infrastructure knowledge. As such, it provides a series of courses focused on open source collaboration, rust programming, distributed database and systems.

> Note:

> Each course is developed by different teams, so they may vary in their organization and learning outcomes. Please see the individual course documentation for details.

## Our Courses

### Series 1: Open Source Collaboration

Open source collaboration includes a series of open-source related learning materials to help  enthusiasts gain basic knowledge of what open source software is, the differences between existing open-source software licenses, how to participate in open source projects, and what a welcoming open source community looks like. 

Courses include:

- [TP 101: Introduction to open source software](courses/tp101-intro-to-oss.md)
- [TP 102: How to use Git and GitHub](courses/tp102-how-to-use-git-github.md)
- [TP 103: Build a welcoming community](courses/tp103-open-source-community.md)

### Series 2: Rust Programming

This series is core to TALENT-PLAN. It builds your understanding of Rust as a programming language and provides opportunities for you to practice with it.

Courses include:

- [TP 201: Practical Networked Applications in Rust](courses/rust/README.md). A series of projects that incrementally develop a single Rust project from the ground up into a high-performance, networked, parallel and asynchronous key/value store. Along the way various real-world Rust development subject matter are explored and discussed.

- [TP 202: Distributed Systems in Rust](courses/dss/README.md). Adapted from the [MIT 6.824](http://nil.csail.mit.edu/6.824/2017/index.html) distributed systems coursework, this course focuses on implementing important distributed algorithms, including the [Raft](https://raft.github.io/) consensus algorithm, and the [Percolator](https://storage.googleapis.com/pub-tools-public-publication-data/pdf/36726.pdf) distributed transaction protocol.

### Series 3: Distributed Database 

This series provides information on TinySQL and TinyKV, which are distributed databases in Go.

Courses include:

- [TP 301: TinySQL, a distributed relational database in Go](https://github.com/pingcap-incubator/tinysql)
- [TP 302: TinyKV, a distributed key value database in Go](https://github.com/pingcap-incubator/tinykv) 

### Series 4: Deep Dive into TiDB Ecosystems 

This series provides information on TiDB and TiKV, which are distributed databases developed by PingCAP.

Courses include:

- TP 401: Deep Dive into TiDB(WIP)
- TP 402: Deep Dive into TiKV(WIP)


See [Courses](courses/README.md) for more details.

# Contributing to talent plan

Contributions of any kind are welcome! Check out the [Contributing Guide](CONTRIBUTING.md) in this repository for more information on how you can contribute to Talent Plan. 

We love our community and take great care to ensure it is fun, safe and rewarding. Please review our [Code of Conduct](/CODE_OF_CONDUCT.md) for community expectations and guidelines for reporting concerns.


## We're here to help

If you have questions about building (or taking) courses, you can ask in the channel **#wg-talent-plan-courses** of the [tidbcommunity](https://tidbcommunity.slack.com/join/shared_invite/enQtNzc0MzI4ODExMDc4LWYwYmIzMjZkYzJiNDUxMmZlN2FiMGJkZjAyMzQ5NGU0NGY0NzI3NTYwMjAyNGQ1N2I2ZjAxNzc1OGUwYWM0NzE#/shared-invite/email) slack workspace.

## License

These courses may be freely used and modified for any purpose, under the terms of each course's individual license. See the courses for details.


================================================
FILE: courses/README.md
================================================
# All public courses

Here we list all public courses of Talent Plan, including:

- [TP 101: Introduction to open source software](tp101-intro-to-oss.md)
- [TP 102: How to use Git and GitHub](tp102-how-to-use-git-github.md)
- [TP 103: Build a welcoming community](tp103-open-source-community.md)
- [TP 201: Practical Networked Applications in Rust](rust/README.md)
- [TP 202: Distributed Systems in Rust](dss/README.md)
- [TP 301: TinySQL, a distributed relational database in Go](https://github.com/pingcap-incubator/tinysql)
- [TP 302: TinyKV, a distributed key value database in Go](https://github.com/pingcap-incubator/tinykv) 
- TP 401: Deep Dive into TiDB(WIP)
- TP 402: Deep Dive into TiKV(WIP)


================================================
FILE: courses/dss/.gitignore
================================================
**/target
**/*.rs.bk
6.824-golabs-2018


================================================
FILE: courses/dss/Cargo.toml
================================================
[workspace]
members = [
    "labcodec",
    "labrpc",
    "linearizability",
    "raft",
    "percolator"
]


================================================
FILE: courses/dss/Makefile
================================================
export RUSTFLAGS=-Dwarnings
export RUST_TEST_THREADS=1
export RUST_BACKTRACE=1

LOG_LEVEL ?= raft=info,percolator=info

check:
	cargo fmt --all -- --check
	cargo clippy --all --tests -- -D clippy::all

test: test_others test_2 test_3

test_2: test_2a test_2b test_2c test_2d

test_2a: cargo_test_2a

test_2b: cargo_test_2b

test_2c: cargo_test_2c

test_2d: cargo_test_2d

test_3: test_3a test_3b

test_3a: cargo_test_3a

test_3b: cargo_test_3b

cargo_test_%: check
	RUST_LOG=${LOG_LEVEL} cargo test -p raft -- --nocapture --test $*

test_others: check
	RUST_LOG=${LOG_LEVEL} cargo test -p labrpc -p labcodec -- --nocapture

test_percolator: check
	RUST_LOG=${LOG_LEVEL} cargo test -p percolator -- --nocapture


================================================
FILE: courses/dss/README.md
================================================
# Distributed Systems in Rust

A training course about the distributed systems in [Rust].

Subjects covered include:

- [Raft consensus algorithm] (including a fault-tolerant key-value storage service
using Raft)
- [Percolator transaction model]

After completing this course you will have the knowledge to implement a basic
key-value storage service with transaction and fault-tolerant in Rust.

**Important note: Distributed Systems in Rust is in an alpha state**
It might contain bugs. Any feedback is greatly appreciated. Please [file issues]
if you have any problem. And also You are encouraged to fix problems on your own
and submit pull requests.

## The goal of this course

The goal of this course is to teach the Rust programmers who are interested in
distributed systems to know about how to make the distributed systems reliable
and how to implement the distributed transaction.

## Who is this for?

Distributed Systems in Rust is for experienced _Rust_ programmers, who are
familiar with the Rust language. If you are not, you can first learn our [rust]
lessons.

## A PingCAP-specific note

This course, combined with [Deep Dive TiKV], is intended to be enough to enable
programmers to meaningfully contribute to [TiKV]. It is most specifically
designed to teach those in the Chinese Rust community enough Rust to work on
TiKV. The language used is intended to be simple so that those who read only a
little English can follow. If you find any of the language difficult to
understand please [file issues].

## License

[CC-BY 4.0](https://opendefinition.org/licenses/cc-by/)

<!-- links -->
[rust]: ../rust/README.md
[file issues]: https://github.com/pingcap/talent-plan/issues/
[Deep Dive TiKV]: https://tikv.github.io/deep-dive-tikv/overview/introduction.html
[TiKV]: https://github.com/tikv/tikv/
[Rust]: https://www.rust-lang.org/
[Raft consensus algorithm]: raft/README.md
[Percolator transaction model]: percolator/README.md


================================================
FILE: courses/dss/labcodec/Cargo.toml
================================================
[package]
name = "labcodec"
version = "0.1.0"
build = "build.rs"
edition = "2018"
publish = false

[dependencies]
prost = "0.6"

[build-dependencies]
prost-build = "0.6"


================================================
FILE: courses/dss/labcodec/build.rs
================================================
fn main() {
    prost_build::compile_protos(&["proto/fixture.proto"], &["proto"]).unwrap();
    println!("cargo:rerun-if-changed=proto");
}


================================================
FILE: courses/dss/labcodec/demonstration/README.md
================================================
# Demonstration

Expanded version of generated rust files. Files in the folder are for the sake
of understanding how procedural macro works, and they are not compilable.


================================================
FILE: courses/dss/labcodec/demonstration/expanded_fixture.rs
================================================
/// A simple protobuf message.
pub struct Msg {
    #[prost(enumeration = "msg::Type", tag = "1")]
    pub r#type: i32,
    #[prost(uint64, tag = "2")]
    pub id: u64,
    #[prost(string, tag = "3")]
    pub name: std::string::String,
    #[prost(bytes, repeated, tag = "4")]
    pub paylad: ::std::vec::Vec<std::vec::Vec<u8>>,
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Msg {
    #[inline]
    fn clone(&self) -> Msg {
        match *self {
            Msg {
                r#type: ref __self_0_0,
                id: ref __self_0_1,
                name: ref __self_0_2,
                paylad: ref __self_0_3,
            } => Msg {
                r#type: ::core::clone::Clone::clone(&(*__self_0_0)),
                id: ::core::clone::Clone::clone(&(*__self_0_1)),
                name: ::core::clone::Clone::clone(&(*__self_0_2)),
                paylad: ::core::clone::Clone::clone(&(*__self_0_3)),
            },
        }
    }
}
impl ::core::marker::StructuralPartialEq for Msg {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Msg {
    #[inline]
    fn eq(&self, other: &Msg) -> bool {
        match *other {
            Msg {
                r#type: ref __self_1_0,
                id: ref __self_1_1,
                name: ref __self_1_2,
                paylad: ref __self_1_3,
            } => match *self {
                Msg {
                    r#type: ref __self_0_0,
                    id: ref __self_0_1,
                    name: ref __self_0_2,
                    paylad: ref __self_0_3,
                } => {
                    (*__self_0_0) == (*__self_1_0)
                        && (*__self_0_1) == (*__self_1_1)
                        && (*__self_0_2) == (*__self_1_2)
                        && (*__self_0_3) == (*__self_1_3)
                }
            },
        }
    }
    #[inline]
    fn ne(&self, other: &Msg) -> bool {
        match *other {
            Msg {
                r#type: ref __self_1_0,
                id: ref __self_1_1,
                name: ref __self_1_2,
                paylad: ref __self_1_3,
            } => match *self {
                Msg {
                    r#type: ref __self_0_0,
                    id: ref __self_0_1,
                    name: ref __self_0_2,
                    paylad: ref __self_0_3,
                } => {
                    (*__self_0_0) != (*__self_1_0)
                        || (*__self_0_1) != (*__self_1_1)
                        || (*__self_0_2) != (*__self_1_2)
                        || (*__self_0_3) != (*__self_1_3)
                }
            },
        }
    }
}
impl ::prost::Message for Msg {
    #[allow(unused_variables)]
    fn encode_raw<B>(&self, buf: &mut B)
    where
        B: ::prost::bytes::BufMut,
    {
        if self.r#type != msg::Type::default() as i32 {
            ::prost::encoding::int32::encode(1u32, &self.r#type, buf);
        }
        if self.id != 0u64 {
            ::prost::encoding::uint64::encode(2u32, &self.id, buf);
        }
        if self.name != "" {
            ::prost::encoding::string::encode(3u32, &self.name, buf);
        }
        ::prost::encoding::bytes::encode_repeated(4u32, &self.paylad, buf);
    }
    #[allow(unused_variables)]
    fn merge_field<B>(
        &mut self,
        tag: u32,
        wire_type: ::prost::encoding::WireType,
        buf: &mut B,
        ctx: ::prost::encoding::DecodeContext,
    ) -> ::std::result::Result<(), ::prost::DecodeError>
    where
        B: ::prost::bytes::Buf,
    {
        const STRUCT_NAME: &'static str = "Msg";
        match tag {
            1u32 => {
                let mut value = &mut self.r#type;
                ::prost::encoding::int32::merge(wire_type, value, buf, ctx).map_err(|mut error| {
                    error.push(STRUCT_NAME, "r#type");
                    error
                })
            }
            2u32 => {
                let mut value = &mut self.id;
                ::prost::encoding::uint64::merge(wire_type, value, buf, ctx).map_err(|mut error| {
                    error.push(STRUCT_NAME, "id");
                    error
                })
            }
            3u32 => {
                let mut value = &mut self.name;
                ::prost::encoding::string::merge(wire_type, value, buf, ctx).map_err(|mut error| {
                    error.push(STRUCT_NAME, "name");
                    error
                })
            }
            4u32 => {
                let mut value = &mut self.paylad;
                ::prost::encoding::bytes::merge_repeated(wire_type, value, buf, ctx).map_err(
                    |mut error| {
                        error.push(STRUCT_NAME, "paylad");
                        error
                    },
                )
            }
            _ => ::prost::encoding::skip_field(wire_type, tag, buf, ctx),
        }
    }
    #[inline]
    fn encoded_len(&self) -> usize {
        0 + if self.r#type != msg::Type::default() as i32 {
            ::prost::encoding::int32::encoded_len(1u32, &self.r#type)
        } else {
            0
        } + if self.id != 0u64 {
            ::prost::encoding::uint64::encoded_len(2u32, &self.id)
        } else {
            0
        } + if self.name != "" {
            ::prost::encoding::string::encoded_len(3u32, &self.name)
        } else {
            0
        } + ::prost::encoding::bytes::encoded_len_repeated(4u32, &self.paylad)
    }
    fn clear(&mut self) {
        self.r#type = msg::Type::default() as i32;
        self.id = 0u64;
        self.name.clear();
        self.paylad.clear();
    }
}
impl Default for Msg {
    fn default() -> Msg {
        Msg {
            r#type: msg::Type::default() as i32,
            id: 0u64,
            name: ::std::string::String::new(),
            paylad: ::std::vec::Vec::new(),
        }
    }
}
impl ::std::fmt::Debug for Msg {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        let mut builder = f.debug_struct("Msg");
        let builder = {
            let wrapper = {
                struct ScalarWrapper<'a>(&'a i32);
                impl<'a> ::std::fmt::Debug for ScalarWrapper<'a> {
                    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                        match msg::Type::from_i32(*self.0) {
                            None => ::std::fmt::Debug::fmt(&self.0, f),
                            Some(en) => ::std::fmt::Debug::fmt(&en, f),
                        }
                    }
                }
                ScalarWrapper(&self.r#type)
            };
            builder.field("r#type", &wrapper)
        };
        let builder = {
            let wrapper = {
                fn ScalarWrapper<T>(v: T) -> T {
                    v
                }
                ScalarWrapper(&self.id)
            };
            builder.field("id", &wrapper)
        };
        let builder = {
            let wrapper = {
                fn ScalarWrapper<T>(v: T) -> T {
                    v
                }
                ScalarWrapper(&self.name)
            };
            builder.field("name", &wrapper)
        };
        let builder = {
            let wrapper = {
                struct ScalarWrapper<'a>(&'a ::std::vec::Vec<::std::vec::Vec<u8>>);
                impl<'a> ::std::fmt::Debug for ScalarWrapper<'a> {
                    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                        let mut vec_builder = f.debug_list();
                        for v in self.0 {
                            fn Inner<T>(v: T) -> T {
                                v
                            }
                            vec_builder.entry(&Inner(v));
                        }
                        vec_builder.finish()
                    }
                }
                ScalarWrapper(&self.paylad)
            };
            builder.field("paylad", &wrapper)
        };
        builder.finish()
    }
}
#[allow(dead_code)]
impl Msg {
    ///Returns the enum value of `type`, or the default if the field is set to an invalid enum value.
    pub fn r#type(&self) -> msg::Type {
        msg::Type::from_i32(self.r#type).unwrap_or(msg::Type::default())
    }
    ///Sets `type` to the provided enum value.
    pub fn set_type(&mut self, value: msg::Type) {
        self.r#type = value as i32;
    }
}
pub mod msg {
    #[repr(i32)]
    pub enum Type {
        Unknown = 0,
        Put = 1,
        Get = 2,
        Del = 3,
    }
    #[automatically_derived]
    #[allow(unused_qualifications)]
    impl ::core::clone::Clone for Type {
        #[inline]
        fn clone(&self) -> Type {
            {
                *self
            }
        }
    }
    #[automatically_derived]
    #[allow(unused_qualifications)]
    impl ::core::marker::Copy for Type {}
    #[automatically_derived]
    #[allow(unused_qualifications)]
    impl ::core::fmt::Debug for Type {
        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
            match (&*self,) {
                (&Type::Unknown,) => {
                    let mut debug_trait_builder = f.debug_tuple("Unknown");
                    debug_trait_builder.finish()
                }
                (&Type::Put,) => {
                    let mut debug_trait_builder = f.debug_tuple("Put");
                    debug_trait_builder.finish()
                }
                (&Type::Get,) => {
                    let mut debug_trait_builder = f.debug_tuple("Get");
                    debug_trait_builder.finish()
                }
                (&Type::Del,) => {
                    let mut debug_trait_builder = f.debug_tuple("Del");
                    debug_trait_builder.finish()
                }
            }
        }
    }
    impl ::core::marker::StructuralPartialEq for Type {}
    #[automatically_derived]
    #[allow(unused_qualifications)]
    impl ::core::cmp::PartialEq for Type {
        #[inline]
        fn eq(&self, other: &Type) -> bool {
            {
                let __self_vi = unsafe { ::core::intrinsics::discriminant_value(&*self) } as i32;
                let __arg_1_vi = unsafe { ::core::intrinsics::discriminant_value(&*other) } as i32;
                if true && __self_vi == __arg_1_vi {
                    match (&*self, &*other) {
                        _ => true,
                    }
                } else {
                    false
                }
            }
        }
    }
    impl ::core::marker::StructuralEq for Type {}
    #[automatically_derived]
    #[allow(unused_qualifications)]
    impl ::core::cmp::Eq for Type {
        #[inline]
        #[doc(hidden)]
        fn assert_receiver_is_total_eq(&self) -> () {
            {}
        }
    }
    #[automatically_derived]
    #[allow(unused_qualifications)]
    impl ::core::hash::Hash for Type {
        fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
            match (&*self,) {
                _ => ::core::hash::Hash::hash(
                    &unsafe { ::core::intrinsics::discriminant_value(self) },
                    state,
                ),
            }
        }
    }
    #[automatically_derived]
    #[allow(unused_qualifications)]
    impl ::core::cmp::PartialOrd for Type {
        #[inline]
        fn partial_cmp(&self, other: &Type) -> ::core::option::Option<::core::cmp::Ordering> {
            {
                let __self_vi = unsafe { ::core::intrinsics::discriminant_value(&*self) } as i32;
                let __arg_1_vi = unsafe { ::core::intrinsics::discriminant_value(&*other) } as i32;
                if true && __self_vi == __arg_1_vi {
                    match (&*self, &*other) {
                        _ => ::core::option::Option::Some(::core::cmp::Ordering::Equal),
                    }
                } else {
                    __self_vi.partial_cmp(&__arg_1_vi)
                }
            }
        }
    }
    #[automatically_derived]
    #[allow(unused_qualifications)]
    impl ::core::cmp::Ord for Type {
        #[inline]
        fn cmp(&self, other: &Type) -> ::core::cmp::Ordering {
            {
                let __self_vi = unsafe { ::core::intrinsics::discriminant_value(&*self) } as i32;
                let __arg_1_vi = unsafe { ::core::intrinsics::discriminant_value(&*other) } as i32;
                if true && __self_vi == __arg_1_vi {
                    match (&*self, &*other) {
                        _ => ::core::cmp::Ordering::Equal,
                    }
                } else {
                    __self_vi.cmp(&__arg_1_vi)
                }
            }
        }
    }
    impl Type {
        ///Returns `true` if `value` is a variant of `Type`.
        pub fn is_valid(value: i32) -> bool {
            match value {
                0 => true,
                1 => true,
                2 => true,
                3 => true,
                _ => false,
            }
        }
        ///Converts an `i32` to a `Type`, or `None` if `value` is not a valid variant.
        pub fn from_i32(value: i32) -> ::std::option::Option<Type> {
            match value {
                0 => ::std::option::Option::Some(Type::Unknown),
                1 => ::std::option::Option::Some(Type::Put),
                2 => ::std::option::Option::Some(Type::Get),
                3 => ::std::option::Option::Some(Type::Del),
                _ => ::std::option::Option::None,
            }
        }
    }
    impl ::std::default::Default for Type {
        fn default() -> Type {
            Type::Unknown
        }
    }
    impl ::std::convert::From<Type> for i32 {
        fn from(value: Type) -> i32 {
            value as i32
        }
    }
}


================================================
FILE: courses/dss/labcodec/proto/fixture.proto
================================================
syntax = "proto3";

package fixture;

// A simple protobuf message.
message Msg {
    enum Type {
        UNKNOWN = 0;
        PUT = 1;
        GET = 2;
        DEL = 3;
    }

    Type type = 1;
    uint64 id = 2;
    string name = 3;
    repeated bytes paylad = 4;
}


================================================
FILE: courses/dss/labcodec/src/lib.rs
================================================
//! A thin wrapper of [prost](https://docs.rs/prost/0.6.1/prost/)

/// A labcodec message.
pub trait Message: prost::Message + Default {}
impl<T: prost::Message + Default> Message for T {}

/// A message encoding error.
pub type EncodeError = prost::EncodeError;
/// A message decoding error.
pub type DecodeError = prost::DecodeError;

/// Encodes the message to a `Vec<u8>`.
pub fn encode<M: Message>(message: &M, buf: &mut Vec<u8>) -> Result<(), EncodeError> {
    buf.reserve(message.encoded_len());
    message.encode(buf)?;
    Ok(())
}

/// Decodes an message from the buffer.
pub fn decode<M: Message>(buf: &[u8]) -> Result<M, DecodeError> {
    M::decode(buf)
}

#[cfg(test)]
mod tests {
    mod fixture {
        // The generated rust file:
        // labs6824/target/debug/build/labcodec-hashhashhashhash/out/fixture.rs
        //
        // It looks like:
        //
        // ```no_run
        // /// A simple protobuf message.
        // #[derive(Clone, PartialEq, Message)]
        // pub struct Msg {
        //     #[prost(enumeration="msg::Type", tag="1")]
        //     pub type_: i32,
        //     #[prost(uint64, tag="2")]
        //     pub id: u64,
        //     #[prost(string, tag="3")]
        //     pub name: String,
        //     #[prost(bytes, repeated, tag="4")]
        //     pub paylad: ::std::vec::Vec<Vec<u8>>,
        // }
        // pub mod msg {
        //     #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
        //     pub enum Type {
        //         Unknown = 0,
        //         Put = 1,
        //         Get = 2,
        //         Del = 3,
        //     }
        // }
        // ```
        include!(concat!(env!("OUT_DIR"), "/fixture.rs"));
    }

    use super::{decode, encode};

    #[test]
    fn test_basic_encode_decode() {
        let msg = fixture::Msg {
            r#type: fixture::msg::Type::Put as _,
            id: 42,
            name: "the answer".to_owned(),
            paylad: vec![vec![7; 3]; 2],
        };
        let mut buf = vec![];
        encode(&msg, &mut buf).unwrap();
        let msg1 = decode(&buf).unwrap();
        assert_eq!(msg, msg1);
    }

    #[test]
    fn test_default() {
        let msg = fixture::Msg::default();
        let msg1 = decode(&[]).unwrap();
        assert_eq!(msg, msg1);
    }
}


================================================
FILE: courses/dss/labrpc/Cargo.toml
================================================
[package]
name = "labrpc"
version = "0.1.0"
edition = "2018"
publish = false

[dependencies]
async-trait = "0.1"
futures = { version = "0.3", features = ["thread-pool"] }
futures-timer = "3.0"
log = "0.4"
prost = "0.6"
rand = "0.7"

labcodec = { path = "../labcodec" }

[dev-dependencies]
criterion = "0.3"
env_logger = "0.7"
prost-derive = "0.6"

[[bench]]
name = "rpc"
path = "benches/rpc.rs"
harness = false


================================================
FILE: courses/dss/labrpc/benches/rpc.rs
================================================
use std::sync::{Arc, Mutex};

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use futures::executor::block_on;
use prost_derive::Message;

use labrpc::{service, Network, Result, Server, ServerBuilder};

service! {
    /// A simple bench-purpose service.
    service bench {
        /// Doc comments.
        rpc handler(BenchArgs) returns (BenchReply);
    }
}
use bench::{add_service, Client as BenchClient, Service};

// Hand-written protobuf messages.
#[derive(Clone, PartialEq, Message)]
pub struct BenchArgs {
    #[prost(int64, tag = "1")]
    pub x: i64,
}

#[derive(Clone, PartialEq, Message)]
pub struct BenchReply {
    #[prost(string, tag = "1")]
    pub x: String,
}

#[derive(Default)]
struct BenchInner {
    log2: Vec<i64>,
}
#[derive(Clone)]
pub struct BenchService {
    inner: Arc<Mutex<BenchInner>>,
}
impl BenchService {
    fn new() -> BenchService {
        BenchService {
            inner: Arc::default(),
        }
    }
}

#[async_trait::async_trait]
impl Service for BenchService {
    async fn handler(&self, args: BenchArgs) -> Result<BenchReply> {
        self.inner.lock().unwrap().log2.push(args.x);
        Ok(BenchReply {
            x: format!("handler-{}", args.x),
        })
    }
}

fn bench_suit() -> (Network, Server, BenchService) {
    let net = Network::new();
    let server_name = "test_server".to_owned();
    let mut builder = ServerBuilder::new(server_name);
    let bench_server = BenchService::new();
    add_service(bench_server.clone(), &mut builder).unwrap();
    let server = builder.build();
    net.add_server(server.clone());
    (net, server, bench_server)
}

fn bench_rpc(c: &mut Criterion) {
    let (net, server, _bench_server) = bench_suit();
    let server_name = server.name();
    let client_name = "client";
    let client = BenchClient::new(net.create_client(client_name.to_owned()));
    net.connect(client_name, server_name);
    net.enable(client_name, true);

    c.bench_function("rpc", |b| {
        b.iter(|| {
            black_box(block_on(async {
                client.handler(&BenchArgs { x: 111 }).await.unwrap()
            }));
        })
        // i7-8650U, 13 microseconds per RPC
    });
}

criterion_group!(benches, bench_rpc);
criterion_main!(benches);


================================================
FILE: courses/dss/labrpc/examples/echo.rs
================================================
use futures::executor::block_on;
use prost_derive::Message;

use labrpc::*;

/// A Hand-written protobuf messages
#[derive(Clone, PartialEq, Message)]
pub struct Echo {
    #[prost(int64, tag = "1")]
    pub x: i64,
}

service! {
    service echo {
        rpc ping(Echo) returns (Echo);
    }
}
use echo::{add_service, Client, Service};

#[derive(Clone)]
struct EchoService;

#[async_trait::async_trait]
impl Service for EchoService {
    async fn ping(&self, input: Echo) -> Result<Echo> {
        Ok(input)
    }
}

fn main() {
    let rn = Network::new();
    let server_name = "echo_server";
    let mut builder = ServerBuilder::new(server_name.to_owned());
    add_service(EchoService, &mut builder).unwrap();
    let server = builder.build();
    rn.add_server(server);

    let client_name = "client";
    let client = Client::new(rn.create_client(client_name.to_owned()));
    rn.enable(client_name, true);
    rn.connect(client_name, server_name);

    let reply = block_on(async { client.ping(&Echo { x: 777 }).await.unwrap() });
    assert_eq!(reply, Echo { x: 777 });
    println!("{:?}", reply);
}


================================================
FILE: courses/dss/labrpc/src/client.rs
================================================
use std::fmt;
use std::sync::{Arc, Mutex};

use futures::channel::mpsc::UnboundedSender;
use futures::channel::oneshot;
use futures::executor::ThreadPool;
use futures::future::{self, FutureExt};

use crate::error::{Error, Result};
use crate::server::RpcFuture;

pub struct Rpc {
    pub(crate) client_name: String,
    pub(crate) fq_name: &'static str,
    pub(crate) req: Option<Vec<u8>>,
    pub(crate) resp: Option<oneshot::Sender<Result<Vec<u8>>>>,
    pub(crate) hooks: Arc<Mutex<Option<Arc<dyn RpcHooks>>>>,
}

impl Rpc {
    pub(crate) fn take_resp_sender(&mut self) -> Option<oneshot::Sender<Result<Vec<u8>>>> {
        self.resp.take()
    }
}

impl fmt::Debug for Rpc {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Rpc")
            .field("client_name", &self.client_name)
            .field("fq_name", &self.fq_name)
            .finish()
    }
}

pub trait RpcHooks: Sync + Send + 'static {
    fn before_dispatch(&self, fq_name: &str, req: &[u8]) -> Result<()>;
    fn after_dispatch(&self, fq_name: &str, resp: Result<Vec<u8>>) -> Result<Vec<u8>>;
}

#[derive(Clone)]
pub struct Client {
    // this end-point's name
    pub(crate) name: String,
    // copy of Network.sender
    pub(crate) sender: UnboundedSender<Rpc>,
    pub(crate) hooks: Arc<Mutex<Option<Arc<dyn RpcHooks>>>>,

    pub worker: ThreadPool,
}

impl Client {
    pub fn call<Req, Rsp>(&self, fq_name: &'static str, req: &Req) -> RpcFuture<Result<Rsp>>
    where
        Req: labcodec::Message,
        Rsp: labcodec::Message + 'static,
    {
        let mut buf = vec![];
        if let Err(e) = labcodec::encode(req, &mut buf) {
            return Box::pin(future::err(Error::Encode(e)));
        }

        let (tx, rx) = oneshot::channel();
        let rpc = Rpc {
            client_name: self.name.clone(),
            fq_name,
            req: Some(buf),
            resp: Some(tx),
            hooks: self.hooks.clone(),
        };

        // Sends requests and waits responses.
        if self.sender.unbounded_send(rpc).is_err() {
            return Box::pin(future::err(Error::Stopped));
        }

        Box::pin(rx.then(|res| async move {
            match res {
                Ok(Ok(resp)) => labcodec::decode(&resp).map_err(Error::Decode),
                Ok(Err(e)) => Err(e),
                Err(e) => Err(Error::Recv(e)),
            }
        }))
    }

    pub fn set_hooks(&self, hooks: Arc<dyn RpcHooks>) {
        *self.hooks.lock().unwrap() = Some(hooks);
    }

    pub fn clear_hooks(&self) {
        *self.hooks.lock().unwrap() = None;
    }
}


================================================
FILE: courses/dss/labrpc/src/error.rs
================================================
use std::{error, fmt, result};

use futures::channel::oneshot::Canceled;

use labcodec::{DecodeError, EncodeError};

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Error {
    Unimplemented(String),
    Encode(EncodeError),
    Decode(DecodeError),
    Recv(Canceled),
    Timeout,
    Stopped,
    Other(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl error::Error for Error {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match *self {
            Error::Encode(ref e) => Some(e),
            Error::Decode(ref e) => Some(e),
            Error::Recv(ref e) => Some(e),
            _ => None,
        }
    }
}

pub type Result<T> = result::Result<T, Error>;


================================================
FILE: courses/dss/labrpc/src/lib.rs
================================================
#![allow(clippy::new_without_default)]

mod client;
mod error;
#[macro_use]
mod macros;
mod network;
mod server;

pub use self::client::{Client, Rpc, RpcHooks};
pub use self::error::{Error, Result};
pub use self::network::Network;
pub use self::server::{Handler, HandlerFactory, RpcFuture, Server, ServerBuilder};

#[cfg(test)]
pub mod tests {
    use std::sync::atomic::{AtomicBool, Ordering};
    use std::sync::{mpsc, Arc, Mutex, Once};
    use std::thread;
    use std::time::{Duration, Instant};

    use futures::channel::oneshot::Canceled;
    use futures::executor::{block_on, ThreadPool};
    use futures::stream::StreamExt;
    use futures_timer::Delay;
    use prost_derive::Message;

    use super::*;

    service! {
        /// A simple test-purpose service.
        service junk {
            /// Doc comments.
            rpc handler2(JunkArgs) returns (JunkReply);
            rpc handler3(JunkArgs) returns (JunkReply);
            rpc handler4(JunkArgs) returns (JunkReply);
        }
    }
    use junk::{add_service, Client as JunkClient, Service as Junk};

    // Hand-written protobuf messages.
    #[derive(Clone, PartialEq, Message)]
    pub struct JunkArgs {
        #[prost(int64, tag = "1")]
        pub x: i64,
    }
    #[derive(Clone, PartialEq, Message)]
    pub struct JunkReply {
        #[prost(string, tag = "1")]
        pub x: String,
    }

    #[derive(Default)]
    struct JunkInner {
        log2: Vec<i64>,
    }
    #[derive(Clone)]
    struct JunkService {
        inner: Arc<Mutex<JunkInner>>,
    }
    impl JunkService {
        fn new() -> JunkService {
            JunkService {
                inner: Arc::default(),
            }
        }
    }
    #[async_trait::async_trait]
    impl Junk for JunkService {
        async fn handler2(&self, args: JunkArgs) -> Result<JunkReply> {
            self.inner.lock().unwrap().log2.push(args.x);
            Ok(JunkReply {
                x: format!("handler2-{}", args.x),
            })
        }
        async fn handler3(&self, args: JunkArgs) -> Result<JunkReply> {
            Delay::new(Duration::from_secs(20)).await;
            Ok(JunkReply {
                x: format!("handler3-{}", -args.x),
            })
        }
        async fn handler4(&self, _: JunkArgs) -> Result<JunkReply> {
            Ok(JunkReply {
                x: "pointer".to_owned(),
            })
        }
    }

    fn init_logger() {
        static LOGGER_INIT: Once = Once::new();
        LOGGER_INIT.call_once(env_logger::init);
    }

    #[test]
    fn test_service_dispatch() {
        init_logger();

        let mut builder = ServerBuilder::new("test".to_owned());
        let junk = JunkService::new();
        add_service(junk.clone(), &mut builder).unwrap();
        let prev_len = builder.services.len();
        add_service(junk, &mut builder).unwrap_err();
        assert_eq!(builder.services.len(), prev_len);
        let server = builder.build();

        let buf = block_on(async { server.dispatch("junk.handler4", &[]).await.unwrap() });
        let rsp = labcodec::decode(&buf).unwrap();
        assert_eq!(
            JunkReply {
                x: "pointer".to_owned(),
            },
            rsp,
        );

        block_on(async {
            server
                .dispatch("junk.handler4", b"bad message")
                .await
                .unwrap_err();

            server.dispatch("badjunk.handler4", &[]).await.unwrap_err();

            server.dispatch("junk.badhandler", &[]).await.unwrap_err();
        });
    }

    #[test]
    fn test_network_client_rpc() {
        init_logger();

        let mut builder = ServerBuilder::new("test".to_owned());
        let junk = JunkService::new();
        add_service(junk, &mut builder).unwrap();
        let server = builder.build();

        let (net, incoming) = Network::create();
        net.add_server(server);

        let client = JunkClient::new(net.create_client("test_client".to_owned()));
        let (tx, rx) = mpsc::channel();
        let cli = client.clone();
        client.spawn(async move {
            let reply = cli.handler4(&JunkArgs { x: 777 }).await;
            tx.send(reply).unwrap();
        });
        let (mut rpc, incoming) = block_on(async {
            match incoming.into_future().await {
                (Some(rpc), s) => (rpc, s),
                _ => panic!("unexpected error"),
            }
        });
        let reply = JunkReply {
            x: "boom!!!".to_owned(),
        };
        let mut buf = vec![];
        labcodec::encode(&reply, &mut buf).unwrap();
        let resp = rpc.take_resp_sender().unwrap();
        resp.send(Ok(buf)).unwrap();
        assert_eq!(rpc.client_name, "test_client");
        assert_eq!(rpc.fq_name, "junk.handler4");
        assert!(!rpc.req.as_ref().unwrap().is_empty());
        assert_eq!(rx.recv().unwrap(), Ok(reply));

        let (tx, rx) = mpsc::channel();
        let cli = client.clone();
        client.spawn(async move {
            let reply = cli.handler4(&JunkArgs { x: 777 }).await;
            tx.send(reply).unwrap();
        });
        let (rpc, incoming) = block_on(async {
            match incoming.into_future().await {
                (Some(rpc), s) => (rpc, s),
                _ => panic!("unexpected error"),
            }
        });
        drop(rpc.resp);
        assert_eq!(rx.recv().unwrap(), Err(Error::Recv(Canceled)));

        drop(incoming);
        assert_eq!(
            block_on(async { client.handler4(&JunkArgs::default()).await }),
            Err(Error::Stopped)
        );
    }

    fn junk_suit() -> (Network, Server, JunkService) {
        let net = Network::new();
        let server_name = "test_server".to_owned();
        let mut builder = ServerBuilder::new(server_name);
        let junk_server = JunkService::new();
        add_service(junk_server.clone(), &mut builder).unwrap();
        let server = builder.build();
        net.add_server(server.clone());
        (net, server, junk_server)
    }

    #[test]
    fn test_basic() {
        init_logger();

        let (net, _, _) = junk_suit();

        let client = JunkClient::new(net.create_client("test_client".to_owned()));
        net.connect("test_client", "test_server");
        net.enable("test_client", true);

        let rsp = block_on(async { client.handler4(&JunkArgs::default()).await.unwrap() });
        assert_eq!(
            JunkReply {
                x: "pointer".to_owned(),
            },
            rsp,
        );
    }

    // does net.Enable(endname, false) really disconnect a client?
    #[test]
    fn test_disconnect() {
        init_logger();

        let (net, _, _) = junk_suit();

        let client = JunkClient::new(net.create_client("test_client".to_owned()));
        net.connect("test_client", "test_server");

        block_on(async { client.handler4(&JunkArgs::default()).await.unwrap_err() });

        net.enable("test_client", true);
        let rsp = block_on(async { client.handler4(&JunkArgs::default()).await.unwrap() });

        assert_eq!(
            JunkReply {
                x: "pointer".to_owned(),
            },
            rsp,
        );
    }

    // test net.GetCount()
    #[test]
    fn test_count() {
        init_logger();

        let (net, _, _) = junk_suit();

        let client = JunkClient::new(net.create_client("test_client".to_owned()));
        net.connect("test_client", "test_server");
        net.enable("test_client", true);

        for i in 0..=16 {
            let reply = block_on(async { client.handler2(&JunkArgs { x: i }).await.unwrap() });
            assert_eq!(reply.x, format!("handler2-{}", i));
        }

        assert_eq!(net.count("test_server"), 17);
    }

    // test RPCs from concurrent Clients
    #[test]
    fn test_concurrent_many() {
        init_logger();

        let (net, server, _) = junk_suit();
        let server_name = server.name();

        let pool = ThreadPool::new().unwrap();
        let (tx, rx) = mpsc::channel::<usize>();

        let nclients = 20usize;
        let nrpcs = 10usize;
        for i in 0..nclients {
            let net = net.clone();
            let sender = tx.clone();
            let server_name = server_name.to_string();

            pool.spawn_ok(async move {
                let mut n = 0;
                let client_name = format!("client-{}", i);
                let client = JunkClient::new(net.create_client(client_name.clone()));
                net.enable(&client_name, true);
                net.connect(&client_name, &server_name);

                for j in 0..nrpcs {
                    let x = (i * 100 + j) as i64;
                    let reply = client.handler2(&JunkArgs { x }).await.unwrap();
                    assert_eq!(reply.x, format!("handler2-{}", x));
                    n += 1;
                }

                sender.send(n).unwrap();
            });
        }

        let mut total = 0;
        for _ in 0..nclients {
            total += rx.recv().unwrap();
        }
        assert_eq!(total, nrpcs * nclients);
        let n = net.count(server_name);
        assert_eq!(n, total);
    }

    #[test]
    fn test_unreliable() {
        init_logger();

        let (net, server, _) = junk_suit();
        let server_name = server.name();
        net.set_reliable(false);

        let pool = ThreadPool::new().unwrap();
        let (tx, rx) = mpsc::channel::<usize>();
        let nclients = 300;
        for i in 0..nclients {
            let sender = tx.clone();
            let mut n = 0;
            let server_name = server_name.to_owned();
            let net = net.clone();

            pool.spawn_ok(async move {
                let client_name = format!("client-{}", i);
                let client = JunkClient::new(net.create_client(client_name.clone()));
                net.enable(&client_name, true);
                net.connect(&client_name, &server_name);

                let x = i * 100;
                if let Ok(reply) = client.handler2(&JunkArgs { x }).await {
                    assert_eq!(reply.x, format!("handler2-{}", x));
                    n += 1;
                }
                sender.send(n).unwrap();
            });
        }
        let mut total = 0;
        for _ in 0..nclients {
            total += rx.recv().unwrap();
        }
        assert!(
            !(total == nclients as _ || total == 0),
            "all RPCs succeeded despite unreliable total {}, nclients {}",
            total,
            nclients
        );
    }

    // test concurrent RPCs from a single Client
    #[test]
    fn test_concurrent_one() {
        init_logger();

        let (net, server, junk_server) = junk_suit();
        let server_name = server.name();

        let pool = ThreadPool::new().unwrap();
        let (tx, rx) = mpsc::channel::<usize>();
        let nrpcs = 20;
        for i in 0..20 {
            let sender = tx.clone();
            let client_name = format!("client-{}", i);
            let client = JunkClient::new(net.create_client(client_name.clone()));
            net.enable(&client_name, true);
            net.connect(&client_name, server_name);

            pool.spawn_ok(async move {
                let mut n = 0;
                let x = i + 100;
                let reply = client.handler2(&JunkArgs { x }).await.unwrap();
                assert_eq!(reply.x, format!("handler2-{}", x));
                n += 1;
                sender.send(n).unwrap()
            });
        }

        let mut total = 0;
        for _ in 0..nrpcs {
            total += rx.recv().unwrap();
        }
        assert_eq!(
            total, nrpcs,
            "wrong number of RPCs completed, got {}, expected {}",
            total, nrpcs
        );

        assert_eq!(
            junk_server.inner.lock().unwrap().log2.len(),
            nrpcs,
            "wrong number of RPCs delivered"
        );

        let n = net.count(server.name());
        assert_eq!(n, total, "wrong count() {}, expected {}", n, total);
    }

    // regression: an RPC that's delayed during Enabled=false
    // should not delay subsequent RPCs (e.g. after Enabled=true).
    #[test]
    fn test_regression1() {
        init_logger();

        let (net, server, junk_server) = junk_suit();
        let server_name = server.name();

        let client_name = "client";
        let client = JunkClient::new(net.create_client(client_name.to_owned()));
        net.connect(client_name, server_name);

        // start some RPCs while the Client is disabled.
        // they'll be delayed.
        net.enable(client_name, false);

        let pool = ThreadPool::new().unwrap();
        let (tx, rx) = mpsc::channel::<bool>();
        let nrpcs = 20;
        for i in 0..20 {
            let sender = tx.clone();
            let cli = client.clone();
            pool.spawn_ok(async move {
                let x = i + 100;
                // this call ought to return false.
                let _ = cli.handler2(&JunkArgs { x });
                sender.send(true).unwrap();
            });
        }

        // FIXME: have to sleep 300ms to pass the test
        //        in my computer (i5-4200U, 4 threads).
        thread::sleep(Duration::from_millis(100 * 3));

        let t0 = Instant::now();
        net.enable(client_name, true);
        let x = 99;
        let reply = block_on(async { client.handler2(&JunkArgs { x }).await.unwrap() });
        assert_eq!(reply.x, format!("handler2-{}", x));
        let dur = t0.elapsed();
        assert!(
            dur < Duration::from_millis(30),
            "RPC took too long ({:?}) after Enable",
            dur
        );

        for _ in 0..nrpcs {
            rx.recv().unwrap();
        }

        let len = junk_server.inner.lock().unwrap().log2.len();
        assert_eq!(
            len, 1,
            "wrong number ({}) of RPCs delivered, expected 1",
            len
        );

        let n = net.count(server.name());
        assert_eq!(n, 1, "wrong count() {}, expected 1", n);
    }

    // if an RPC is stuck in a server, and the server
    // is killed with DeleteServer(), does the RPC
    // get un-stuck?
    #[test]
    fn test_killed() {
        init_logger();

        let (net, server, _junk_server) = junk_suit();
        let server_name = server.name();

        let client_name = "client";
        let client = JunkClient::new(net.create_client(client_name.to_owned()));
        net.connect(client_name, server_name);
        net.enable(client_name, true);
        let (tx, rx) = mpsc::channel();
        let cli = client.clone();
        client.spawn(async move {
            let reply = cli.handler3(&JunkArgs { x: 99 }).await;
            tx.send(reply).unwrap();
        });
        thread::sleep(Duration::from_secs(1));
        rx.recv_timeout(Duration::from_millis(100)).unwrap_err();

        net.delete_server(server_name);
        let reply = rx.recv_timeout(Duration::from_millis(100)).unwrap();
        assert_eq!(reply, Err(Error::Stopped));
    }

    struct Hooks {
        drop_req: AtomicBool,
        drop_resp: AtomicBool,
    }
    impl RpcHooks for Hooks {
        fn before_dispatch(&self, _: &str, _: &[u8]) -> Result<()> {
            if self.drop_req.load(Ordering::Relaxed) {
                Err(Error::Other("reqhook".to_owned()))
            } else {
                Ok(())
            }
        }
        fn after_dispatch(&self, _: &str, resp: Result<Vec<u8>>) -> Result<Vec<u8>> {
            if self.drop_resp.load(Ordering::Relaxed) {
                Err(Error::Other("resphook".to_owned()))
            } else {
                resp
            }
        }
    }

    #[test]
    fn test_rpc_hooks() {
        init_logger();
        let (net, _, _) = junk_suit();

        let raw_cli = net.create_client("test_client".to_owned());
        let hook = Arc::new(Hooks {
            drop_req: AtomicBool::new(false),
            drop_resp: AtomicBool::new(false),
        });
        raw_cli.set_hooks(hook.clone());

        let client = JunkClient::new(raw_cli);
        net.connect("test_client", "test_server");
        net.enable("test_client", true);

        let i = 100;
        let reply = block_on(async { client.handler2(&JunkArgs { x: i }).await.unwrap() });
        assert_eq!(reply.x, format!("handler2-{}", i));
        hook.drop_req.store(true, Ordering::Relaxed);
        assert_eq!(
            block_on(async { client.handler2(&JunkArgs { x: i }).await.unwrap_err() }),
            Error::Other("reqhook".to_owned())
        );
        hook.drop_req.store(false, Ordering::Relaxed);
        hook.drop_resp.store(true, Ordering::Relaxed);
        assert_eq!(
            block_on(async { client.handler2(&JunkArgs { x: i }).await.unwrap_err() }),
            Error::Other("resphook".to_owned())
        );
        hook.drop_resp.store(false, Ordering::Relaxed);
        block_on(async { client.handler2(&JunkArgs { x: i }).await.unwrap() });
        assert_eq!(reply.x, format!("handler2-{}", i));
    }
}


================================================
FILE: courses/dss/labrpc/src/macros.rs
================================================
#[macro_export]
macro_rules! service {
    () => {
        compile_error!("empty service is not allowed");
    };
    (
        $(#[$service_attr:meta])*
        service $svc_name:ident {
            $(
                $(#[$method_attr:meta])*
                rpc $method_name:ident($input:ty) returns ($output:ty);
            )*
        }
    ) => {
        $(#[$service_attr])*
        pub mod $svc_name {
            // In order to find input and output.
            use super::*;
            // $( use super::$input; )*
            // $( use super::$output;)*

            extern crate futures as __futures;

            #[async_trait::async_trait]
            pub trait Service: Clone + Send + 'static {
                $(
                    $(#[$method_attr])*
                    async fn $method_name(&self, req: $input) -> $crate::Result<$output>;
                )*
            }

            #[derive(Clone)]
            pub struct Client {
                client: $crate::Client,
            }
            impl Client {
                pub fn new(client: $crate::Client) -> Client {
                    Client { client }
                }

                pub fn spawn<F>(&self, f: F)
                where F: __futures::Future<Output = ()> + Send + 'static
                {
                    self.client.worker.spawn_ok(f);
                }

                $(pub fn $method_name(&self, args: &$input) -> $crate::RpcFuture<$crate::Result<$output>> {
                    let fq_name = concat!(stringify!($svc_name), ".", stringify!($method_name));
                    self.client.call(fq_name, args)
                })*
            }

            pub fn add_service<T: Service>(svc: T, builder: &mut $crate::ServerBuilder) -> $crate::Result<()> {
                use ::std::sync::Mutex;
                struct Factory<S> {
                    svc: Mutex<S>,
                }
                impl<S: Service> $crate::HandlerFactory for Factory<S> {
                    fn handler(&self, name: &'static str) -> Box<$crate::Handler> {
                        let s = self.svc.lock().unwrap().clone();
                        Box::new(move |req| {
                            match name {
                                $(stringify!($method_name) => {
                                    let request = match labcodec::decode(req) {
                                        Ok(req) => req,
                                        Err(e) => return Box::pin(__futures::future::err(
                                            $crate::Error::Decode(e)
                                        )),
                                    };
                                    Box::pin(async move {
                                        let f = s.$method_name(request);
                                        let resp = f.await;
                                        match resp {
                                            Ok(resp) => {
                                                let mut rsp = vec![];
                                                labcodec::encode(&resp, &mut rsp).map_err($crate::Error::Encode)?;
                                                Ok(rsp)
                                            }
                                            Err(e) => Err(e),
                                        }
                                    })
                                })*
                                other => {
                                    Box::pin(__futures::future::err(
                                        $crate::Error::Unimplemented(
                                            format!("unknown {} in {}", other, stringify!($svc_name))
                                        )
                                    ))
                                }
                            }
                        })
                    }
                }

                let fact = Factory {
                    svc: Mutex::new(svc),
                };

                builder.add_service(stringify!($svc_name), Box::new(fact))
            }
        }
    };
}


================================================
FILE: courses/dss/labrpc/src/network.rs
================================================
use std::collections::HashMap;
use std::future::Future;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Duration;

use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
use futures::executor::ThreadPool;
use futures::future::FutureExt;
use futures::select;
use futures::stream::StreamExt;
use futures_timer::Delay;
use log::{debug, error};
use rand::{thread_rng, Rng};

use crate::client::{Client, Rpc};
use crate::error::{Error, Result};
use crate::server::Server;

#[derive(Debug)]
struct EndInfo {
    enabled: bool,
    reliable: bool,
    long_reordering: bool,
    server: Option<Server>,
}

struct Endpoints {
    // by client name
    enabled: HashMap<String, bool>,
    // servers, by name
    servers: HashMap<String, Option<Server>>,
    // client_name -> server_name
    connections: HashMap<String, Option<String>>,
}

struct NetworkCore {
    reliable: AtomicBool,
    // pause a long time on send on disabled connection
    long_delays: AtomicBool,
    // sometimes delay replies a long time
    long_reordering: AtomicBool,
    endpoints: Mutex<Endpoints>,
    count: AtomicUsize,
    sender: UnboundedSender<Rpc>,
    poller: ThreadPool,
    worker: ThreadPool,
}

#[derive(Clone)]
pub struct Network {
    core: Arc<NetworkCore>,
}

impl Network {
    pub fn new() -> Network {
        let (net, incoming) = Network::create();
        net.start(incoming);
        net
    }

    pub fn create() -> (Network, UnboundedReceiver<Rpc>) {
        let (sender, incoming) = unbounded();
        let net = Network {
            core: Arc::new(NetworkCore {
                reliable: AtomicBool::new(true),
                long_delays: AtomicBool::new(false),
                long_reordering: AtomicBool::new(false),
                endpoints: Mutex::new(Endpoints {
                    enabled: HashMap::new(),
                    servers: HashMap::new(),
                    connections: HashMap::new(),
                }),
                count: AtomicUsize::new(0),
                poller: ThreadPool::builder().pool_size(2).create().unwrap(),
                worker: ThreadPool::new().unwrap(),
                sender,
            }),
        };

        (net, incoming)
    }

    fn start(&self, mut incoming: UnboundedReceiver<Rpc>) {
        let network = self.clone();
        self.core.poller.spawn_ok(async move {
            while let Some(mut rpc) = incoming.next().await {
                let resp = rpc.take_resp_sender().unwrap();
                let net = network.clone();
                network.core.poller.spawn_ok(async move {
                    let res = net.process_rpc(rpc).await;
                    if let Err(e) = resp.send(res) {
                        error!("fail to send resp: {:?}", e);
                    }
                })
            }
        });
    }

    pub fn add_server(&self, server: Server) {
        let mut eps = self.core.endpoints.lock().unwrap();
        eps.servers.insert(server.core.name.clone(), Some(server));
    }

    pub fn delete_server(&self, name: &str) {
        let mut eps = self.core.endpoints.lock().unwrap();
        if let Some(s) = eps.servers.get_mut(name) {
            *s = None;
        }
    }

    pub fn create_client(&self, name: String) -> Client {
        let sender = self.core.sender.clone();
        let mut eps = self.core.endpoints.lock().unwrap();
        eps.enabled.insert(name.clone(), false);
        eps.connections.insert(name.clone(), None);
        Client {
            name,
            sender,
            worker: self.core.worker.clone(),
            hooks: Arc::new(Mutex::new(None)),
        }
    }

    /// Connects a Client to a server.
    /// a Client can only be connected once in its lifetime.
    pub fn connect(&self, client_name: &str, server_name: &str) {
        let mut eps = self.core.endpoints.lock().unwrap();
        eps.connections
            .insert(client_name.to_owned(), Some(server_name.to_owned()));
    }

    /// Enable/disable a Client.
    pub fn enable(&self, client_name: &str, enabled: bool) {
        debug!(
            "client {} is {}",
            client_name,
            if enabled { "enabled" } else { "disabled" }
        );
        let mut eps = self.core.endpoints.lock().unwrap();
        eps.enabled.insert(client_name.to_owned(), enabled);
    }

    pub fn set_reliable(&self, yes: bool) {
        self.core.reliable.store(yes, Ordering::Release);
    }

    pub fn set_long_reordering(&self, yes: bool) {
        self.core.long_reordering.store(yes, Ordering::Release);
    }

    pub fn set_long_delays(&self, yes: bool) {
        self.core.long_delays.store(yes, Ordering::Release);
    }

    pub fn count(&self, server_name: &str) -> usize {
        let eps = self.core.endpoints.lock().unwrap();
        eps.servers[server_name].as_ref().unwrap().count()
    }

    pub fn total_count(&self) -> usize {
        self.core.count.load(Ordering::Relaxed)
    }

    fn end_info(&self, client_name: &str) -> EndInfo {
        let eps = self.core.endpoints.lock().unwrap();
        let mut server = None;
        if let Some(Some(server_name)) = eps.connections.get(client_name) {
            server = eps.servers[server_name].clone();
        }
        EndInfo {
            enabled: eps.enabled[client_name],
            reliable: self.core.reliable.load(Ordering::Acquire),
            long_reordering: self.core.long_reordering.load(Ordering::Acquire),
            server,
        }
    }

    fn is_server_dead(&self, client_name: &str, server_name: &str, server_id: usize) -> bool {
        let eps = self.core.endpoints.lock().unwrap();
        !eps.enabled[client_name]
            || eps.servers.get(server_name).map_or(true, |o| {
                o.as_ref().map(|s| s.core.id != server_id).unwrap_or(true)
            })
    }

    async fn process_rpc(&self, rpc: Rpc) -> Result<Vec<u8>> {
        self.core.count.fetch_add(1, Ordering::Relaxed);
        let network = self.clone();
        let end_info = self.end_info(&rpc.client_name);
        debug!("{:?} process with {:?}", rpc, end_info);
        let EndInfo {
            enabled,
            reliable,
            long_reordering,
            server,
        } = end_info;

        match (enabled, server) {
            (true, Some(server)) => {
                let short_delay = if !reliable {
                    // short delay
                    let ms = thread_rng().gen::<u64>() % 27;
                    Some(ms)
                } else {
                    None
                };

                if !reliable && (thread_rng().gen::<u64>() % 1000) < 100 {
                    // drop the request, return as if timeout
                    Delay::new(Duration::from_secs(short_delay.unwrap())).await;
                    return Err(Error::Timeout);
                }

                let drop_reply = !reliable && thread_rng().gen::<u64>() % 1000 < 100;
                let long_reordering = if long_reordering && thread_rng().gen_range(0, 900) < 600i32
                {
                    // delay the response for a while
                    let upper_bound: u64 = 1 + thread_rng().gen_range(0, 2000);
                    Some(200 + thread_rng().gen_range(0, upper_bound))
                } else {
                    None
                };

                // Dispatch
                process_rpc(
                    short_delay,
                    drop_reply,
                    long_reordering,
                    rpc,
                    network,
                    server,
                )
                .await
            }
            _ => {
                // simulate no reply and eventual timeout.
                let ms = if self.core.long_delays.load(Ordering::Acquire) {
                    // let Raft tests check that leader doesn't send
                    // RPCs synchronously.
                    thread_rng().gen::<u64>() % 7000
                } else {
                    // many kv tests require the client to try each
                    // server in fairly rapid succession.
                    thread_rng().gen::<u64>() % 100
                };

                debug!("{:?} delay {}ms then timeout", rpc, ms);
                Delay::new(Duration::from_millis(ms)).await;
                Err(Error::Timeout)
            }
        }
    }

    /// Spawns a future to run on this net framework.
    pub fn spawn<F>(&self, f: F)
    where
        F: Future<Output = ()> + Send + 'static,
    {
        self.core.worker.spawn_ok(f);
    }

    /// Spawns a future to run on this net framework.
    pub fn spawn_poller<F>(&self, f: F)
    where
        F: Future<Output = ()> + Send + 'static,
    {
        self.core.poller.spawn_ok(f);
    }
}

async fn process_rpc(
    mut delay: Option<u64>,
    drop_reply: bool,
    long_reordering: Option<u64>,
    mut rpc: Rpc,
    network: Network,
    server: Server,
) -> Result<Vec<u8>> {
    // Dispatch ===============================================================
    if let Some(delay) = delay {
        Delay::new(Duration::from_millis(delay)).await;
    }
    // We has finished the delay, take it out to prevent polling
    // twice.
    delay.take();

    let fq_name = rpc.fq_name;
    let req = rpc.req.take().unwrap();
    if let Some(hooks) = rpc.hooks.lock().unwrap().as_ref() {
        hooks.before_dispatch(fq_name, &req)?;
    }

    // Execute the request (call the RPC handler) in a separate thread so that
    // we can periodically check if the server has been killed and the RPC
    // should get a failure reply.
    //
    // do not reply if DeleteServer() has been called, i.e. the server has been killed.
    // this is needed to avoid situation in which a client gets a positive reply
    // to an Append, but the server persisted the update into the old Persister.
    // config.go is careful to call DeleteServer() before superseding the Persister.
    let resp = select! {
        res = server.dispatch(fq_name, &req).fuse() => res,
        _ = server_dead(
            Duration::from_millis(100),
            network.clone(),
            &rpc.client_name,
            &server.core.name,
            server.core.id,
        ).fuse() => Err(Error::Stopped),
    };

    let resp = if let Some(hooks) = rpc.hooks.lock().unwrap().as_ref() {
        hooks.after_dispatch(fq_name, resp)?
    } else {
        resp?
    };

    // Ongoing ================================================================
    let client_name = &rpc.client_name;
    let server_name = &server.core.name;
    let server_id = server.core.id;
    if network.is_server_dead(client_name, server_name, server_id) {
        return Err(Error::Stopped);
    }
    if drop_reply {
        // drop the reply, return as if timeout.
        return Err(Error::Timeout);
    }

    // Reordering =============================================================
    if let Some(reordering) = long_reordering {
        debug!("{:?} next long reordering {}ms", rpc, reordering);
        Delay::new(Duration::from_millis(reordering)).await;
        Ok(resp)
    } else {
        Ok(resp)
    }
}

/// Checks if the specified server killed.
///
/// It will return when the server is killed.
async fn server_dead(
    interval: Duration,
    net: Network,
    client_name: &str,
    server_name: &str,
    server_id: usize,
) {
    loop {
        Delay::new(interval).await;
        if net.is_server_dead(client_name, server_name, server_id) {
            debug!("{:?} is dead", server_name);
            return;
        }
    }
}


================================================
FILE: courses/dss/labrpc/src/server.rs
================================================
use std::collections::hash_map::{Entry, HashMap};
use std::fmt;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;

use futures::future::{self, BoxFuture};

use crate::error::{Error, Result};

static ID_ALLOC: AtomicUsize = AtomicUsize::new(0);

pub type RpcFuture<T> = BoxFuture<'static, T>;

pub type Handler = dyn FnOnce(&[u8]) -> RpcFuture<Result<Vec<u8>>>;

pub trait HandlerFactory: Sync + Send + 'static {
    fn handler(&self, name: &'static str) -> Box<Handler>;
}

pub struct ServerBuilder {
    name: String,
    // Service name -> service methods
    pub(crate) services: HashMap<&'static str, Box<dyn HandlerFactory>>,
}

impl ServerBuilder {
    pub fn new(name: String) -> ServerBuilder {
        ServerBuilder {
            name,
            services: HashMap::new(),
        }
    }

    pub fn add_service(
        &mut self,
        service_name: &'static str,
        factory: Box<dyn HandlerFactory>,
    ) -> Result<()> {
        match self.services.entry(service_name) {
            Entry::Occupied(_) => Err(Error::Other(format!(
                "{} has already registered",
                service_name
            ))),
            Entry::Vacant(entry) => {
                entry.insert(factory);
                Ok(())
            }
        }
    }

    pub fn build(self) -> Server {
        Server {
            core: Arc::new(ServerCore {
                name: self.name,
                services: self.services,
                id: ID_ALLOC.fetch_add(1, Ordering::Relaxed),
                count: AtomicUsize::new(0),
            }),
        }
    }
}

pub(crate) struct ServerCore {
    pub(crate) name: String,
    pub(crate) id: usize,

    pub(crate) services: HashMap<&'static str, Box<dyn HandlerFactory>>,
    pub(crate) count: AtomicUsize,
}

#[derive(Clone)]
pub struct Server {
    pub(crate) core: Arc<ServerCore>,
}

impl Server {
    pub fn count(&self) -> usize {
        self.core.count.load(Ordering::Relaxed)
    }

    pub fn name(&self) -> &str {
        &self.core.name
    }

    pub(crate) fn dispatch(&self, fq_name: &'static str, req: &[u8]) -> RpcFuture<Result<Vec<u8>>> {
        self.core.count.fetch_add(1, Ordering::Relaxed);
        let mut names = fq_name.split('.');
        let service_name = match names.next() {
            Some(n) => n,
            None => {
                return Box::pin(future::err(Error::Unimplemented(format!(
                    "unknown {}",
                    fq_name
                ))));
            }
        };
        let method_name = match names.next() {
            Some(n) => n,
            None => {
                return Box::pin(future::err(Error::Unimplemented(format!(
                    "unknown {}",
                    fq_name
                ))));
            }
        };
        if let Some(factory) = self.core.services.get(service_name) {
            let handle = factory.handler(method_name);
            handle(req)
        } else {
            Box::pin(future::err(Error::Unimplemented(format!(
                "unknown {}",
                fq_name
            ))))
        }
    }
}

impl fmt::Debug for Server {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Server")
            .field("name", &self.core.name)
            .field("id", &self.core.id)
            .finish()
    }
}


================================================
FILE: courses/dss/linearizability/Cargo.toml
================================================
[package]
name = "linearizability"
version = "0.1.0"
edition = "2018"
publish = false

[dev-dependencies]
regex = "1.3"
lazy_static = "1.4"


================================================
FILE: courses/dss/linearizability/src/bitset.rs
================================================
use std::num::Wrapping;

#[derive(Clone)]
pub struct Bitset(Vec<u64>);

impl Bitset {
    pub fn new(bits: usize) -> Self {
        let extra = if bits % 64 != 0 { 1 } else { 0 };
        Bitset(vec![0; bits / 64 + extra])
    }

    pub fn set(&mut self, pos: usize) {
        let (major, minor) = bitset_index(pos);
        self.0[major] |= 1 << minor;
    }

    pub fn clear(&mut self, pos: usize) {
        let (major, minor) = bitset_index(pos);
        self.0[major] &= !(1 << minor);
    }

    fn popcnt(&self) -> usize {
        let mut total = 0;
        for b in &self.0 {
            let mut v = *b;
            v = (v & 0x5555_5555_5555_5555) + ((v & 0xAAAA_AAAA_AAAA_AAAA) >> 1);
            v = (v & 0x3333_3333_3333_3333) + ((v & 0xCCCC_CCCC_CCCC_CCCC) >> 2);
            v = (v & 0x0F0F_0F0F_0F0F_0F0F) + ((v & 0xF0F0_F0F0_F0F0_F0F0) >> 4);
            v = (Wrapping(v) * Wrapping(0x0101_0101_0101_0101)).0;
            total += ((v >> 56) & 0xFF) as usize;
        }
        total
    }

    pub fn hash(&self) -> u64 {
        let mut hash = self.popcnt() as u64;
        for v in &self.0 {
            hash ^= v;
        }
        hash
    }

    pub fn equals(&self, b2: &Bitset) -> bool {
        let b = &self.0;
        let b2 = &b2.0;
        if b.len() != b2.len() {
            return false;
        }
        for i in 0..b.len() {
            if b[i] != b2[i] {
                return false;
            }
        }
        true
    }
}

fn bitset_index(pos: usize) -> (usize, usize) {
    (pos / 64, pos % 64)
}


================================================
FILE: courses/dss/linearizability/src/lib.rs
================================================
mod bitset;
pub mod model;
pub mod models;

use std::cell::{Ref, RefCell};
use std::collections::HashMap;
use std::fmt::Debug;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{channel, Receiver, RecvTimeoutError};
use std::sync::Arc;
use std::thread;
use std::time::Duration;

use crate::bitset::Bitset;
use crate::model::{Event, EventKind, Events, Model, Operations, Value};

enum EntryKind {
    CallEntry,
    ReturnEntry,
}

struct Entry<T> {
    pub kind: EntryKind,
    pub value: T,
    pub id: usize,
    pub time: i64,
}

fn make_entries<I: Debug, O: Debug>(history: Operations<I, O>) -> Vec<Entry<Value<I, O>>> {
    let mut entries = Vec::new();
    for (id, elem) in history.into_iter().enumerate() {
        entries.push(Entry {
            kind: EntryKind::CallEntry,
            value: Value::Input(elem.input),
            id,
            time: elem.call,
        });
        entries.push(Entry {
            kind: EntryKind::ReturnEntry,
            value: Value::Output(elem.output),
            id,
            time: elem.finish,
        })
    }
    entries.sort_by(|a, b| a.time.partial_cmp(&b.time).unwrap());
    entries
}

struct LinkedNodes<T: Debug> {
    head: Option<LinkNode<T>>,
}

impl<T: Debug> LinkedNodes<T> {
    pub fn new() -> Self {
        LinkedNodes { head: None }
    }

    pub fn head(&self) -> Option<LinkNode<T>> {
        self.head.clone()
    }

    pub fn from_entries(entries: Vec<Entry<T>>) -> Self {
        let mut matches: HashMap<usize, LinkNode<T>> = HashMap::new();
        let mut nodes = Self::new();

        for entry in entries.into_iter().rev() {
            nodes.push_front(match entry.kind {
                EntryKind::CallEntry => Rc::new(RefCell::new(Node {
                    value: entry.value,
                    matched: matches.get(&entry.id).cloned(),
                    id: entry.id,
                    next: None,
                    prev: None,
                })),
                EntryKind::ReturnEntry => {
                    let node = Rc::new(RefCell::new(Node {
                        value: entry.value,
                        matched: None,
                        id: entry.id,
                        next: None,
                        prev: None,
                    }));
                    matches.insert(entry.id, node.clone());
                    node
                }
            })
        }

        nodes
    }

    pub fn len(&self) -> usize {
        let mut len = 0;
        let mut entry = self.head.clone();
        while let Some(e) = entry {
            entry = e.borrow().next.clone();
            len += 1;
        }
        len
    }

    pub fn push_front(&mut self, new_head: LinkNode<T>) {
        match self.head.take() {
            Some(old_head) => {
                old_head.borrow_mut().prev = Some(new_head.clone());
                new_head.borrow_mut().next = Some(old_head);
                self.head = Some(new_head);
            }
            None => {
                self.head = Some(new_head);
            }
        }
    }
}

type LinkNode<T> = Rc<RefCell<Node<T>>>;

struct Node<T: Debug> {
    pub value: T,
    pub matched: Option<LinkNode<T>>,
    pub id: usize,
    pub next: Option<LinkNode<T>>,
    pub prev: Option<LinkNode<T>>,
}

fn renumber<T>(events: Vec<Event<T>>) -> Vec<Event<T>> {
    let mut e = Vec::new();
    let mut m: HashMap<usize, usize> = HashMap::new(); // renumbering
    let mut id: usize = 0;
    for event in events {
        e.push(Event {
            kind: event.kind,
            value: event.value,
            id: *m.entry(event.id).or_insert_with(|| {
                id += 1;
                id - 1
            }),
        });
    }
    e
}

fn convert_entries<T>(events: Vec<Event<T>>) -> Vec<Entry<T>> {
    let mut entries = Vec::new();
    for event in events {
        entries.push(match event.kind {
            EventKind::CallEvent => Entry {
                kind: EntryKind::CallEntry,
                value: event.value,
                id: event.id,
                time: -1,
            },
            EventKind::ReturnEvent => Entry {
                kind: EntryKind::ReturnEntry,
                value: event.value,
                id: event.id,
                time: -1,
            },
        })
    }
    entries
}

struct CacheEntry<T> {
    linearized: Bitset,
    state: T,
}

fn cache_contains<M: Model>(
    model: &M,
    cache: &HashMap<u64, Vec<CacheEntry<M::State>>>,
    entry: &CacheEntry<M::State>,
) -> bool {
    if cache.contains_key(&entry.linearized.hash()) {
        for elem in &cache[&entry.linearized.hash()] {
            if entry.linearized.equals(&elem.linearized) && model.equal(&entry.state, &elem.state) {
                return true;
            }
        }
    }
    false
}

struct CallsEntry<V: Debug, T> {
    entry: Option<LinkNode<V>>,
    state: T,
}

fn lift<T: Debug>(entry: &LinkNode<T>) {
    let prev = Ref::map(entry.borrow(), |e| e.prev.as_ref().unwrap());
    prev.borrow_mut().next = entry.borrow().next.clone();
    let next = Ref::map(entry.borrow(), |e| e.next.as_ref().unwrap());
    next.borrow_mut().prev = entry.borrow().prev.clone();

    let matched = Ref::map(entry.borrow(), |e| e.matched.as_ref().unwrap());
    let matched_prev = Ref::map(matched.borrow(), |e| e.prev.as_ref().unwrap());
    matched_prev.borrow_mut().next = matched.borrow().next.clone();
    if matched.borrow().next.is_some() {
        let matched_next = Ref::map(matched.borrow(), |e| e.next.as_ref().unwrap());
        matched_next.borrow_mut().prev = matched.borrow().prev.clone();
    }
}

fn unlift<T: Debug>(entry: &LinkNode<T>) {
    {
        let matched = Ref::map(entry.borrow(), |e| e.matched.as_ref().unwrap());
        let matched_prev = Ref::map(matched.borrow(), |e| e.prev.as_ref().unwrap());
        matched_prev.borrow_mut().next = Some(matched.clone());
        if matched.borrow().next.is_some() {
            let matched_next = Ref::map(matched.borrow(), |e| e.next.as_ref().unwrap());
            matched_next.borrow_mut().prev = Some(matched.clone());
        }
    }

    let prev = Ref::map(entry.borrow(), |e| e.prev.as_ref().unwrap());
    prev.borrow_mut().next = Some(entry.clone());
    let next = Ref::map(entry.borrow(), |e| e.next.as_ref().unwrap());
    next.borrow_mut().prev = Some(entry.clone());
}

fn check_single<M: Model>(
    model: M,
    mut subhistory: LinkedNodes<Value<M::Input, M::Output>>,
    kill: Arc<AtomicBool>,
) -> bool {
    let n = subhistory.len() / 2;
    let mut linearized = Bitset::new(n);
    let mut cache = HashMap::new();
    let mut calls = vec![];

    let mut state = model.init();
    subhistory.push_front(Rc::new(RefCell::new(Node {
        value: Value::None,
        matched: None,
        id: usize::max_value(),
        prev: None,
        next: None,
    })));
    let head_entry = subhistory.head().unwrap();
    let mut entry = head_entry.borrow().next.clone();
    while head_entry.borrow().next.is_some() {
        if kill.load(Ordering::SeqCst) {
            return false;
        }
        let matched = entry.as_ref().unwrap().borrow().matched.clone();
        entry = if let Some(matching) = matched {
            // the return entry
            let res = model.step(
                &state,
                entry.as_ref().unwrap().borrow().value.input(),
                matching.borrow().value.output(),
            );
            match res {
                (true, new_state) => {
                    let mut new_linearized = linearized.clone();
                    new_linearized.set(entry.as_ref().unwrap().borrow().id);
                    let new_cache_entry = CacheEntry {
                        linearized: new_linearized.clone(),
                        state: new_state.clone(),
                    };
                    if !cache_contains(&model, &cache, &new_cache_entry) {
                        let hash = new_linearized.hash();
                        cache.entry(hash).or_default().push(new_cache_entry);
                        calls.push(CallsEntry {
                            entry: entry.clone(),
                            state,
                        });
                        state = new_state;
                        linearized.set(entry.as_ref().unwrap().borrow().id);
                        lift(entry.as_ref().unwrap());
                        head_entry.borrow().next.clone()
                    } else {
                        entry.as_ref().unwrap().borrow().next.clone()
                    }
                }
                (false, _) => entry.as_ref().unwrap().borrow().next.clone(),
            }
        } else {
            if calls.is_empty() {
                return false;
            }
            let calls_top = calls.pop().unwrap();
            entry = calls_top.entry;
            state = calls_top.state;
            linearized.clear(entry.as_ref().unwrap().borrow().id);
            unlift(entry.as_ref().unwrap());
            entry.as_ref().unwrap().borrow().next.clone()
        }
    }
    true
}

pub fn check_operations<M: Model>(model: M, history: Operations<M::Input, M::Output>) -> bool {
    check_operations_timeout(model, history, Duration::new(0, 0))
}

// timeout = 0 means no timeout
// if this operation times out, then a false positive is possible
pub fn check_operations_timeout<M: Model>(
    model: M,
    history: Operations<M::Input, M::Output>,
    timeout: Duration,
) -> bool {
    let partitions = model.partition(history);

    let (tx, rx) = channel();
    let mut handles = vec![];
    let kill = Arc::new(AtomicBool::new(false));
    let count = partitions.len();
    for subhistory in partitions {
        let tx = tx.clone();
        let kill = Arc::clone(&kill);
        let m = model.clone();
        let handle = thread::spawn(move || {
            let l = LinkedNodes::from_entries(make_entries(subhistory));
            let _ = tx.send(check_single(m, l, kill));
        });
        handles.push(handle);
    }

    let res = wait_res(rx, kill, count, timeout);
    for handle in handles {
        handle.join().unwrap();
    }
    res
}

pub fn check_events<M: Model>(model: M, history: Events<M::Input, M::Output>) -> bool {
    check_events_timeout(model, history, Duration::new(0, 0))
}

// timeout = 0 means no timeout
// if this operation times out, then a false positive is possible
pub fn check_events_timeout<M: Model>(
    model: M,
    history: Events<M::Input, M::Output>,
    timeout: Duration,
) -> bool {
    let partitions = model.partition_event(history);

    let (tx, rx) = channel();
    let mut handles = vec![];
    let kill = Arc::new(AtomicBool::new(false));
    let count = partitions.len();
    for subhistory in partitions {
        let tx = tx.clone();
        let kill = Arc::clone(&kill);
        let m = model.clone();
        let handle = thread::spawn(move || {
            let l = LinkedNodes::from_entries(convert_entries(renumber(subhistory)));
            let _ = tx.send(check_single(m, l, kill));
        });
        handles.push(handle);
    }

    let res = wait_res(rx, kill, count, timeout);
    for handle in handles {
        handle.join().unwrap();
    }
    res
}

fn wait_res(
    rx: Receiver<bool>,
    kill: Arc<AtomicBool>,
    mut count: usize,
    timeout: Duration,
) -> bool {
    let mut ok = true;
    loop {
        match if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
            rx.recv().map_err(From::from)
        } else {
            rx.recv_timeout(timeout)
        } {
            Ok(res) => {
                ok = ok && res;
                if !ok {
                    kill.store(true, Ordering::SeqCst);
                    break;
                }
                count -= 1;
                if count == 0 {
                    break;
                }
            }
            Err(RecvTimeoutError::Timeout) => break,
            Err(e) => panic!("recv err: {}", e),
        }
    }
    ok
}


================================================
FILE: courses/dss/linearizability/src/model.rs
================================================
use std::cmp::PartialEq;
use std::fmt::Debug;
use std::fmt::Display;
use std::marker::Send;

#[derive(Debug)]
pub enum Value<I: Debug, O: Debug> {
    Input(I),
    Output(O),
    None,
}

impl<I: Debug, O: Debug> Value<I, O> {
    pub fn input(&self) -> &I {
        if let Value::Input(i) = self {
            i
        } else {
            panic!("Not a input")
        }
    }

    pub fn output(&self) -> &O {
        if let Value::Output(o) = self {
            o
        } else {
            panic!("Not a output")
        }
    }
}

#[derive(Debug)]
pub struct Operation<I: Debug, O: Debug> {
    pub input: I,
    pub call: i64, // invocation time
    pub output: O,
    pub finish: i64, // response time
}

pub enum EventKind {
    CallEvent,
    ReturnEvent,
}

pub struct Event<T> {
    pub kind: EventKind,
    pub value: T,
    pub id: usize,
}

pub type Operations<I, O> = Vec<Operation<I, O>>;
pub type Events<I, O> = Vec<Event<Value<I, O>>>;

pub trait Model: Clone + Send + 'static {
    type State: Clone + Display + PartialEq;
    type Input: Send + Debug + 'static;
    type Output: Send + Debug + 'static;

    // Partition functions, such that a history is linearizable if an only
    // if each partition is linearizable. If you don't want to implement
    // this, you can always use the `NoPartition` functions implemented
    // below.
    fn partition(
        &self,
        history: Operations<Self::Input, Self::Output>,
    ) -> Vec<Operations<Self::Input, Self::Output>> {
        vec![history]
    }

    fn partition_event(
        &self,
        history: Events<Self::Input, Self::Output>,
    ) -> Vec<Events<Self::Input, Self::Output>> {
        vec![history]
    }

    // Initial state of the system.
    fn init(&self) -> Self::State;

    // Step function for the system. Returns whether or not the system
    // could take this step with the given inputs and outputs and also
    // returns the new state. This should not mutate the existing state.
    fn step(
        &self,
        state: &Self::State,
        input: &Self::Input,
        output: &Self::Output,
    ) -> (bool, Self::State);

    // Equality on states. If you are using a simple data type for states,
    // you can use the `ShallowEqual` function implemented below.
    fn equal(&self, state1: &Self::State, state2: &Self::State) -> bool {
        state1 == state2
    }
}


================================================
FILE: courses/dss/linearizability/src/models.rs
================================================
use std::collections::HashMap;

use super::model::{EventKind, Events, Model, Operations};

#[derive(Clone, Debug)]
pub enum Op {
    Get,
    Put,
    Append,
}

#[derive(Clone, Debug)]
pub struct KvInput {
    pub op: Op,
    pub key: String,
    pub value: String,
}

#[derive(Clone, Debug)]
pub struct KvOutput {
    pub value: String,
}

#[derive(Clone, Default)]
pub struct KvModel {}

impl Model for KvModel {
    type State = String;
    type Input = KvInput;
    type Output = KvOutput;

    fn partition(
        &self,
        history: Operations<Self::Input, Self::Output>,
    ) -> Vec<Operations<Self::Input, Self::Output>> {
        let mut map = HashMap::new();
        for op in history {
            let v = map.entry(op.input.key.clone()).or_insert_with(Vec::new);
            (*v).push(op);
        }
        let mut ret = vec![];
        for (_, ops) in map {
            ret.push(ops);
        }
        ret
    }

    fn partition_event(
        &self,
        history: Events<Self::Input, Self::Output>,
    ) -> Vec<Events<Self::Input, Self::Output>> {
        let mut m = HashMap::new();
        let mut matched: HashMap<usize, String> = HashMap::new();
        for event in history {
            match event.kind {
                EventKind::CallEvent => {
                    let key = event.value.input().key.clone();
                    matched.insert(event.id, key.clone());
                    m.entry(key).or_insert_with(Vec::new).push(event);
                }
                EventKind::ReturnEvent => {
                    let key = matched[&event.id].clone();
                    m.entry(key).or_insert_with(Vec::new).push(event);
                }
            }
        }
        let mut ret = vec![];
        for (_, v) in m {
            ret.push(v);
        }
        ret
    }

    fn init(&self) -> Self::State {
        // note: we are modeling a single key's value here;
        // we're partitioning by key, so this is okay
        "".to_string()
    }

    fn step(
        &self,
        state: &Self::State,
        input: &Self::Input,
        output: &Self::Output,
    ) -> (bool, Self::State) {
        match input.op {
            Op::Get => (&output.value == state, state.clone()),
            Op::Put => (true, input.value.clone()),
            Op::Append => (true, state.clone() + &input.value),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;
    use std::fs::File;
    use std::io::{BufRead, BufReader, Result};

    use super::super::check_events;
    use super::{KvInput, KvModel, KvOutput, Op};
    use crate::model::{Event, EventKind, Events, Model, Value};
    use regex::Regex;

    fn check_kv(log_name: String, correct: bool) {
        let model = KvModel {};

        let file_name = format!("../linearizability/test_data/{}.txt", &log_name);
        let events = match parse_kv_log(&file_name) {
            Ok(events) => events,
            Err(e) => panic!("parse kv log {} failed: {}", &file_name, e),
        };
        assert_eq!(check_events(model, events), correct);
    }

    fn parse_kv_log(
        file_name: &str,
    ) -> Result<Events<<KvModel as Model>::Input, <KvModel as Model>::Output>> {
        lazy_static::lazy_static! {
            static ref INVOKE_GET: Regex = Regex::new(
                r#"\{:process (\d+), :type :invoke, :f :get, :key "(.*)", :value nil\}"#
            )
            .unwrap();
            static ref INVOKE_PUT: Regex = Regex::new(
                r#"\{:process (\d+), :type :invoke, :f :put, :key "(.*)", :value "(.*)"\}"#
            )
            .unwrap();
            static ref INVOKE_APPEND: Regex = Regex::new(
                r#"\{:process (\d+), :type :invoke, :f :append, :key "(.*)", :value "(.*)"\}"#
            )
            .unwrap();
            static ref RETURN_GET: Regex =
                Regex::new(r#"\{:process (\d+), :type :ok, :f :get, :key ".*", :value "(.*)"\}"#)
                    .unwrap();
            static ref RETURN_PUT: Regex =
                Regex::new(r#"\{:process (\d+), :type :ok, :f :put, :key ".*", :value ".*"\}"#)
                    .unwrap();
            static ref RETURN_APPEND: Regex =
                Regex::new(r#"\{:process (\d+), :type :ok, :f :append, :key ".*", :value ".*"\}"#)
                    .unwrap();
        }

        let f = File::open(file_name)?;
        let buf_reader = BufReader::new(f);
        let mut events = vec![];
        let mut id = 0;
        let mut procid_map: HashMap<isize, usize> = HashMap::new();

        for line in buf_reader.lines() {
            let contents = line.unwrap();
            if let Some(args) = INVOKE_GET.captures(&contents) {
                events.push(Event {
                    kind: EventKind::CallEvent,
                    value: Value::Input(KvInput {
                        op: Op::Get,
                        key: args[2].to_string(),
                        value: "".to_string(),
                    }),
                    id,
                });
                procid_map.insert(args[1].to_string().parse().unwrap(), id);
                id += 1;
            } else if let Some(args) = INVOKE_PUT.captures(&contents) {
                events.push(Event {
                    kind: EventKind::CallEvent,
                    value: Value::Input(KvInput {
                        op: Op::Put,
                        key: args[2].to_string(),
                        value: args[3].to_string(),
                    }),
                    id,
                });
                procid_map.insert(args[1].to_string().parse().unwrap(), id);
                id += 1;
            } else if let Some(args) = INVOKE_APPEND.captures(&contents) {
                events.push(Event {
                    kind: EventKind::CallEvent,
                    value: Value::Input(KvInput {
                        op: Op::Append,
                        key: args[2].to_string(),
                        value: args[3].to_string(),
                    }),
                    id,
                });
                procid_map.insert(args[1].to_string().parse().unwrap(), id);
                id += 1;
            } else if let Some(args) = RETURN_GET.captures(&contents) {
                let match_id = procid_map
                    .remove(&args[1].to_string().parse().unwrap())
                    .unwrap();
                events.push(Event {
                    kind: EventKind::ReturnEvent,
                    value: Value::Output(KvOutput {
                        value: args[2].to_string(),
                    }),
                    id: match_id,
                });
            } else if let Some(args) = RETURN_PUT.captures(&contents) {
                let match_id = procid_map
                    .remove(&args[1].to_string().parse().unwrap())
                    .unwrap();
                events.push(Event {
                    kind: EventKind::ReturnEvent,
                    value: Value::Output(KvOutput {
                        value: "".to_string(),
                    }),
                    id: match_id,
                });
            } else if let Some(args) = RETURN_APPEND.captures(&contents) {
                let match_id = procid_map
                    .remove(&args[1].to_string().parse().unwrap())
                    .unwrap();
                events.push(Event {
                    kind: EventKind::ReturnEvent,
                    value: Value::Output(KvOutput {
                        value: "".to_string(),
                    }),
                    id: match_id,
                });
            } else {
                unreachable!();
            }
        }

        for (_, match_id) in procid_map {
            events.push(Event {
                kind: EventKind::ReturnEvent,
                value: Value::Output(KvOutput {
                    value: "".to_string(),
                }),
                id: match_id,
            })
        }
        Ok(events)
    }

    #[test]
    fn test_kv_1client_ok() {
        check_kv("c01-ok".to_string(), true)
    }

    #[test]
    fn test_kv_1client_bad() {
        check_kv("c01-bad".to_string(), false)
    }

    #[test]
    fn test_kv_10client_ok() {
        check_kv("c10-ok".to_string(), true)
    }

    #[test]
    fn test_kv_10client_bad() {
        check_kv("c10-bad".to_string(), false)
    }

    #[test]
    fn test_kv_50client_ok() {
        check_kv("c50-ok".to_string(), true)
    }

    #[test]
    fn test_kv_50client_bad() {
        check_kv("c50-bad".to_string(), false)
    }
}


================================================
FILE: courses/dss/linearizability/test_data/c01-bad.txt
================================================
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 0 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 0 y"}
{:process 0, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "7", :value ""}
{:process 0, :type :invoke, :f :get, :key "6", :value nil}
{:process 0, :type :ok, :f :get, :key "6", :value ""}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value ""}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value ""}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 1 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value ""}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 2 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 2 y"}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 3 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 3 y"}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 4 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :append, :key "5", :value "x 0 5 y"}
{:process 0, :type :ok, :f :append, :key "5", :value "x 0 5 y"}
{:process 0, :type :invoke, :f :get, :key "6", :value nil}
{:process 0, :type :ok, :f :get, :key "6", :value ""}
{:process 0, :type :invoke, :f :append, :key "1", :value "x 0 6 y"}
{:process 0, :type :ok, :f :append, :key "1", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :get, :key "1", :value nil}
{:process 0, :type :ok, :f :get, :key "1", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :get, :key "3", :value nil}
{:process 0, :type :ok, :f :get, :key "3", :value ""}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 7 y"}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 7 y"}
{:process 0, :type :invoke, :f :get, :key "0", :value nil}
{:process 0, :type :ok, :f :get, :key "0", :value "x 0 0 yx 0 1 yx 0 2 yx 0 3 yx 0 4 y"}
{:process 0, :type :invoke, :f :append, :key "1", :value "x 0 8 y"}
{:process 0, :type :ok, :f :append, :key "1", :value "x 0 8 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 0 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 0 y"}
{:process 0, :type :invoke, :f :get, :key "0", :value nil}
{:process 0, :type :ok, :f :get, :key "0", :value "x 0 0 yx 0 1 yx 0 2 yx 0 3 yx 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value "x 0 7 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value "x 0 5 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value "x 0 7 y"}
{:process 0, :type :invoke, :f :append, :key "6", :value "x 0 1 y"}
{:process 0, :type :ok, :f :append, :key "6", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value "x 0 5 y"}
{:process 0, :type :invoke, :f :put, :key "1", :value "x 0 2 y"}
{:process 0, :type :ok, :f :put, :key "1", :value "x 0 2 y"}
{:process 0, :type :invoke, :f :get, :key "6", :value nil}
{:process 0, :type :ok, :f :get, :key "6", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 3 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 3 y"}
{:process 0, :type :invoke, :f :append, :key "3", :value "x 0 4 y"}
{:process 0, :type :ok, :f :append, :key "3", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "7", :value "x 0 0 y"}
{:process 0, :type :invoke, :f :append, :key "3", :value "x 0 5 y"}
{:process 0, :type :ok, :f :append, :key "3", :value "x 0 5 y"}
{:process 0, :type :invoke, :f :append, :key "6", :value "x 0 6 y"}
{:process 0, :type :ok, :f :append, :key "6", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :append, :key "4", :value "x 0 7 y"}
{:process 0, :type :ok, :f :append, :key "4", :value "x 0 7 y"}
{:process 0, :type :invoke, :f :append, :key "6", :value "x 0 8 y"}
{:process 0, :type :ok, :f :append, :key "6", :value "x 0 8 y"}
{:process 0, :type :invoke, :f :append, :key "3", :value "x 0 9 y"}
{:process 0, :type :ok, :f :append, :key "3", :value "x 0 9 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value "x 0 7 y"}
{:process 0, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "7", :value "x 0 0 yx 0 3 y"}
{:process 0, :type :invoke, :f :put, :key "2", :value "x 0 10 y"}
{:process 0, :type :ok, :f :put, :key "2", :value "x 0 10 y"}

================================================
FILE: courses/dss/linearizability/test_data/c01-ok.txt
================================================
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 0 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 0 y"}
{:process 0, :type :invoke, :f :append, :key "4", :value "x 0 1 y"}
{:process 0, :type :ok, :f :append, :key "4", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :append, :key "9", :value "x 0 2 y"}
{:process 0, :type :ok, :f :append, :key "9", :value "x 0 2 y"}
{:process 0, :type :invoke, :f :append, :key "4", :value "x 0 3 y"}
{:process 0, :type :ok, :f :append, :key "4", :value "x 0 3 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value ""}
{:process 0, :type :invoke, :f :get, :key "0", :value nil}
{:process 0, :type :ok, :f :get, :key "0", :value "x 0 0 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 4 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "7", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :append, :key "9", :value "x 0 5 y"}
{:process 0, :type :ok, :f :append, :key "9", :value "x 0 5 y"}
{:process 0, :type :invoke, :f :get, :key "9", :value nil}
{:process 0, :type :ok, :f :get, :key "9", :value "x 0 2 yx 0 5 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 6 y"}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 7 y"}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 7 y"}
{:process 0, :type :invoke, :f :get, :key "1", :value nil}
{:process 0, :type :ok, :f :get, :key "1", :value ""}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 8 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 8 y"}
{:process 0, :type :invoke, :f :put, :key "9", :value "x 0 9 y"}
{:process 0, :type :ok, :f :put, :key "9", :value "x 0 9 y"}
{:process 0, :type :invoke, :f :get, :key "8", :value nil}
{:process 0, :type :ok, :f :get, :key "8", :value ""}
{:process 0, :type :invoke, :f :get, :key "8", :value nil}
{:process 0, :type :ok, :f :get, :key "8", :value ""}
{:process 0, :type :invoke, :f :get, :key "9", :value nil}
{:process 0, :type :ok, :f :get, :key "9", :value "x 0 9 y"}
{:process 0, :type :invoke, :f :append, :key "1", :value "x 0 10 y"}
{:process 0, :type :ok, :f :append, :key "1", :value "x 0 10 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 11 y"}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 11 y"}
{:process 0, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "7", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "7", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :append, :key "5", :value "x 0 12 y"}
{:process 0, :type :ok, :f :append, :key "5", :value "x 0 12 y"}
{:process 0, :type :invoke, :f :get, :key "6", :value nil}
{:process 0, :type :ok, :f :get, :key "6", :value ""}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value "x 0 12 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 0 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 0 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value "x 0 12 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 1 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 2 y"}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 2 y"}
{:process 0, :type :invoke, :f :get, :key "8", :value nil}
{:process 0, :type :ok, :f :get, :key "8", :value ""}
{:process 0, :type :invoke, :f :get, :key "9", :value nil}
{:process 0, :type :ok, :f :get, :key "9", :value "x 0 9 y"}
{:process 0, :type :invoke, :f :append, :key "8", :value "x 0 3 y"}
{:process 0, :type :ok, :f :append, :key "8", :value "x 0 3 y"}
{:process 0, :type :invoke, :f :append, :key "5", :value "x 0 4 y"}
{:process 0, :type :ok, :f :append, :key "5", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value "x 0 12 yx 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value "x 0 12 yx 0 4 y"}
{:process 0, :type :invoke, :f :append, :key "1", :value "x 0 5 y"}
{:process 0, :type :ok, :f :append, :key "1", :value "x 0 5 y"}
{:process 0, :type :invoke, :f :append, :key "3", :value "x 0 6 y"}
{:process 0, :type :ok, :f :append, :key "3", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 7 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 7 y"}
{:process 0, :type :invoke, :f :get, :key "0", :value nil}
{:process 0, :type :ok, :f :get, :key "0", :value "x 0 0 yx 0 8 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 8 y"}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 8 y"}
{:process 0, :type :invoke, :f :append, :key "4", :value "x 0 9 y"}
{:process 0, :type :ok, :f :append, :key "4", :value "x 0 9 y"}
{:process 0, :type :invoke, :f :put, :key "4", :value "x 0 10 y"}
{:process 0, :type :ok, :f :put, :key "4", :value "x 0 10 y"}
{:process 0, :type :invoke, :f :get, :key "1", :value nil}
{:process 0, :type :ok, :f :get, :key "1", :value "x 0 10 yx 0 5 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 11 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 11 y"}
{:process 0, :type :invoke, :f :append, :key "4", :value "x 0 12 y"}
{:process 0, :type :ok, :f :append, :key "4", :value "x 0 12 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 13 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 13 y"}
{:process 0, :type :invoke, :f :append, :key "5", :value "x 0 14 y"}
{:process 0, :type :ok, :f :append, :key "5", :value "x 0 14 y"}
{:process 0, :type :invoke, :f :get, :key "8", :value nil}
{:process 0, :type :ok, :f :get, :key "8", :value "x 0 3 y"}
{:process 0, :type :invoke, :f :get, :key "3", :value nil}
{:process 0, :type :ok, :f :get, :key "3", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :get, :key "3", :value nil}
{:process 0, :type :ok, :f :get, :key "3", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "7", :value "x 0 4 yx 0 0 yx 0 1 yx 0 7 yx 0 11 yx 0 13 y"}
{:process 0, :type :invoke, :f :append, :key "5", :value "x 0 15 y"}
{:process 0, :type :ok, :f :append, :key "5", :value "x 0 15 y"}
{:process 0, :type :invoke, :f :get, :key "3", :value nil}
{:process 0, :type :ok, :f :get, :key "3", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value "x 0 6 yx 0 7 yx 0 11 yx 0 2 yx 0 8 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 16 y"}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 16 y"}
{:process 0, :type :invoke, :f :append, :key "5", :value "x 0 17 y"}
{:process 0, :type :ok, :f :append, :key "5", :value "x 0 17 y"}
{:process 0, :type :invoke, :f :append, :key "6", :value "x 0 18 y"}
{:process 0, :type :ok, :f :append, :key "6", :value "x 0 18 y"}
{:process 0, :type :invoke, :f :append, :key "3", :value "x 0 19 y"}
{:process 0, :type :ok, :f :append, :key "3", :value "x 0 19 y"}

================================================
FILE: courses/dss/linearizability/test_data/c10-bad.txt
================================================
{:process 9, :type :invoke, :f :append, :key "0", :value "x 9 0 y"}
{:process 4, :type :invoke, :f :append, :key "1", :value "x 4 0 y"}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 0 y"}
{:process 1, :type :invoke, :f :get, :key "9", :value nil}
{:process 2, :type :invoke, :f :append, :key "9", :value "x 2 0 y"}
{:process 6, :type :invoke, :f :append, :key "9", :value "x 6 0 y"}
{:process 3, :type :invoke, :f :append, :key "1", :value "x 3 0 y"}
{:process 5, :type :invoke, :f :get, :key "1", :value nil}
{:process 7, :type :invoke, :f :get, :key "9", :value nil}
{:process 8, :type :invoke, :f :get, :key "6", :value nil}
{:process 5, :type :ok, :f :get, :key "1", :value ""}
{:process 5, :type :invoke, :f :put, :key "8", :value "x 5 0 y"}
{:process 1, :type :ok, :f :get, :key "9", :value ""}
{:process 1, :type :invoke, :f :put, :key "8", :value "x 1 0 y"}
{:process 7, :type :ok, :f :get, :key "9", :value ""}
{:process 7, :type :invoke, :f :append, :key "4", :value "x 7 0 y"}
{:process 8, :type :ok, :f :get, :key "6", :value ""}
{:process 8, :type :invoke, :f :append, :key "0", :value "x 8 0 y"}
{:process 3, :type :ok, :f :append, :key "1", :value "x 3 0 y"}
{:process 3, :type :invoke, :f :get, :key "4", :value nil}
{:process 3, :type :ok, :f :get, :key "4", :value ""}
{:process 3, :type :invoke, :f :append, :key "1", :value "x 3 1 y"}
{:process 9, :type :ok, :f :append, :key "0", :value "x 9 0 y"}
{:process 9, :type :invoke, :f :append, :key "3", :value "x 9 1 y"}
{:process 3, :type :ok, :f :append, :key "1", :value "x 3 1 y"}
{:process 3, :type :invoke, :f :get, :key "6", :value nil}
{:process 9, :type :ok, :f :append, :key "3", :value "x 9 1 y"}
{:process 9, :type :invoke, :f :get, :key "9", :value nil}
{:process 3, :type :ok, :f :get, :key "6", :value ""}
{:process 3, :type :invoke, :f :put, :key "8", :value "x 3 2 y"}
{:process 3, :type :ok, :f :put, :key "8", :value "x 3 2 y"}
{:process 3, :type :invoke, :f :append, :key "5", :value "x 3 3 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 0 y"}
{:process 0, :type :invoke, :f :put, :key "2", :value "x 0 1 y"}
{:process 0, :type :ok, :f :put, :key "2", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :append, :key "6", :value "x 0 2 y"}
{:process 9, :type :ok, :f :get, :key "9", :value ""}
{:process 9, :type :invoke, :f :append, :key "7", :value "x 9 2 y"}
{:process 8, :type :ok, :f :append, :key "0", :value "x 8 0 y"}
{:process 8, :type :invoke, :f :append, :key "2", :value "x 8 1 y"}
{:process 6, :type :ok, :f :append, :key "9", :value "x 6 0 y"}
{:process 6, :type :invoke, :f :get, :key "1", :value nil}
{:process 5, :type :ok, :f :put, :key "8", :value "x 5 0 y"}
{:process 5, :type :invoke, :f :append, :key "8", :value "x 5 1 y"}
{:process 1, :type :ok, :f :put, :key "8", :value "x 1 0 y"}
{:process 1, :type :invoke, :f :get, :key "2", :value nil}
{:process 1, :type :ok, :f :get, :key "2", :value "x 0 1 y"}
{:process 1, :type :invoke, :f :get, :key "1", :value nil}
{:process 5, :type :ok, :f :append, :key "8", :value "x 5 1 y"}
{:process 5, :type :invoke, :f :get, :key "2", :value nil}
{:process 1, :type :ok, :f :get, :key "1", :value "x 3 0 yx 3 1 yx 4 0 y"}
{:process 1, :type :invoke, :f :get, :key "3", :value nil}
{:process 5, :type :ok, :f :get, :key "2", :value "x 0 1 y"}
{:process 5, :type :invoke, :f :append, :key "7", :value "x 5 2 y"}
{:process 1, :type :ok, :f :get, :key "3", :value "x 9 1 y"}
{:process 1, :type :invoke, :f :append, :key "2", :value "x 1 1 y"}
{:process 6, :type :ok, :f :get, :key "1", :value "x 3 0 yx 3 1 y"}
{:process 6, :type :invoke, :f :append, :key "5", :value "x 6 1 y"}
{:process 2, :type :ok, :f :append, :key "9", :value "x 2 0 y"}
{:process 2, :type :invoke, :f :get, :key "8", :value nil}
{:process 2, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 y"}
{:process 2, :type :invoke, :f :get, :key "2", :value nil}
{:process 9, :type :ok, :f :append, :key "7", :value "x 9 2 y"}
{:process 9, :type :invoke, :f :get, :key "8", :value nil}
{:process 9, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 y"}
{:process 9, :type :invoke, :f :get, :key "7", :value nil}
{:process 9, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 y"}
{:process 9, :type :invoke, :f :append, :key "2", :value "x 9 3 y"}
{:process 9, :type :ok, :f :append, :key "2", :value "x 9 3 y"}
{:process 9, :type :invoke, :f :append, :key "2", :value "x 9 4 y"}
{:process 9, :type :ok, :f :append, :key "2", :value "x 9 4 y"}
{:process 9, :type :invoke, :f :append, :key "2", :value "x 9 5 y"}
{:process 9, :type :ok, :f :append, :key "2", :value "x 9 5 y"}
{:process 9, :type :invoke, :f :get, :key "4", :value nil}
{:process 0, :type :ok, :f :append, :key "6", :value "x 0 2 y"}
{:process 8, :type :ok, :f :append, :key "2", :value "x 8 1 y"}
{:process 8, :type :invoke, :f :get, :key "3", :value nil}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value "x 3 3 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 7, :type :ok, :f :append, :key "4", :value "x 7 0 y"}
{:process 7, :type :invoke, :f :append, :key "0", :value "x 7 1 y"}
{:process 0, :type :ok, :f :get, :key "5", :value "x 3 3 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 3 y"}
{:process 9, :type :ok, :f :get, :key "4", :value "x 7 0 y"}
{:process 9, :type :invoke, :f :get, :key "5", :value nil}
{:process 2, :type :ok, :f :get, :key "2", :value "x 0 1 yx 9 3 yx 9 4 yx 9 5 yx 8 1 y"}
{:process 2, :type :invoke, :f :get, :key "2", :value nil}
{:process 9, :type :ok, :f :get, :key "5", :value "x 3 3 y"}
{:process 9, :type :invoke, :f :get, :key "1", :value nil}
{:process 9, :type :ok, :f :get, :key "1", :value "x 3 0 yx 3 1 y"}
{:process 9, :type :invoke, :f :append, :key "3", :value "x 9 6 y"}
{:process 7, :type :ok, :f :append, :key "0", :value "x 7 1 y"}
{:process 7, :type :invoke, :f :append, :key "5", :value "x 7 2 y"}
{:process 2, :type :ok, :f :get, :key "2", :value "x 0 1 yx 9 3 yx 9 4 yx 9 5 yx 8 1 y"}
{:process 2, :type :invoke, :f :get, :key "3", :value nil}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 3 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 4 y"}
{:process 7, :type :ok, :f :append, :key "5", :value "x 7 2 y"}
{:process 7, :type :invoke, :f :append, :key "6", :value "x 7 3 y"}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "9", :value nil}
{:process 8, :type :ok, :f :get, :key "3", :value "x 9 1 y"}
{:process 8, :type :invoke, :f :append, :key "1", :value "x 8 2 y"}
{:process 0, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 y"}
{:process 0, :type :invoke, :f :append, :key "4", :value "x 0 5 y"}
{:process 7, :type :ok, :f :append, :key "6", :value "x 7 3 y"}
{:process 7, :type :invoke, :f :put, :key "4", :value "x 7 4 y"}
{:process 2, :type :ok, :f :get, :key "3", :value "x 9 1 y"}
{:process 2, :type :invoke, :f :get, :key "9", :value nil}
{:process 2, :type :ok, :f :get, :key "9", :value ""}
{:process 2, :type :invoke, :f :append, :key "6", :value "x 2 1 y"}
{:process 0, :type :ok, :f :append, :key "4", :value "x 0 5 y"}
{:process 0, :type :invoke, :f :get, :key "8", :value nil}
{:process 0, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 y"}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 6 y"}
{:process 9, :type :ok, :f :append, :key "3", :value "x 9 6 y"}
{:process 9, :type :invoke, :f :get, :key "0", :value nil}
{:process 9, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 8 0 yx 7 1 y"}
{:process 9, :type :invoke, :f :append, :key "7", :value "x 9 7 y"}
{:process 8, :type :ok, :f :append, :key "1", :value "x 8 2 y"}
{:process 8, :type :invoke, :f :append, :key "5", :value "x 8 3 y"}
{:process 9, :type :ok, :f :append, :key "7", :value "x 9 7 y"}
{:process 9, :type :invoke, :f :append, :key "2", :value "x 9 8 y"}
{:process 8, :type :ok, :f :append, :key "5", :value "x 8 3 y"}
{:process 8, :type :invoke, :f :append, :key "2", :value "x 8 4 y"}
{:process 9, :type :ok, :f :append, :key "2", :value "x 9 8 y"}
{:process 8, :type :ok, :f :append, :key "2", :value "x 8 4 y"}
{:process 9, :type :invoke, :f :get, :key "9", :value nil}
{:process 8, :type :invoke, :f :get, :key "6", :value nil}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :get, :key "8", :value nil}
{:process 7, :type :ok, :f :put, :key "4", :value "x 7 4 y"}
{:process 7, :type :invoke, :f :append, :key "8", :value "x 7 5 y"}
{:process 0, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 7 y"}
{:process 7, :type :ok, :f :append, :key "8", :value "x 7 5 y"}
{:process 7, :type :invoke, :f :append, :key "0", :value "x 7 6 y"}
{:process 7, :type :ok, :f :append, :key "0", :value "x 7 6 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 7 y"}
{:process 7, :type :invoke, :f :get, :key "0", :value nil}
{:process 0, :type :invoke, :f :append, :key "6", :value "x 0 8 y"}
{:process 7, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 8 0 yx 7 1 yx 0 6 yx 7 6 y"}
{:process 7, :type :invoke, :f :append, :key "0", :value "x 7 7 y"}
{:process 0, :type :ok, :f :append, :key "6", :value "x 0 8 y"}
{:process 0, :type :invoke, :f :get, :key "4", :value nil}
{:process 9, :type :ok, :f :get, :key "9", :value ""}
{:process 9, :type :invoke, :f :append, :key "1", :value "x 9 9 y"}
{:process 8, :type :ok, :f :get, :key "6", :value "x 0 2 y"}
{:process 8, :type :invoke, :f :get, :key "3", :value nil}
{:process 8, :type :ok, :f :get, :key "3", :value "x 9 1 y"}
{:process 8, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "4", :value "x 7 4 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 8, :type :ok, :f :get, :key "7", :value ""}
{:process 8, :type :invoke, :f :get, :key "0", :value nil}
{:process 8, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 8 0 y"}
{:process 8, :type :invoke, :f :get, :key "7", :value nil}
{:process 8, :type :ok, :f :get, :key "7", :value ""}
{:process 8, :type :invoke, :f :append, :key "3", :value "x 8 5 y"}
{:process 0, :type :ok, :f :get, :key "2", :value "x 0 1 yx 9 3 yx 9 4 yx 9 5 yx 8 1 yx 0 3 yx 0 4 yx 9 8 yx 8 4 y"}
{:process 0, :type :invoke, :f :get, :key "9", :value nil}
{:process 0, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 y"}
{:process 0, :type :invoke, :f :append, :key "9", :value "x 0 9 y"}
{:process 7, :type :ok, :f :append, :key "0", :value "x 7 7 y"}
{:process 7, :type :invoke, :f :append, :key "2", :value "x 7 8 y"}
{:process 0, :type :ok, :f :append, :key "9", :value "x 0 9 y"}
{:process 0, :type :invoke, :f :get, :key "0", :value nil}
{:process 0, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 8 0 yx 7 1 yx 0 6 yx 7 6 yx 7 7 y"}
{:process 0, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 y"}
{:process 0, :type :invoke, :f :get, :key "7", :value nil}
{:process 0, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value "x 0 1 yx 9 3 yx 9 4 yx 9 5 yx 8 1 yx 0 3 yx 0 4 yx 9 8 yx 8 4 y"}
{:process 0, :type :invoke, :f :get, :key "1", :value nil}
{:process 0, :type :ok, :f :get, :key "1", :value "x 3 0 yx 3 1 yx 4 0 yx 8 2 y"}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 10 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 10 y"}
{:process 0, :type :invoke, :f :append, :key "3", :value "x 0 11 y"}
{:process 6, :type :ok, :f :append, :key "5", :value "x 6 1 y"}
{:process 6, :type :invoke, :f :get, :key "3", :value nil}
{:process 6, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 y"}
{:process 6, :type :invoke, :f :append, :key "3", :value "x 6 2 y"}
{:process 0, :type :ok, :f :append, :key "3", :value "x 0 11 y"}
{:process 0, :type :invoke, :f :append, :key "4", :value "x 0 12 y"}
{:process 7, :type :ok, :f :append, :key "2", :value "x 7 8 y"}
{:process 7, :type :invoke, :f :append, :key "6", :value "x 7 9 y"}
{:process 6, :type :ok, :f :append, :key "3", :value "x 6 2 y"}
{:process 6, :type :invoke, :f :get, :key "2", :value nil}
{:process 7, :type :ok, :f :append, :key "6", :value "x 7 9 y"}
{:process 7, :type :invoke, :f :get, :key "9", :value nil}
{:process 0, :type :ok, :f :append, :key "4", :value "x 0 12 y"}
{:process 0, :type :invoke, :f :get, :key "6", :value nil}
{:process 1, :type :ok, :f :append, :key "2", :value "x 1 1 y"}
{:process 1, :type :invoke, :f :put, :key "1", :value "x 1 2 y"}
{:process 0, :type :ok, :f :get, :key "6", :value "x 0 2 yx 7 3 yx 0 8 yx 7 9 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 y"}
{:process 0, :type :invoke, :f :append, :key "9", :value "x 0 13 y"}
{:process 1, :type :ok, :f :put, :key "1", :value "x 1 2 y"}
{:process 1, :type :invoke, :f :get, :key "4", :value nil}
{:process 1, :type :ok, :f :get, :key "4", :value "x 7 4 yx 0 12 y"}
{:process 1, :type :invoke, :f :get, :key "3", :value nil}
{:process 0, :type :ok, :f :append, :key "9", :value "x 0 13 y"}
{:process 0, :type :invoke, :f :append, :key "9", :value "x 0 14 y"}
{:process 1, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 y"}
{:process 1, :type :invoke, :f :append, :key "5", :value "x 1 3 y"}
{:process 6, :type :ok, :f :get, :key "2", :value "x 0 1 yx 9 3 yx 9 4 yx 9 5 yx 8 1 yx 0 3 yx 0 4 yx 9 8 yx 8 4 yx 7 8 yx 1 1 y"}
{:process 6, :type :invoke, :f :get, :key "4", :value nil}
{:process 6, :type :ok, :f :get, :key "4", :value "x 7 4 yx 0 12 y"}
{:process 6, :type :invoke, :f :get, :key "9", :value nil}
{:process 7, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 yx 0 9 yx 0 13 y"}
{:process 7, :type :invoke, :f :get, :key "5", :value nil}
{:process 7, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 y"}
{:process 7, :type :invoke, :f :append, :key "5", :value "x 7 10 y"}
{:process 6, :type :ok, :f :get, :key "9", :value ""}
{:process 6, :type :invoke, :f :append, :key "0", :value "x 6 3 y"}
{:process 9, :type :ok, :f :append, :key "1", :value "x 9 9 y"}
{:process 9, :type :invoke, :f :put, :key "6", :value "x 9 10 y"}
{:process 8, :type :ok, :f :append, :key "3", :value "x 8 5 y"}
{:process 8, :type :invoke, :f :get, :key "6", :value nil}
{:process 8, :type :ok, :f :get, :key "6", :value "x 9 10 y"}
{:process 8, :type :invoke, :f :append, :key "6", :value "x 8 6 y"}
{:process 8, :type :ok, :f :append, :key "6", :value "x 8 6 y"}
{:process 8, :type :invoke, :f :get, :key "0", :value nil}
{:process 8, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 8 0 yx 7 1 yx 0 6 yx 7 6 yx 7 7 yx 0 10 y"}
{:process 8, :type :invoke, :f :append, :key "1", :value "x 8 7 y"}
{:process 8, :type :ok, :f :append, :key "1", :value "x 8 7 y"}
{:process 8, :type :invoke, :f :append, :key "3", :value "x 8 8 y"}
{:process 8, :type :ok, :f :append, :key "3", :value "x 8 8 y"}
{:process 8, :type :invoke, :f :get, :key "6", :value nil}
{:process 8, :type :ok, :f :get, :key "6", :value "x 9 10 yx 8 6 y"}
{:process 8, :type :invoke, :f :append, :key "6", :value "x 8 9 y"}
{:process 8, :type :ok, :f :append, :key "6", :value "x 8 9 y"}
{:process 8, :type :invoke, :f :append, :key "5", :value "x 8 10 y"}
{:process 7, :type :ok, :f :append, :key "5", :value "x 7 10 y"}
{:process 7, :type :invoke, :f :get, :key "1", :value nil}
{:process 7, :type :ok, :f :get, :key "1", :value "x 1 2 yx 9 9 yx 8 7 y"}
{:process 7, :type :invoke, :f :get, :key "5", :value nil}
{:process 4, :type :ok, :f :append, :key "1", :value "x 4 0 y"}
{:process 4, :type :invoke, :f :append, :key "1", :value "x 4 1 y"}
{:process 0, :type :ok, :f :append, :key "9", :value "x 0 14 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 7, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 y"}
{:process 7, :type :invoke, :f :get, :key "0", :value nil}
{:process 4, :type :ok, :f :append, :key "1", :value "x 4 1 y"}
{:process 4, :type :invoke, :f :append, :key "4", :value "x 4 2 y"}
{:process 7, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 8 0 yx 7 1 yx 0 6 yx 7 6 yx 7 7 yx 0 10 yx 6 3 y"}
{:process 7, :type :invoke, :f :append, :key "0", :value "x 7 11 y"}
{:process 0, :type :ok, :f :get, :key "2", :value "x 0 1 yx 9 3 yx 9 4 yx 9 5 yx 8 1 yx 0 3 yx 0 4 yx 9 8 yx 8 4 yx 7 8 yx 1 1 y"}
{:process 0, :type :invoke, :f :append, :key "4", :value "x 0 15 y"}
{:process 1, :type :ok, :f :append, :key "5", :value "x 1 3 y"}
{:process 1, :type :invoke, :f :get, :key "4", :value nil}
{:process 1, :type :ok, :f :get, :key "4", :value "x 7 4 yx 0 12 y"}
{:process 1, :type :invoke, :f :put, :key "1", :value "x 1 4 y"}
{:process 2, :type :ok, :f :append, :key "6", :value "x 2 1 y"}
{:process 2, :type :invoke, :f :append, :key "2", :value "x 2 2 y"}
{:process 0, :type :ok, :f :append, :key "4", :value "x 0 15 y"}
{:process 0, :type :invoke, :f :append, :key "1", :value "x 0 16 y"}
{:process 7, :type :ok, :f :append, :key "0", :value "x 7 11 y"}
{:process 7, :type :invoke, :f :get, :key "4", :value nil}
{:process 4, :type :ok, :f :append, :key "4", :value "x 4 2 y"}
{:process 4, :type :invoke, :f :append, :key "8", :value "x 4 3 y"}
{:process 1, :type :ok, :f :put, :key "1", :value "x 1 4 y"}
{:process 1, :type :invoke, :f :append, :key "0", :value "x 1 5 y"}
{:process 0, :type :ok, :f :append, :key "1", :value "x 0 16 y"}
{:process 0, :type :invoke, :f :append, :key "1", :value "x 0 17 y"}
{:process 7, :type :ok, :f :get, :key "4", :value "x 7 4 yx 0 12 yx 0 15 yx 4 2 y"}
{:process 7, :type :invoke, :f :append, :key "4", :value "x 7 12 y"}
{:process 4, :type :ok, :f :append, :key "8", :value "x 4 3 y"}
{:process 4, :type :invoke, :f :get, :key "5", :value nil}
{:process 4, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 y"}
{:process 4, :type :invoke, :f :append, :key "2", :value "x 4 4 y"}
{:process 9, :type :ok, :f :put, :key "6", :value "x 9 10 y"}
{:process 9, :type :invoke, :f :get, :key "5", :value nil}
{:process 9, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 y"}
{:process 9, :type :invoke, :f :get, :key "7", :value nil}
{:process 9, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 y"}
{:process 9, :type :invoke, :f :get, :key "5", :value nil}
{:process 8, :type :ok, :f :append, :key "5", :value "x 8 10 y"}
{:process 8, :type :invoke, :f :append, :key "7", :value "x 8 11 y"}
{:process 8, :type :ok, :f :append, :key "7", :value "x 8 11 y"}
{:process 8, :type :invoke, :f :put, :key "4", :value "x 8 12 y"}
{:process 8, :type :ok, :f :put, :key "4", :value "x 8 12 y"}
{:process 8, :type :invoke, :f :put, :key "0", :value "x 8 13 y"}
{:process 6, :type :ok, :f :append, :key "0", :value "x 6 3 y"}
{:process 6, :type :invoke, :f :append, :key "3", :value "x 6 4 y"}
{:process 6, :type :ok, :f :append, :key "3", :value "x 6 4 y"}
{:process 6, :type :invoke, :f :append, :key "6", :value "x 6 5 y"}
{:process 9, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 y"}
{:process 9, :type :invoke, :f :get, :key "0", :value nil}
{:process 9, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 8 0 yx 7 1 yx 0 6 yx 7 6 yx 7 7 yx 0 10 yx 6 3 yx 7 11 yx 1 5 y"}
{:process 9, :type :invoke, :f :get, :key "8", :value nil}
{:process 6, :type :ok, :f :append, :key "6", :value "x 6 5 y"}
{:process 6, :type :invoke, :f :get, :key "9", :value nil}
{:process 6, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 yx 0 9 yx 0 13 yx 0 14 y"}
{:process 6, :type :invoke, :f :get, :key "1", :value nil}
{:process 2, :type :ok, :f :append, :key "2", :value "x 2 2 y"}
{:process 2, :type :invoke, :f :append, :key "9", :value "x 2 3 y"}
{:process 9, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 yx 7 5 yx 4 3 y"}
{:process 9, :type :invoke, :f :get, :key "5", :value nil}
{:process 9, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 y"}
{:process 9, :type :invoke, :f :get, :key "2", :value nil}
{:process 9, :type :ok, :f :get, :key "2", :value "x 0 1 yx 9 3 yx 9 4 yx 9 5 yx 8 1 yx 0 3 yx 0 4 yx 9 8 yx 8 4 yx 7 8 yx 1 1 y"}
{:process 9, :type :invoke, :f :append, :key "8", :value "x 9 11 y"}
{:process 6, :type :ok, :f :get, :key "1", :value "x 1 4 yx 0 16 yx 0 17 y"}
{:process 6, :type :invoke, :f :get, :key "7", :value nil}
{:process 6, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 y"}
{:process 6, :type :invoke, :f :get, :key "1", :value nil}
{:process 6, :type :ok, :f :get, :key "1", :value "x 1 4 yx 0 16 yx 0 17 y"}
{:process 6, :type :invoke, :f :put, :key "2", :value "x 6 6 y"}
{:process 7, :type :ok, :f :append, :key "4", :value "x 7 12 y"}
{:process 7, :type :invoke, :f :append, :key "4", :value "x 7 13 y"}
{:process 7, :type :ok, :f :append, :key "4", :value "x 7 13 y"}
{:process 7, :type :invoke, :f :get, :key "1", :value nil}
{:process 1, :type :ok, :f :append, :key "0", :value "x 1 5 y"}
{:process 1, :type :invoke, :f :append, :key "0", :value "x 1 6 y"}
{:process 7, :type :ok, :f :get, :key "1", :value "x 1 4 yx 0 16 yx 0 17 y"}
{:process 7, :type :invoke, :f :append, :key "9", :value "x 7 14 y"}
{:process 7, :type :ok, :f :append, :key "9", :value "x 7 14 y"}
{:process 7, :type :invoke, :f :get, :key "2", :value nil}
{:process 1, :type :ok, :f :append, :key "0", :value "x 1 6 y"}
{:process 1, :type :invoke, :f :get, :key "0", :value nil}
{:process 1, :type :ok, :f :get, :key "0", :value "x 8 13 yx 1 6 y"}
{:process 1, :type :invoke, :f :get, :key "2", :value nil}
{:process 1, :type :ok, :f :get, :key "2", :value "x 0 1 yx 9 3 yx 9 4 yx 9 5 yx 8 1 yx 0 3 yx 0 4 yx 9 8 yx 8 4 yx 7 8 yx 1 1 yx 2 2 y"}
{:process 1, :type :invoke, :f :append, :key "9", :value "x 1 7 y"}
{:process 7, :type :ok, :f :get, :key "2", :value "x 0 1 yx 9 3 yx 9 4 yx 9 5 yx 8 1 yx 0 3 yx 0 4 yx 9 8 yx 8 4 yx 7 8 yx 1 1 yx 2 2 y"}
{:process 7, :type :invoke, :f :append, :key "1", :value "x 7 15 y"}
{:process 9, :type :ok, :f :append, :key "8", :value "x 9 11 y"}
{:process 9, :type :invoke, :f :append, :key "4", :value "x 9 12 y"}
{:process 9, :type :ok, :f :append, :key "4", :value "x 9 12 y"}
{:process 9, :type :invoke, :f :get, :key "9", :value nil}
{:process 9, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 yx 0 9 yx 0 13 yx 0 14 yx 7 14 y"}
{:process 9, :type :invoke, :f :append, :key "5", :value "x 9 13 y"}
{:process 1, :type :ok, :f :append, :key "9", :value "x 1 7 y"}
{:process 7, :type :ok, :f :append, :key "1", :value "x 7 15 y"}
{:process 4, :type :ok, :f :append, :key "2", :value "x 4 4 y"}
{:process 5, :type :ok, :f :append, :key "7", :value "x 5 2 y"}
{:process 9, :type :ok, :f :append, :key "5", :value "x 9 13 y"}
{:process 2, :type :ok, :f :append, :key "9", :value "x 2 3 y"}
{:process 3, :type :ok, :f :append, :key "5", :value "x 3 3 y"}
{:process 8, :type :ok, :f :put, :key "0", :value "x 8 13 y"}
{:process 6, :type :ok, :f :put, :key "2", :value "x 6 6 y"}
{:process 0, :type :ok, :f :append, :key "1", :value "x 0 17 y"}
{:process 1, :type :invoke, :f :get, :key "2", :value nil}
{:process 9, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :invoke, :f :get, :key "8", :value nil}
{:process 2, :type :invoke, :f :append, :key "9", :value "x 2 0 y"}
{:process 3, :type :invoke, :f :append, :key "9", :value "x 3 0 y"}
{:process 6, :type :invoke, :f :get, :key "7", :value nil}
{:process 4, :type :invoke, :f :append, :key "9", :value "x 4 0 y"}
{:process 7, :type :invoke, :f :append, :key "9", :value "x 7 0 y"}
{:process 8, :type :invoke, :f :append, :key "5", :value "x 8 0 y"}
{:process 5, :type :invoke, :f :append, :key "3", :value "x 5 0 y"}
{:process 6, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 y"}
{:process 6, :type :invoke, :f :get, :key "5", :value nil}
{:process 9, :type :ok, :f :get, :key "2", :value "x 6 6 y"}
{:process 9, :type :invoke, :f :get, :key "7", :value nil}
{:process 1, :type :ok, :f :get, :key "2", :value "x 6 6 y"}
{:process 1, :type :invoke, :f :append, :key "1", :value "x 1 0 y"}
{:process 6, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 yx 9 13 y"}
{:process 6, :type :invoke, :f :get, :key "7", :value nil}
{:process 7, :type :ok, :f :append, :key "9", :value "x 7 0 y"}
{:process 7, :type :invoke, :f :get, :key "5", :value nil}
{:process 7, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 yx 9 13 y"}
{:process 7, :type :invoke, :f :get, :key "2", :value nil}
{:process 9, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 y"}
{:process 9, :type :invoke, :f :get, :key "1", :value nil}
{:process 6, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 y"}
{:process 6, :type :invoke, :f :get, :key "9", :value nil}
{:process 9, :type :ok, :f :get, :key "1", :value "x 1 4 yx 0 16 yx 0 17 yx 7 15 y"}
{:process 9, :type :invoke, :f :append, :key "5", :value "x 9 0 y"}
{:process 6, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 yx 0 9 yx 0 13 yx 0 14 yx 7 14 yx 1 7 yx 2 3 yx 7 0 y"}
{:process 6, :type :invoke, :f :append, :key "2", :value "x 6 0 y"}
{:process 7, :type :ok, :f :get, :key "2", :value "x 6 6 y"}
{:process 7, :type :invoke, :f :put, :key "1", :value "x 7 1 y"}
{:process 7, :type :ok, :f :put, :key "1", :value "x 7 1 y"}
{:process 7, :type :invoke, :f :append, :key "7", :value "x 7 2 y"}
{:process 6, :type :ok, :f :append, :key "2", :value "x 6 0 y"}
{:process 6, :type :invoke, :f :get, :key "4", :value nil}
{:process 6, :type :ok, :f :get, :key "4", :value "x 8 12 yx 7 13 yx 9 12 y"}
{:process 6, :type :invoke, :f :put, :key "0", :value "x 6 1 y"}
{:process 4, :type :ok, :f :append, :key "9", :value "x 4 0 y"}
{:process 4, :type :invoke, :f :get, :key "7", :value nil}
{:process 6, :type :ok, :f :put, :key "0", :value "x 6 1 y"}
{:process 6, :type :invoke, :f :append, :key "7", :value "x 6 2 y"}
{:process 6, :type :ok, :f :append, :key "7", :value "x 6 2 y"}
{:process 6, :type :invoke, :f :append, :key "2", :value "x 6 3 y"}
{:process 4, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 yx 7 2 yx 6 2 y"}
{:process 4, :type :invoke, :f :append, :key "3", :value "x 4 1 y"}
{:process 0, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 yx 7 5 yx 4 3 yx 9 11 y"}
{:process 0, :type :invoke, :f :get, :key "6", :value nil}
{:process 6, :type :ok, :f :append, :key "2", :value "x 6 3 y"}
{:process 6, :type :invoke, :f :append, :key "9", :value "x 6 4 y"}
{:process 0, :type :ok, :f :get, :key "6", :value "x 9 10 yx 8 6 yx 8 9 yx 2 1 yx 6 5 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 0 y"}
{:process 6, :type :ok, :f :append, :key "9", :value "x 6 4 y"}
{:process 6, :type :invoke, :f :append, :key "5", :value "x 6 5 y"}
{:process 5, :type :ok, :f :append, :key "3", :value "x 5 0 y"}
{:process 5, :type :invoke, :f :get, :key "2", :value nil}
{:process 2, :type :ok, :f :append, :key "9", :value "x 2 0 y"}
{:process 2, :type :invoke, :f :append, :key "1", :value "x 2 1 y"}
{:process 5, :type :ok, :f :get, :key "2", :value "x 6 6 yx 6 0 yx 6 3 y"}
{:process 5, :type :invoke, :f :get, :key "0", :value nil}
{:process 5, :type :ok, :f :get, :key "0", :value "x 6 1 y"}
{:process 5, :type :invoke, :f :get, :key "0", :value nil}
{:process 5, :type :ok, :f :get, :key "0", :value "x 6 1 y"}
{:process 5, :type :invoke, :f :append, :key "9", :value "x 5 1 y"}
{:process 2, :type :ok, :f :append, :key "1", :value "x 2 1 y"}
{:process 2, :type :invoke, :f :append, :key "6", :value "x 2 2 y"}
{:process 5, :type :ok, :f :append, :key "9", :value "x 5 1 y"}
{:process 5, :type :invoke, :f :append, :key "1", :value "x 5 2 y"}
{:process 2, :type :ok, :f :append, :key "6", :value "x 2 2 y"}
{:process 2, :type :invoke, :f :get, :key "1", :value nil}
{:process 2, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 y"}
{:process 2, :type :invoke, :f :get, :key "7", :value nil}
{:process 2, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 yx 7 2 yx 6 2 y"}
{:process 2, :type :invoke, :f :get, :key "9", :value nil}
{:process 2, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 yx 0 9 yx 0 13 yx 0 14 yx 7 14 yx 1 7 yx 2 3 yx 7 0 yx 4 0 yx 6 4 yx 2 0 yx 5 1 y"}
{:process 2, :type :invoke, :f :get, :key "8", :value nil}
{:process 5, :type :ok, :f :append, :key "1", :value "x 5 2 y"}
{:process 5, :type :invoke, :f :append, :key "9", :value "x 5 3 y"}
{:process 5, :type :ok, :f :append, :key "9", :value "x 5 3 y"}
{:process 5, :type :invoke, :f :get, :key "6", :value nil}
{:process 2, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 yx 7 5 yx 4 3 yx 9 11 y"}
{:process 2, :type :invoke, :f :get, :key "3", :value nil}
{:process 2, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 y"}
{:process 2, :type :invoke, :f :get, :key "7", :value nil}
{:process 5, :type :ok, :f :get, :key "6", :value "x 9 10 yx 8 6 yx 8 9 yx 2 1 yx 6 5 yx 2 2 y"}
{:process 5, :type :invoke, :f :append, :key "4", :value "x 5 4 y"}
{:process 2, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 yx 7 2 yx 6 2 y"}
{:process 2, :type :invoke, :f :append, :key "5", :value "x 2 3 y"}
{:process 8, :type :ok, :f :append, :key "5", :value "x 8 0 y"}
{:process 8, :type :invoke, :f :get, :key "3", :value nil}
{:process 8, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 y"}
{:process 8, :type :invoke, :f :get, :key "5", :value nil}
{:process 8, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 yx 9 13 yx 8 0 y"}
{:process 8, :type :invoke, :f :append, :key "1", :value "x 8 1 y"}
{:process 8, :type :ok, :f :append, :key "1", :value "x 8 1 y"}
{:process 8, :type :invoke, :f :get, :key "7", :value nil}
{:process 8, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 yx 7 2 yx 6 2 y"}
{:process 8, :type :invoke, :f :get, :key "5", :value nil}
{:process 8, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 yx 9 13 yx 8 0 y"}
{:process 8, :type :invoke, :f :get, :key "9", :value nil}
{:process 8, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 yx 0 9 yx 0 13 yx 0 14 yx 7 14 yx 1 7 yx 2 3 yx 7 0 yx 4 0 yx 6 4 yx 2 0 yx 5 1 yx 5 3 yx 3 0 y"}
{:process 8, :type :invoke, :f :get, :key "8", :value nil}
{:process 8, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 yx 7 5 yx 4 3 yx 9 11 y"}
{:process 8, :type :invoke, :f :get, :key "3", :value nil}
{:process 8, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 y"}
{:process 8, :type :invoke, :f :get, :key "0", :value nil}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 0 y"}
{:process 0, :type :invoke, :f :put, :key "2", :value "x 0 1 y"}
{:process 8, :type :ok, :f :get, :key "0", :value "x 6 1 y"}
{:process 8, :type :invoke, :f :append, :key "4", :value "x 8 2 y"}
{:process 9, :type :ok, :f :append, :key "5", :value "x 9 0 y"}
{:process 9, :type :invoke, :f :get, :key "0", :value nil}
{:process 9, :type :ok, :f :get, :key "0", :value "x 6 1 y"}
{:process 9, :type :invoke, :f :get, :key "2", :value nil}
{:process 9, :type :ok, :f :get, :key "2", :value "x 6 6 yx 6 0 yx 6 3 yx 0 0 y"}
{:process 9, :type :invoke, :f :get, :key "2", :value nil}
{:process 9, :type :ok, :f :get, :key "2", :value "x 6 6 yx 6 0 yx 6 3 yx 0 0 y"}
{:process 9, :type :invoke, :f :append, :key "4", :value "x 9 1 y"}
{:process 0, :type :ok, :f :put, :key "2", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :append, :key "3", :value "x 0 2 y"}
{:process 6, :type :ok, :f :append, :key "5", :value "x 6 5 y"}
{:process 6, :type :invoke, :f :append, :key "2", :value "x 6 6 y"}
{:process 6, :type :ok, :f :append, :key "2", :value "x 6 6 y"}
{:process 6, :type :invoke, :f :get, :key "6", :value nil}
{:process 6, :type :ok, :f :get, :key "6", :value "x 9 10 yx 8 6 yx 8 9 yx 2 1 yx 6 5 yx 2 2 y"}
{:process 6, :type :invoke, :f :append, :key "7", :value "x 6 7 y"}
{:process 6, :type :ok, :f :append, :key "7", :value "x 6 7 y"}
{:process 6, :type :invoke, :f :append, :key "3", :value "x 6 8 y"}
{:process 6, :type :ok, :f :append, :key "3", :value "x 6 8 y"}
{:process 6, :type :invoke, :f :get, :key "7", :value nil}
{:process 6, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 yx 7 2 yx 6 2 yx 6 7 y"}
{:process 6, :type :invoke, :f :append, :key "5", :value "x 6 9 y"}
{:process 8, :type :ok, :f :append, :key "4", :value "x 8 2 y"}
{:process 8, :type :invoke, :f :append, :key "1", :value "x 8 3 y"}
{:process 6, :type :ok, :f :append, :key "5", :value "x 6 9 y"}
{:process 6, :type :invoke, :f :get, :key "6", :value nil}
{:process 6, :type :ok, :f :get, :key "6", :value "x 9 10 yx 8 6 yx 8 9 yx 2 1 yx 6 5 yx 2 2 y"}
{:process 6, :type :invoke, :f :append, :key "9", :value "x 6 10 y"}
{:process 8, :type :ok, :f :append, :key "1", :value "x 8 3 y"}
{:process 8, :type :invoke, :f :append, :key "6", :value "x 8 4 y"}
{:process 6, :type :ok, :f :append, :key "9", :value "x 6 10 y"}
{:process 6, :type :invoke, :f :get, :key "8", :value nil}
{:process 3, :type :ok, :f :append, :key "9", :value "x 3 0 y"}
{:process 3, :type :invoke, :f :append, :key "5", :value "x 3 1 y"}
{:process 7, :type :ok, :f :append, :key "7", :value "x 7 2 y"}
{:process 7, :type :invoke, :f :append, :key "8", :value "x 7 3 y"}
{:process 6, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 yx 7 5 yx 4 3 yx 9 11 y"}
{:process 6, :type :invoke, :f :get, :key "5", :value nil}
{:process 8, :type :ok, :f :append, :key "6", :value "x 8 4 y"}
{:process 8, :type :invoke, :f :get, :key "1", :value nil}
{:process 6, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 yx 9 13 yx 8 0 yx 9 0 yx 6 5 yx 6 9 y"}
{:process 6, :type :invoke, :f :get, :key "5", :value nil}
{:process 7, :type :ok, :f :append, :key "8", :value "x 7 3 y"}
{:process 7, :type :invoke, :f :get, :key "0", :value nil}
{:process 6, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 yx 9 13 yx 8 0 yx 9 0 yx 6 5 yx 6 9 y"}
{:process 6, :type :invoke, :f :append, :key "7", :value "x 6 11 y"}
{:process 7, :type :ok, :f :get, :key "0", :value "x 6 1 y"}
{:process 7, :type :invoke, :f :append, :key "5", :value "x 7 4 y"}
{:process 3, :type :ok, :f :append, :key "5", :value "x 3 1 y"}
{:process 3, :type :invoke, :f :get, :key "5", :value nil}
{:process 6, :type :ok, :f :append, :key "7", :value "x 6 11 y"}
{:process 6, :type :invoke, :f :get, :key "0", :value nil}
{:process 7, :type :ok, :f :append, :key "5", :value "x 7 4 y"}
{:process 7, :type :invoke, :f :get, :key "3", :value nil}
{:process 5, :type :ok, :f :append, :key "4", :value "x 5 4 y"}
{:process 5, :type :invoke, :f :append, :key "7", :value "x 5 5 y"}
{:process 3, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 yx 9 13 yx 8 0 yx 9 0 yx 6 5 yx 6 9 yx 3 1 yx 7 4 y"}
{:process 3, :type :invoke, :f :append, :key "0", :value "x 3 2 y"}
{:process 7, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 y"}
{:process 7, :type :invoke, :f :get, :key "6", :value nil}
{:process 7, :type :ok, :f :get, :key "6", :value "x 9 10 yx 8 6 yx 8 9 yx 2 1 yx 6 5 yx 2 2 yx 8 4 y"}
{:process 7, :type :invoke, :f :get, :key "5", :value nil}
{:process 5, :type :ok, :f :append, :key "7", :value "x 5 5 y"}
{:process 5, :type :invoke, :f :append, :key "5", :value "x 5 6 y"}
{:process 3, :type :ok, :f :append, :key "0", :value "x 3 2 y"}
{:process 3, :type :invoke, :f :get, :key "8", :value nil}
{:process 5, :type :ok, :f :append, :key "5", :value "x 5 6 y"}
{:process 5, :type :invoke, :f :append, :key "1", :value "x 5 7 y"}
{:process 2, :type :ok, :f :append, :key "5", :value "x 2 3 y"}
{:process 2, :type :invoke, :f :get, :key "3", :value nil}
{:process 3, :type :ok, :f :get, :key "8", :value "x 1 0 yx 5 1 yx 7 5 yx 4 3 yx 9 11 yx 7 3 y"}
{:process 3, :type :invoke, :f :get, :key "1", :value nil}
{:process 8, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 y"}
{:process 8, :type :invoke, :f :append, :key "7", :value "x 8 5 y"}
{:process 2, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 y"}
{:process 2, :type :invoke, :f :put, :key "4", :value "x 2 4 y"}
{:process 5, :type :ok, :f :append, :key "1", :value "x 5 7 y"}
{:process 5, :type :invoke, :f :get, :key "4", :value nil}
{:process 5, :type :ok, :f :get, :key "4", :value "x 8 12 yx 7 13 yx 9 12 yx 8 2 yx 5 4 y"}
{:process 5, :type :invoke, :f :append, :key "6", :value "x 5 8 y"}
{:process 5, :type :ok, :f :append, :key "6", :value "x 5 8 y"}
{:process 5, :type :invoke, :f :append, :key "1", :value "x 5 9 y"}
{:process 6, :type :ok, :f :get, :key "0", :value "x 6 1 yx 3 2 y"}
{:process 6, :type :invoke, :f :append, :key "3", :value "x 6 12 y"}
{:process 7, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 yx 9 13 yx 8 0 yx 9 0 y"}
{:process 7, :type :invoke, :f :get, :key "1", :value nil}
{:process 7, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 y"}
{:process 7, :type :invoke, :f :append, :key "4", :value "x 7 5 y"}
{:process 3, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 y"}
{:process 3, :type :invoke, :f :get, :key "3", :value nil}
{:process 3, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 y"}
{:process 3, :type :invoke, :f :append, :key "5", :value "x 3 3 y"}
{:process 9, :type :ok, :f :append, :key "4", :value "x 9 1 y"}
{:process 9, :type :invoke, :f :put, :key "2", :value "x 9 2 y"}
{:process 3, :type :ok, :f :append, :key "5", :value "x 3 3 y"}
{:process 3, :type :invoke, :f :append, :key "2", :value "x 3 4 y"}
{:process 3, :type :ok, :f :append, :key "2", :value "x 3 4 y"}
{:process 3, :type :invoke, :f :get, :key "1", :value nil}
{:process 3, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 yx 5 9 y"}
{:process 3, :type :invoke, :f :get, :key "6", :value nil}
{:process 2, :type :ok, :f :put, :key "4", :value "x 2 4 y"}
{:process 2, :type :invoke, :f :get, :key "1", :value nil}
{:process 2, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 yx 5 9 y"}
{:process 2, :type :invoke, :f :get, :key "9", :value nil}
{:process 2, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 yx 0 9 yx 0 13 yx 0 14 yx 7 14 yx 1 7 yx 2 3 yx 7 0 yx 4 0 yx 6 4 yx 2 0 yx 5 1 yx 5 3 yx 3 0 yx 6 10 y"}
{:process 2, :type :invoke, :f :append, :key "3", :value "x 2 5 y"}
{:process 5, :type :ok, :f :append, :key "1", :value "x 5 9 y"}
{:process 5, :type :invoke, :f :append, :key "4", :value "x 5 10 y"}
{:process 2, :type :ok, :f :append, :key "3", :value "x 2 5 y"}
{:process 2, :type :invoke, :f :get, :key "1", :value nil}
{:process 2, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 yx 5 9 y"}
{:process 2, :type :invoke, :f :append, :key "6", :value "x 2 6 y"}
{:process 2, :type :ok, :f :append, :key "6", :value "x 2 6 y"}
{:process 2, :type :invoke, :f :append, :key "6", :value "x 2 7 y"}
{:process 3, :type :ok, :f :get, :key "6", :value "x 9 10 yx 8 6 yx 8 9 yx 2 1 yx 6 5 yx 2 2 yx 8 4 yx 5 8 y"}
{:process 3, :type :invoke, :f :put, :key "6", :value "x 3 5 y"}
{:process 2, :type :ok, :f :append, :key "6", :value "x 2 7 y"}
{:process 2, :type :invoke, :f :get, :key "9", :value nil}
{:process 2, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 yx 0 9 yx 0 13 yx 0 14 yx 7 14 yx 1 7 yx 2 3 yx 7 0 yx 4 0 yx 6 4 yx 2 0 yx 5 1 yx 5 3 yx 3 0 yx 6 10 y"}
{:process 2, :type :invoke, :f :append, :key "4", :value "x 2 8 y"}
{:process 9, :type :ok, :f :put, :key "2", :value "x 9 2 y"}
{:process 9, :type :invoke, :f :append, :key "1", :value "x 9 3 y"}
{:process 2, :type :ok, :f :append, :key "4", :value "x 2 8 y"}
{:process 2, :type :invoke, :f :get, :key "7", :value nil}
{:process 9, :type :ok, :f :append, :key "1", :value "x 9 3 y"}
{:process 9, :type :invoke, :f :append, :key "7", :value "x 9 4 y"}
{:process 2, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 yx 7 2 yx 6 2 yx 6 7 yx 6 11 yx 5 5 y"}
{:process 2, :type :invoke, :f :get, :key "3", :value nil}
{:process 2, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 yx 2 5 y"}
{:process 2, :type :invoke, :f :append, :key "5", :value "x 2 9 y"}
{:process 6, :type :ok, :f :append, :key "3", :value "x 6 12 y"}
{:process 6, :type :invoke, :f :append, :key "9", :value "x 6 13 y"}
{:process 6, :type :ok, :f :append, :key "9", :value "x 6 13 y"}
{:process 6, :type :invoke, :f :append, :key "8", :value "x 6 14 y"}
{:process 6, :type :ok, :f :append, :key "8", :value "x 6 14 y"}
{:process 6, :type :invoke, :f :get, :key "1", :value nil}
{:process 6, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 yx 5 9 yx 9 3 y"}
{:process 6, :type :invoke, :f :append, :key "1", :value "x 6 15 y"}
{:process 6, :type :ok, :f :append, :key "1", :value "x 6 15 y"}
{:process 6, :type :invoke, :f :get, :key "4", :value nil}
{:process 6, :type :ok, :f :get, :key "4", :value "x 2 4 yx 9 1 yx 2 8 y"}
{:process 6, :type :invoke, :f :get, :key "1", :value nil}
{:process 6, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 yx 5 9 yx 9 3 yx 6 15 y"}
{:process 6, :type :invoke, :f :get, :key "9", :value nil}
{:process 6, :type :ok, :f :get, :key "9", :value "x 6 0 yx 2 0 yx 0 9 yx 0 13 yx 0 14 yx 7 14 yx 1 7 yx 2 3 yx 7 0 yx 4 0 yx 6 4 yx 2 0 yx 5 1 yx 5 3 yx 3 0 yx 6 10 yx 6 13 y"}
{:process 6, :type :invoke, :f :append, :key "5", :value "x 6 16 y"}
{:process 6, :type :ok, :f :append, :key "5", :value "x 6 16 y"}
{:process 6, :type :invoke, :f :append, :key "6", :value "x 6 17 y"}
{:process 1, :type :ok, :f :append, :key "1", :value "x 1 0 y"}
{:process 1, :type :invoke, :f :append, :key "9", :value "x 1 1 y"}
{:process 6, :type :ok, :f :append, :key "6", :value "x 6 17 y"}
{:process 6, :type :invoke, :f :get, :key "0", :value nil}
{:process 3, :type :ok, :f :put, :key "6", :value "x 3 5 y"}
{:process 3, :type :invoke, :f :get, :key "1", :value nil}
{:process 5, :type :ok, :f :append, :key "4", :value "x 5 10 y"}
{:process 5, :type :invoke, :f :get, :key "2", :value nil}
{:process 3, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 yx 5 9 yx 9 3 yx 6 15 y"}
{:process 3, :type :invoke, :f :get, :key "0", :value nil}
{:process 3, :type :ok, :f :get, :key "0", :value "x 6 1 yx 3 2 y"}
{:process 3, :type :invoke, :f :append, :key "6", :value "x 3 6 y"}
{:process 5, :type :ok, :f :get, :key "2", :value "x 9 2 yx 3 4 y"}
{:process 5, :type :invoke, :f :get, :key "4", :value nil}
{:process 5, :type :ok, :f :get, :key "4", :value "x 2 4 yx 9 1 yx 2 8 yx 5 10 y"}
{:process 5, :type :invoke, :f :get, :key "2", :value nil}
{:process 5, :type :ok, :f :get, :key "2", :value "x 9 2 yx 3 4 y"}
{:process 5, :type :invoke, :f :append, :key "3", :value "x 5 11 y"}
{:process 3, :type :ok, :f :append, :key "6", :value "x 3 6 y"}
{:process 3, :type :invoke, :f :get, :key "4", :value nil}
{:process 3, :type :ok, :f :get, :key "4", :value "x 2 4 yx 9 1 yx 2 8 yx 5 10 y"}
{:process 3, :type :invoke, :f :append, :key "9", :value "x 3 7 y"}
{:process 5, :type :ok, :f :append, :key "3", :value "x 5 11 y"}
{:process 5, :type :invoke, :f :append, :key "2", :value "x 5 12 y"}
{:process 5, :type :ok, :f :append, :key "2", :value "x 5 12 y"}
{:process 5, :type :invoke, :f :append, :key "6", :value "x 5 13 y"}
{:process 5, :type :ok, :f :append, :key "6", :value "x 5 13 y"}
{:process 5, :type :invoke, :f :put, :key "9", :value "x 5 14 y"}
{:process 5, :type :ok, :f :put, :key "9", :value "x 5 14 y"}
{:process 5, :type :invoke, :f :append, :key "0", :value "x 5 15 y"}
{:process 5, :type :ok, :f :append, :key "0", :value "x 5 15 y"}
{:process 5, :type :invoke, :f :append, :key "8", :value "x 5 16 y"}
{:process 2, :type :ok, :f :append, :key "5", :value "x 2 9 y"}
{:process 2, :type :invoke, :f :append, :key "5", :value "x 2 10 y"}
{:process 6, :type :ok, :f :get, :key "0", :value "x 6 1 yx 3 2 y"}
{:process 6, :type :invoke, :f :get, :key "2", :value nil}
{:process 5, :type :ok, :f :append, :key "8", :value "x 5 16 y"}
{:process 5, :type :invoke, :f :append, :key "8", :value "x 5 17 y"}
{:process 6, :type :ok, :f :get, :key "2", :value "x 9 2 yx 3 4 yx 5 12 y"}
{:process 6, :type :invoke, :f :get, :key "2", :value nil}
{:process 2, :type :ok, :f :append, :key "5", :value "x 2 10 y"}
{:process 2, :type :invoke, :f :get, :key "3", :value nil}
{:process 6, :type :ok, :f :get, :key "2", :value "x 9 2 yx 3 4 yx 5 12 y"}
{:process 6, :type :invoke, :f :get, :key "0", :value nil}
{:process 2, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 yx 2 5 yx 6 12 yx 5 11 y"}
{:process 2, :type :invoke, :f :put, :key "5", :value "x 2 11 y"}
{:process 5, :type :ok, :f :append, :key "8", :value "x 5 17 y"}
{:process 5, :type :invoke, :f :get, :key "9", :value nil}
{:process 6, :type :ok, :f :get, :key "0", :value "x 6 1 yx 3 2 yx 5 15 y"}
{:process 6, :type :invoke, :f :get, :key "5", :value nil}
{:process 6, :type :ok, :f :get, :key "5", :value "x 3 3 yx 7 2 yx 8 3 yx 6 1 yx 7 10 yx 1 3 yx 8 10 yx 9 13 yx 8 0 yx 9 0 yx 6 5 yx 6 9 yx 3 1 yx 7 4 yx 5 6 yx 2 3 yx 3 3 yx 6 16 yx 2 9 y"}
{:process 6, :type :invoke, :f :append, :key "9", :value "x 6 18 y"}
{:process 2, :type :ok, :f :put, :key "5", :value "x 2 11 y"}
{:process 2, :type :invoke, :f :get, :key "9", :value nil}
{:process 2, :type :ok, :f :get, :key "9", :value "x 5 14 y"}
{:process 2, :type :invoke, :f :append, :key "2", :value "x 2 12 y"}
{:process 2, :type :ok, :f :append, :key "2", :value "x 2 12 y"}
{:process 2, :type :invoke, :f :append, :key "3", :value "x 2 13 y"}
{:process 5, :type :ok, :f :get, :key "9", :value "x 5 14 y"}
{:process 5, :type :invoke, :f :get, :key "5", :value nil}
{:process 5, :type :ok, :f :get, :key "5", :value "x 2 11 y"}
{:process 5, :type :invoke, :f :append, :key "3", :value "x 5 18 y"}
{:process 0, :type :ok, :f :append, :key "3", :value "x 0 2 y"}
{:process 0, :type :invoke, :f :append, :key "6", :value "x 0 3 y"}
{:process 4, :type :ok, :f :append, :key "3", :value "x 4 1 y"}
{:process 4, :type :invoke, :f :append, :key "2", :value "x 4 2 y"}
{:process 0, :type :ok, :f :append, :key "6", :value "x 0 3 y"}
{:process 0, :type :invoke, :f :get, :key "0", :value nil}
{:process 0, :type :ok, :f :get, :key "0", :value "x 6 1 yx 3 2 yx 5 15 y"}
{:process 0, :type :invoke, :f :get, :key "4", :value nil}
{:process 0, :type :ok, :f :get, :key "4", :value "x 2 4 yx 9 1 yx 2 8 yx 5 10 y"}
{:process 0, :type :invoke, :f :append, :key "1", :value "x 0 4 y"}
{:process 6, :type :ok, :f :append, :key "9", :value "x 6 18 y"}
{:process 6, :type :invoke, :f :get, :key "3", :value nil}
{:process 6, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 yx 2 5 yx 6 12 yx 5 11 y"}
{:process 6, :type :invoke, :f :put, :key "8", :value "x 6 19 y"}
{:process 1, :type :ok, :f :append, :key "9", :value "x 1 1 y"}
{:process 1, :type :invoke, :f :append, :key "2", :value "x 1 2 y"}
{:process 1, :type :ok, :f :append, :key "2", :value "x 1 2 y"}
{:process 1, :type :invoke, :f :append, :key "4", :value "x 1 3 y"}
{:process 2, :type :ok, :f :append, :key "3", :value "x 2 13 y"}
{:process 2, :type :invoke, :f :append, :key "2", :value "x 2 14 y"}
{:process 8, :type :ok, :f :append, :key "7", :value "x 8 5 y"}
{:process 8, :type :invoke, :f :append, :key "3", :value "x 8 6 y"}
{:process 8, :type :ok, :f :append, :key "3", :value "x 8 6 y"}
{:process 8, :type :invoke, :f :put, :key "4", :value "x 8 7 y"}
{:process 8, :type :ok, :f :put, :key "4", :value "x 8 7 y"}
{:process 8, :type :invoke, :f :append, :key "6", :value "x 8 8 y"}
{:process 8, :type :ok, :f :append, :key "6", :value "x 8 8 y"}
{:process 8, :type :invoke, :f :append, :key "5", :value "x 8 9 y"}
{:process 5, :type :ok, :f :append, :key "3", :value "x 5 18 y"}
{:process 5, :type :invoke, :f :get, :key "1", :value nil}
{:process 5, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 yx 5 9 yx 9 3 yx 6 15 y"}
{:process 5, :type :invoke, :f :get, :key "5", :value nil}
{:process 8, :type :ok, :f :append, :key "5", :value "x 8 9 y"}
{:process 8, :type :invoke, :f :get, :key "1", :value nil}
{:process 5, :type :ok, :f :get, :key "5", :value "x 2 11 yx 8 9 y"}
{:process 5, :type :invoke, :f :get, :key "3", :value nil}
{:process 5, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 yx 2 5 yx 6 12 yx 5 11 yx 2 13 yx 8 6 yx 5 18 y"}
{:process 5, :type :invoke, :f :append, :key "8", :value "x 5 19 y"}
{:process 5, :type :ok, :f :append, :key "8", :value "x 5 19 y"}
{:process 5, :type :invoke, :f :append, :key "6", :value "x 5 20 y"}
{:process 5, :type :ok, :f :append, :key "6", :value "x 5 20 y"}
{:process 5, :type :invoke, :f :get, :key "3", :value nil}
{:process 5, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 yx 2 5 yx 6 12 yx 5 11 yx 2 13 yx 8 6 yx 5 18 y"}
{:process 5, :type :invoke, :f :append, :key "4", :value "x 5 21 y"}
{:process 9, :type :ok, :f :append, :key "7", :value "x 9 4 y"}
{:process 9, :type :invoke, :f :get, :key "9", :value nil}
{:process 5, :type :ok, :f :append, :key "4", :value "x 5 21 y"}
{:process 5, :type :invoke, :f :append, :key "4", :value "x 5 22 y"}
{:process 9, :type :ok, :f :get, :key "9", :value "x 5 14 yx 6 18 yx 1 1 y"}
{:process 9, :type :invoke, :f :get, :key "8", :value nil}
{:process 8, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 yx 5 9 yx 9 3 yx 6 15 y"}
{:process 8, :type :invoke, :f :get, :key "3", :value nil}
{:process 4, :type :ok, :f :append, :key "2", :value "x 4 2 y"}
{:process 4, :type :invoke, :f :get, :key "4", :value nil}
{:process 5, :type :ok, :f :append, :key "4", :value "x 5 22 y"}
{:process 5, :type :invoke, :f :get, :key "5", :value nil}
{:process 4, :type :ok, :f :get, :key "4", :value "x 8 7 yx 5 21 yx 5 22 y"}
{:process 4, :type :invoke, :f :append, :key "5", :value "x 4 3 y"}
{:process 9, :type :ok, :f :get, :key "8", :value "x 6 19 yx 5 19 y"}
{:process 9, :type :invoke, :f :get, :key "3", :value nil}
{:process 0, :type :ok, :f :append, :key "1", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "3", :value nil}
{:process 0, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 yx 2 5 yx 6 12 yx 5 11 yx 2 13 yx 8 6 yx 5 18 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 5 y"}
{:process 4, :type :ok, :f :append, :key "5", :value "x 4 3 y"}
{:process 4, :type :invoke, :f :get, :key "2", :value nil}
{:process 9, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 yx 2 5 yx 6 12 yx 5 11 yx 2 13 yx 8 6 yx 5 18 y"}
{:process 9, :type :invoke, :f :append, :key "6", :value "x 9 5 y"}
{:process 4, :type :ok, :f :get, :key "2", :value "x 9 2 yx 3 4 yx 5 12 yx 2 12 yx 4 2 yx 1 2 y"}
{:process 4, :type :invoke, :f :get, :key "2", :value nil}
{:process 4, :type :ok, :f :get, :key "2", :value "x 9 2 yx 3 4 yx 5 12 yx 2 12 yx 4 2 yx 1 2 y"}
{:process 4, :type :invoke, :f :append, :key "4", :value "x 4 4 y"}
{:process 9, :type :ok, :f :append, :key "6", :value "x 9 5 y"}
{:process 9, :type :invoke, :f :append, :key "0", :value "x 9 6 y"}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 5 y"}
{:process 0, :type :invoke, :f :get, :key "6", :value nil}
{:process 0, :type :ok, :f :get, :key "6", :value "x 3 5 yx 3 6 yx 5 13 yx 0 3 yx 8 8 yx 5 20 yx 9 5 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 6 y"}
{:process 7, :type :ok, :f :append, :key "4", :value "x 7 5 y"}
{:process 7, :type :invoke, :f :append, :key "5", :value "x 7 6 y"}
{:process 4, :type :ok, :f :append, :key "4", :value "x 4 4 y"}
{:process 4, :type :invoke, :f :append, :key "4", :value "x 4 5 y"}
{:process 7, :type :ok, :f :append, :key "5", :value "x 7 6 y"}
{:process 7, :type :invoke, :f :get, :key "1", :value nil}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :append, :key "9", :value "x 0 7 y"}
{:process 4, :type :ok, :f :append, :key "4", :value "x 4 5 y"}
{:process 4, :type :invoke, :f :get, :key "7", :value nil}
{:process 9, :type :ok, :f :append, :key "0", :value "x 9 6 y"}
{:process 9, :type :invoke, :f :append, :key "7", :value "x 9 7 y"}
{:process 0, :type :ok, :f :append, :key "9", :value "x 0 7 y"}
{:process 0, :type :invoke, :f :append, :key "3", :value "x 0 8 y"}
{:process 4, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 yx 7 2 yx 6 2 yx 6 7 yx 6 11 yx 5 5 yx 9 4 yx 8 5 y"}
{:process 4, :type :invoke, :f :get, :key "7", :value nil}
{:process 4, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 yx 7 2 yx 6 2 yx 6 7 yx 6 11 yx 5 5 yx 9 4 yx 8 5 y"}
{:process 4, :type :invoke, :f :get, :key "5", :value nil}
{:process 9, :type :ok, :f :append, :key "7", :value "x 9 7 y"}
{:process 9, :type :invoke, :f :append, :key "6", :value "x 9 8 y"}
{:process 0, :type :ok, :f :append, :key "3", :value "x 0 8 y"}
{:process 0, :type :invoke, :f :get, :key "2", :value nil}
{:process 0, :type :ok, :f :get, :key "2", :value "x 9 2 yx 3 4 yx 5 12 yx 2 12 yx 4 2 yx 1 2 yx 0 5 yx 0 6 y"}
{:process 0, :type :invoke, :f :get, :key "1", :value nil}
{:process 0, :type :ok, :f :get, :key "1", :value "x 7 1 yx 2 1 yx 5 2 yx 1 0 yx 8 1 yx 8 3 yx 5 7 yx 5 9 yx 9 3 yx 6 15 yx 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "5", :value nil}
{:process 5, :type :ok, :f :get, :key "5", :value "x 2 11 yx 8 9 yx 4 3 yx 7 6 y"}
{:process 5, :type :invoke, :f :get, :key "7", :value nil}
{:process 4, :type :ok, :f :get, :key "5", :value "x 2 11 yx 8 9 yx 4 3 yx 7 6 y"}
{:process 4, :type :invoke, :f :get, :key "7", :value nil}
{:process 4, :type :ok, :f :get, :key "7", :value "x 5 2 yx 9 2 yx 9 7 yx 0 7 yx 8 11 yx 7 2 yx 6 2 yx 6 7 yx 6 11 yx 5 5 yx 9 4 yx 8 5 yx 9 7 y"}
{:process 4, :type :invoke, :f :append, :key "2", :value "x 4 6 y"}
{:process 0, :type :ok, :f :get, :key "5", :value "x 2 11 yx 8 9 yx 4 3 yx 7 6 y"}
{:process 0, :type :invoke, :f :get, :key "4", :value nil}
{:process 8, :type :ok, :f :get, :key "3", :value "x 9 1 yx 9 6 yx 0 11 yx 6 2 yx 8 5 yx 8 8 yx 6 4 yx 4 1 yx 5 0 yx 0 2 yx 6 8 yx 2 5 yx 6 12 yx 5 11 yx 2 13 yx 8 6 yx 5 18 y"}
{:process 8, :type :invoke, :f :append, :key "6", :value "x 8 10 y"}
{:process 0, :type :ok, :f :get, :key "4", :value "x 8 7 yx 5 21 yx 5 22 yx 7 5 yx 4 4 yx 4 5 y"}
{:process 0, :type :invoke, :f :append, :key "8", :value "x 0 9 y"}
{:process 9, :type :ok, :f :append, :key "6", :value "x 9 8 y"}
{:process 9, :type :invoke, :f :append, :key "8", :value "x 9 9 y"}
{:process 4, :type :ok, :f :append, :key "2", :value "x 4 6 y"}
{:process 4, :type :invoke, :f :append, :key "5", :value "x 4 7 y"}
{:process 0, :type :ok, :f :append, :key "8", :value "x 0 9 y"}
{:process 0, :type :invoke, :f :get, :key "9", :value nil}
{:process 9, :type :ok, :f :append, :key "8", :value "x 9 9 y"}
{:process 9, :type :invoke, :f :append, :key "0", :value "x 9 10 y"}
{:process 0, :type :ok, :f :get, :key "9", :value "x 5 14 yx 6 18 yx 1 1 yx 0 7 y"}
{:process 0, :type :invoke, :f :put, :key "1", :value "x 0 10 y"}
{:process 4, :type :ok, :f :append, :key "5", :value "x 4 7 y"}
{:process 4, :type :invoke, :f :append, :key "5", :value "x 4 8 y"}
{:process 5, :type :ok, :f :get, :key "7", :value ""}
{:process 7, :type :ok, :f :get, :key "1", :value ""}
{:process 6, :type :ok, :f :put, :key "8", :value "x 6 19 y"}
{:process 1, :type :ok, :f :append, :key "4", :value "x 1 3 y"}
{:process 2, :type :ok, :f :append, :key "2", :value "x 2 14 y"}
{:process 3, :type :ok, :f :append, :key "9", :value "x 3 7 y"}
{:process 8, :type :ok, :f :append, :key "6", :value "x 8 10 y"}
{:process 9, :type :ok, :f :append, :key "0", :value "x 9 10 y"}
{:process 0, :type :ok, :f :put, :key "1", :value "x 0 10 y"}
{:process 4, :type :ok, :f :append, :key "5", :value "x 4 8 y"}

================================================
FILE: courses/dss/linearizability/test_data/c10-ok.txt
================================================
{:process 9, :type :invoke, :f :append, :key "0", :value "x 9 0 y"}
{:process 2, :type :invoke, :f :append, :key "1", :value "x 2 0 y"}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 0 y"}
{:process 1, :type :invoke, :f :get, :key "9", :value nil}
{:process 5, :type :invoke, :f :append, :key "9", :value "x 5 0 y"}
{:process 3, :type :invoke, :f :append, :key "9", :value "x 3 0 y"}
{:process 4, :type :invoke, :f :append, :key "1", :value "x 4 0 y"}
{:process 7, :type :invoke, :f :append, :key "5", :value "x 7 0 y"}
{:process 6, :type :invoke, :f :append, :key "9", :value "x 6 0 y"}
{:process 8, :type :invoke, :f :get, :key "8", :value nil}
{:process 4, :type :ok, :f :append, :key "1", :value "x 4 0 y"}
{:process 4, :type :invoke, :f :append, :key "1", :value "x 4 1 y"}
{:process 9, :type :ok, :f :append, :key "0", :value "x 9 0 y"}
{:process 9, :type :invoke, :f :append, :key "5", :value "x 9 1 y"}
{:process 4, :type :ok, :f :append, :key "1", :value "x 4 1 y"}
{:process 4, :type :invoke, :f :append, :key "4", :value "x 4 2 y"}
{:process 9, :type :ok, :f :append, :key "5", :value "x 9 1 y"}
{:process 9, :type :invoke, :f :append, :key "7", :value "x 9 2 y"}
{:process 4, :type :ok, :f :append, :key "4", :value "x 4 2 y"}
{:process 4, :type :invoke, :f :get, :key "3", :value nil}
{:process 4, :type :ok, :f :get, :key "3", :value ""}
{:process 4, :type :invoke, :f :append, :key "3", :value "x 4 3 y"}
{:process 4, :type :ok, :f :append, :key "3", :value "x 4 3 y"}
{:process 4, :type :invoke, :f :append, :key "9", :value "x 4 4 y"}
{:process 4, :type :ok, :f :append, :key "9", :value "x 4 4 y"}
{:process 4, :type :invoke, :f :append, :key "4", :value "x 4 5 y"}
{:process 4, :type :ok, :f :append, :key "4", :value "x 4 5 y"}
{:process 4, :type :invoke, :f :get, :key "5", :value nil}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 0 y"}
{:process 0, :type :invoke, :f :get, :key "3", :value nil}
{:process 4, :type :ok, :f :get, :key "5", :value "x 9 1 y"}
{:process 4, :type :invoke, :f :append, :key "2", :value "x 4 6 y"}
{:process 4, :type :ok, :f :append, :key "2", :value "x 4 6 y"}
{:process 4, :type :invoke, :f :get, :key "9", :value nil}
{:process 6, :type :ok, :f :append, :key "9", :value "x 6 0 y"}
{:process 6, :type :invoke, :f :get, :key "6", :value nil}
{:process 6, :type :ok, :f :get, :key "6", :value ""}
{:process 6, :type :invoke, :f :append, :key "5", :value "x 6 1 y"}
{:process 7, :type :ok, :f :append, :key "5", :value "x 7 0 y"}
{:process 7, :type :invoke, :f :get, :key "0", :value nil}
{:process 7, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 y"}
{:process 7, :type :invoke, :f :append, :key "0", :value "x 7 1 y"}
{:process 2, :type :ok, :f :append, :key "1", :value "x 2 0 y"}
{:process 2, :type :invoke, :f :get, :key "5", :value nil}
{:process 2, :type :ok, :f :get, :key "5", :value "x 9 1 yx 7 0 y"}
{:process 2, :type :invoke, :f :append, :key "1", :value "x 2 1 y"}
{:process 2, :type :ok, :f :append, :key "1", :value "x 2 1 y"}
{:process 2, :type :invoke, :f :append, :key "5", :value "x 2 2 y"}
{:process 3, :type :ok, :f :append, :key "9", :value "x 3 0 y"}
{:process 3, :type :invoke, :f :append, :key "5", :value "x 3 1 y"}
{:process 2, :type :ok, :f :append, :key "5", :value "x 2 2 y"}
{:process 2, :type :invoke, :f :append, :key "9", :value "x 2 3 y"}
{:process 3, :type :ok, :f :append, :key "5", :value "x 3 1 y"}
{:process 3, :type :invoke, :f :append, :key "0", :value "x 3 2 y"}
{:process 3, :type :ok, :f :append, :key "0", :value "x 3 2 y"}
{:process 3, :type :invoke, :f :get, :key "9", :value nil}
{:process 3, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 y"}
{:process 3, :type :invoke, :f :append, :key "5", :value "x 3 3 y"}
{:process 8, :type :ok, :f :get, :key "8", :value ""}
{:process 8, :type :invoke, :f :get, :key "1", :value nil}
{:process 5, :type :ok, :f :append, :key "9", :value "x 5 0 y"}
{:process 5, :type :invoke, :f :get, :key "8", :value nil}
{:process 9, :type :ok, :f :append, :key "7", :value "x 9 2 y"}
{:process 9, :type :invoke, :f :put, :key "6", :value "x 9 3 y"}
{:process 4, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 yx 5 0 y"}
{:process 4, :type :invoke, :f :append, :key "4", :value "x 4 7 y"}
{:process 1, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 yx 5 0 y"}
{:process 1, :type :invoke, :f :append, :key "1", :value "x 1 0 y"}
{:process 6, :type :ok, :f :append, :key "5", :value "x 6 1 y"}
{:process 6, :type :invoke, :f :get, :key "1", :value nil}
{:process 4, :type :ok, :f :append, :key "4", :value "x 4 7 y"}
{:process 4, :type :invoke, :f :append, :key "8", :value "x 4 8 y"}
{:process 1, :type :ok, :f :append, :key "1", :value "x 1 0 y"}
{:process 1, :type :invoke, :f :append, :key "2", :value "x 1 1 y"}
{:process 7, :type :ok, :f :append, :key "0", :value "x 7 1 y"}
{:process 7, :type :invoke, :f :append, :key "5", :value "x 7 2 y"}
{:process 7, :type :ok, :f :append, :key "5", :value "x 7 2 y"}
{:process 7, :type :invoke, :f :append, :key "9", :value "x 7 3 y"}
{:process 1, :type :ok, :f :append, :key "2", :value "x 1 1 y"}
{:process 1, :type :invoke, :f :put, :key "7", :value "x 1 2 y"}
{:process 4, :type :ok, :f :append, :key "8", :value "x 4 8 y"}
{:process 4, :type :invoke, :f :append, :key "5", :value "x 4 9 y"}
{:process 7, :type :ok, :f :append, :key "9", :value "x 7 3 y"}
{:process 7, :type :invoke, :f :get, :key "8", :value nil}
{:process 1, :type :ok, :f :put, :key "7", :value "x 1 2 y"}
{:process 1, :type :invoke, :f :append, :key "4", :value "x 1 3 y"}
{:process 4, :type :ok, :f :append, :key "5", :value "x 4 9 y"}
{:process 4, :type :invoke, :f :append, :key "8", :value "x 4 10 y"}
{:process 1, :type :ok, :f :append, :key "4", :value "x 1 3 y"}
{:process 1, :type :invoke, :f :get, :key "5", :value nil}
{:process 7, :type :ok, :f :get, :key "8", :value "x 4 8 y"}
{:process 7, :type :invoke, :f :put, :key "6", :value "x 7 4 y"}
{:process 1, :type :ok, :f :get, :key "5", :value "x 9 1 yx 7 0 yx 3 1 yx 2 2 yx 6 1 yx 7 2 yx 4 9 y"}
{:process 1, :type :invoke, :f :get, :key "4", :value nil}
{:process 6, :type :ok, :f :get, :key "1", :value "x 4 0 yx 4 1 yx 2 0 yx 2 1 yx 1 0 y"}
{:process 6, :type :invoke, :f :append, :key "2", :value "x 6 2 y"}
{:process 6, :type :ok, :f :append, :key "2", :value "x 6 2 y"}
{:process 6, :type :invoke, :f :get, :key "9", :value nil}
{:process 6, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 yx 5 0 yx 7 3 y"}
{:process 6, :type :invoke, :f :get, :key "8", :value nil}
{:process 4, :type :ok, :f :append, :key "8", :value "x 4 10 y"}
{:process 4, :type :invoke, :f :get, :key "6", :value nil}
{:process 1, :type :ok, :f :get, :key "4", :value "x 4 2 yx 4 5 yx 4 7 yx 1 3 y"}
{:process 1, :type :invoke, :f :append, :key "4", :value "x 1 4 y"}
{:process 0, :type :ok, :f :get, :key "3", :value "x 4 3 y"}
{:process 0, :type :invoke, :f :append, :key "8", :value "x 0 1 y"}
{:process 0, :type :ok, :f :append, :key "8", :value "x 0 1 y"}
{:process 0, :type :invoke, :f :append, :key "2", :value "x 0 2 y"}
{:process 8, :type :ok, :f :get, :key "1", :value "x 4 0 yx 4 1 yx 2 0 yx 2 1 yx 1 0 y"}
{:process 8, :type :invoke, :f :get, :key "9", :value nil}
{:process 0, :type :ok, :f :append, :key "2", :value "x 0 2 y"}
{:process 0, :type :invoke, :f :get, :key "0", :value nil}
{:process 8, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 yx 5 0 yx 7 3 yx 2 3 y"}
{:process 8, :type :invoke, :f :get, :key "7", :value nil}
{:process 3, :type :ok, :f :append, :key "5", :value "x 3 3 y"}
{:process 3, :type :invoke, :f :get, :key "4", :value nil}
{:process 0, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 3 2 yx 7 1 y"}
{:process 0, :type :invoke, :f :append, :key "8", :value "x 0 3 y"}
{:process 3, :type :ok, :f :get, :key "4", :value "x 4 2 yx 4 5 yx 4 7 yx 1 3 y"}
{:process 3, :type :invoke, :f :get, :key "1", :value nil}
{:process 0, :type :ok, :f :append, :key "8", :value "x 0 3 y"}
{:process 0, :type :invoke, :f :get, :key "9", :value nil}
{:process 0, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 yx 5 0 yx 7 3 yx 2 3 y"}
{:process 0, :type :invoke, :f :append, :key "0", :value "x 0 4 y"}
{:process 0, :type :ok, :f :append, :key "0", :value "x 0 4 y"}
{:process 0, :type :invoke, :f :get, :key "1", :value nil}
{:process 6, :type :ok, :f :get, :key "8", :value "x 4 8 yx 4 10 yx 0 1 yx 0 3 y"}
{:process 6, :type :invoke, :f :get, :key "9", :value nil}
{:process 0, :type :ok, :f :get, :key "1", :value "x 4 0 yx 4 1 yx 2 0 yx 2 1 yx 1 0 y"}
{:process 0, :type :invoke, :f :append, :key "5", :value "x 0 5 y"}
{:process 3, :type :ok, :f :get, :key "1", :value "x 4 0 yx 4 1 yx 2 0 yx 2 1 yx 1 0 y"}
{:process 3, :type :invoke, :f :append, :key "8", :value "x 3 4 y"}
{:process 3, :type :ok, :f :append, :key "8", :value "x 3 4 y"}
{:process 3, :type :invoke, :f :get, :key "9", :value nil}
{:process 0, :type :ok, :f :append, :key "5", :value "x 0 5 y"}
{:process 0, :type :invoke, :f :append, :key "7", :value "x 0 6 y"}
{:process 7, :type :ok, :f :put, :key "6", :value "x 7 4 y"}
{:process 7, :type :invoke, :f :append, :key "0", :value "x 7 5 y"}
{:process 0, :type :ok, :f :append, :key "7", :value "x 0 6 y"}
{:process 0, :type :invoke, :f :append, :key "3", :value "x 0 7 y"}
{:process 7, :type :ok, :f :append, :key "0", :value "x 7 5 y"}
{:process 7, :type :invoke, :f :append, :key "0", :value "x 7 6 y"}
{:process 6, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 yx 5 0 yx 7 3 yx 2 3 y"}
{:process 6, :type :invoke, :f :append, :key "9", :value "x 6 3 y"}
{:process 4, :type :ok, :f :get, :key "6", :value "x 7 4 y"}
{:process 4, :type :invoke, :f :get, :key "1", :value nil}
{:process 4, :type :ok, :f :get, :key "1", :value "x 4 0 yx 4 1 yx 2 0 yx 2 1 yx 1 0 y"}
{:process 4, :type :invoke, :f :append, :key "6", :value "x 4 11 y"}
{:process 0, :type :ok, :f :append, :key "3", :value "x 0 7 y"}
{:process 7, :type :ok, :f :append, :key "0", :value "x 7 6 y"}
{:process 4, :type :ok, :f :append, :key "6", :value "x 4 11 y"}
{:process 0, :type :invoke, :f :get, :key "1", :value nil}
{:process 7, :type :invoke, :f :get, :key "9", :value nil}
{:process 4, :type :invoke, :f :append, :key "8", :value "x 4 12 y"}
{:process 4, :type :ok, :f :append, :key "8", :value "x 4 12 y"}
{:process 4, :type :invoke, :f :append, :key "0", :value "x 4 13 y"}
{:process 7, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 yx 5 0 yx 7 3 yx 2 3 y"}
{:process 7, :type :invoke, :f :put, :key "4", :value "x 7 7 y"}
{:process 7, :type :ok, :f :put, :key "4", :value "x 7 7 y"}
{:process 7, :type :invoke, :f :get, :key "4", :value nil}
{:process 4, :type :ok, :f :append, :key "0", :value "x 4 13 y"}
{:process 4, :type :invoke, :f :get, :key "8", :value nil}
{:process 4, :type :ok, :f :get, :key "8", :value "x 4 8 yx 4 10 yx 0 1 yx 0 3 yx 3 4 yx 4 12 y"}
{:process 4, :type :invoke, :f :get, :key "8", :value nil}
{:process 7, :type :ok, :f :get, :key "4", :value "x 7 7 y"}
{:process 7, :type :invoke, :f :get, :key "0", :value nil}
{:process 4, :type :ok, :f :get, :key "8", :value "x 4 8 yx 4 10 yx 0 1 yx 0 3 yx 3 4 yx 4 12 y"}
{:process 4, :type :invoke, :f :append, :key "0", :value "x 4 14 y"}
{:process 7, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 3 2 yx 7 1 yx 0 4 yx 7 5 yx 7 6 yx 4 13 y"}
{:process 7, :type :invoke, :f :get, :key "5", :value nil}
{:process 4, :type :ok, :f :append, :key "0", :value "x 4 14 y"}
{:process 4, :type :invoke, :f :get, :key "9", :value nil}
{:process 5, :type :ok, :f :get, :key "8", :value "x 4 8 yx 4 10 yx 0 1 yx 0 3 yx 3 4 yx 4 12 y"}
{:process 5, :type :invoke, :f :get, :key "5", :value nil}
{:process 2, :type :ok, :f :append, :key "9", :value "x 2 3 y"}
{:process 2, :type :invoke, :f :append, :key "0", :value "x 2 4 y"}
{:process 7, :type :ok, :f :get, :key "5", :value "x 9 1 yx 7 0 yx 3 1 yx 2 2 yx 6 1 yx 7 2 yx 4 9 yx 3 3 yx 0 5 y"}
{:process 7, :type :invoke, :f :append, :key "2", :value "x 7 8 y"}
{:process 5, :type :ok, :f :get, :key "5", :value "x 9 1 yx 7 0 yx 3 1 yx 2 2 yx 6 1 yx 7 2 yx 4 9 yx 3 3 yx 0 5 y"}
{:process 5, :type :invoke, :f :append, :key "4", :value "x 5 1 y"}
{:process 4, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 yx 5 0 yx 7 3 yx 2 3 y"}
{:process 4, :type :invoke, :f :append, :key "1", :value "x 4 15 y"}
{:process 7, :type :ok, :f :append, :key "2", :value "x 7 8 y"}
{:process 7, :type :invoke, :f :append, :key "5", :value "x 7 9 y"}
{:process 2, :type :ok, :f :append, :key "0", :value "x 2 4 y"}
{:process 2, :type :invoke, :f :append, :key "5", :value "x 2 5 y"}
{:process 4, :type :ok, :f :append, :key "1", :value "x 4 15 y"}
{:process 4, :type :invoke, :f :append, :key "6", :value "x 4 16 y"}
{:process 7, :type :ok, :f :append, :key "5", :value "x 7 9 y"}
{:process 7, :type :invoke, :f :get, :key "8", :value nil}
{:process 5, :type :ok, :f :append, :key "4", :value "x 5 1 y"}
{:process 5, :type :invoke, :f :get, :key "2", :value nil}
{:process 4, :type :ok, :f :append, :key "6", :value "x 4 16 y"}
{:process 4, :type :invoke, :f :append, :key "6", :value "x 4 17 y"}
{:process 2, :type :ok, :f :append, :key "5", :value "x 2 5 y"}
{:process 2, :type :invoke, :f :append, :key "4", :value "x 2 6 y"}
{:process 5, :type :ok, :f :get, :key "2", :value "x 4 6 yx 1 1 yx 6 2 yx 0 2 yx 7 8 y"}
{:process 5, :type :invoke, :f :append, :key "7", :value "x 5 2 y"}
{:process 7, :type :ok, :f :get, :key "8", :value "x 4 8 yx 4 10 yx 0 1 yx 0 3 yx 3 4 yx 4 12 y"}
{:process 7, :type :invoke, :f :append, :key "7", :value "x 7 10 y"}
{:process 5, :type :ok, :f :append, :key "7", :value "x 5 2 y"}
{:process 5, :type :invoke, :f :append, :key "1", :value "x 5 3 y"}
{:process 4, :type :ok, :f :append, :key "6", :value "x 4 17 y"}
{:process 4, :type :invoke, :f :get, :key "3", :value nil}
{:process 4, :type :ok, :f :get, :key "3", :value "x 4 3 yx 0 7 y"}
{:process 4, :type :invoke, :f :append, :key "1", :value "x 4 18 y"}
{:process 4, :type :ok, :f :append, :key "1", :value "x 4 18 y"}
{:process 4, :type :invoke, :f :get, :key "2", :value nil}
{:process 4, :type :ok, :f :get, :key "2", :value "x 4 6 yx 1 1 yx 6 2 yx 0 2 yx 7 8 y"}
{:process 4, :type :invoke, :f :append, :key "3", :value "x 4 19 y"}
{:process 4, :type :ok, :f :append, :key "3", :value "x 4 19 y"}
{:process 4, :type :invoke, :f :append, :key "7", :value "x 4 20 y"}
{:process 4, :type :ok, :f :append, :key "7", :value "x 4 20 y"}
{:process 4, :type :invoke, :f :get, :key "8", :value nil}
{:process 8, :type :ok, :f :get, :key "7", :value "x 1 2 yx 0 6 yx 5 2 yx 7 10 yx 4 20 y"}
{:process 8, :type :invoke, :f :get, :key "2", :value nil}
{:process 8, :type :ok, :f :get, :key "2", :value "x 4 6 yx 1 1 yx 6 2 yx 0 2 yx 7 8 y"}
{:process 8, :type :invoke, :f :put, :key "3", :value "x 8 0 y"}
{:process 8, :type :ok, :f :put, :key "3", :value "x 8 0 y"}
{:process 8, :type :invoke, :f :append, :key "4", :value "x 8 1 y"}
{:process 8, :type :ok, :f :append, :key "4", :value "x 8 1 y"}
{:process 8, :type :invoke, :f :append, :key "9", :value "x 8 2 y"}
{:process 8, :type :ok, :f :append, :key "9", :value "x 8 2 y"}
{:process 8, :type :invoke, :f :append, :key "9", :value "x 8 3 y"}
{:process 8, :type :ok, :f :append, :key "9", :value "x 8 3 y"}
{:process 8, :type :invoke, :f :append, :key "0", :value "x 8 4 y"}
{:process 6, :type :ok, :f :append, :key "9", :value "x 6 3 y"}
{:process 6, :type :invoke, :f :get, :key "3", :value nil}
{:process 1, :type :ok, :f :append, :key "4", :value "x 1 4 y"}
{:process 1, :type :invoke, :f :append, :key "5", :value "x 1 5 y"}
{:process 9, :type :ok, :f :put, :key "6", :value "x 9 3 y"}
{:process 9, :type :invoke, :f :get, :key "4", :value nil}
{:process 2, :type :ok, :f :append, :key "4", :value "x 2 6 y"}
{:process 2, :type :invoke, :f :append, :key "5", :value "x 2 7 y"}
{:process 9, :type :ok, :f :get, :key "4", :value "x 7 7 yx 5 1 yx 1 4 yx 2 6 yx 8 1 y"}
{:process 9, :type :invoke, :f :get, :key "4", :value nil}
{:process 2, :type :ok, :f :append, :key "5", :value "x 2 7 y"}
{:process 2, :type :invoke, :f :append, :key "6", :value "x 2 8 y"}
{:process 5, :type :ok, :f :append, :key "1", :value "x 5 3 y"}
{:process 5, :type :invoke, :f :append, :key "3", :value "x 5 4 y"}
{:process 2, :type :ok, :f :append, :key "6", :value "x 2 8 y"}
{:process 2, :type :invoke, :f :append, :key "5", :value "x 2 9 y"}
{:process 5, :type :ok, :f :append, :key "3", :value "x 5 4 y"}
{:process 5, :type :invoke, :f :get, :key "7", :value nil}
{:process 7, :type :ok, :f :append, :key "7", :value "x 7 10 y"}
{:process 7, :type :invoke, :f :get, :key "5", :value nil}
{:process 7, :type :ok, :f :get, :key "5", :value "x 9 1 yx 7 0 yx 3 1 yx 2 2 yx 6 1 yx 7 2 yx 4 9 yx 3 3 yx 0 5 yx 7 9 yx 2 5 yx 1 5 yx 2 7 y"}
{:process 7, :type :invoke, :f :put, :key "7", :value "x 7 11 y"}
{:process 5, :type :ok, :f :get, :key "7", :value "x 1 2 yx 0 6 yx 5 2 yx 7 10 yx 4 20 y"}
{:process 5, :type :invoke, :f :append, :key "0", :value "x 5 5 y"}
{:process 5, :type :ok, :f :append, :key "0", :value "x 5 5 y"}
{:process 5, :type :invoke, :f :get, :key "1", :value nil}
{:process 7, :type :ok, :f :put, :key "7", :value "x 7 11 y"}
{:process 7, :type :invoke, :f :append, :key "6", :value "x 7 12 y"}
{:process 5, :type :ok, :f :get, :key "1", :value "x 4 0 yx 4 1 yx 2 0 yx 2 1 yx 1 0 yx 4 15 yx 4 18 yx 5 3 y"}
{:process 5, :type :invoke, :f :append, :key "5", :value "x 5 6 y"}
{:process 5, :type :ok, :f :append, :key "5", :value "x 5 6 y"}
{:process 5, :type :invoke, :f :append, :key "0", :value "x 5 7 y"}
{:process 5, :type :ok, :f :append, :key "0", :value "x 5 7 y"}
{:process 5, :type :invoke, :f :get, :key "0", :value nil}
{:process 5, :type :ok, :f :get, :key "0", :value "x 9 0 yx 0 0 yx 3 2 yx 7 1 yx 0 4 yx 7 5 yx 7 6 yx 4 13 yx 4 14 yx 2 4 yx 8 4 yx 5 5 yx 5 7 y"}
{:process 5, :type :invoke, :f :append, :key "3", :value "x 5 8 y"}
{:process 5, :type :ok, :f :append, :key "3", :value "x 5 8 y"}
{:process 5, :type :invoke, :f :get, :key "3", :value nil}
{:process 5, :type :ok, :f :get, :key "3", :value "x 8 0 yx 5 4 yx 5 8 y"}
{:process 5, :type :invoke, :f :append, :key "8", :value "x 5 9 y"}
{:process 5, :type :ok, :f :append, :key "8", :value "x 5 9 y"}
{:process 5, :type :invoke, :f :append, :key "4", :value "x 5 10 y"}
{:process 5, :type :ok, :f :append, :key "4", :value "x 5 10 y"}
{:process 5, :type :invoke, :f :put, :key "5", :value "x 5 11 y"}
{:process 4, :type :ok, :f :get, :key "8", :value "x 4 8 yx 4 10 yx 0 1 yx 0 3 yx 3 4 yx 4 12 yx 5 9 y"}
{:process 4, :type :invoke, :f :put, :key "5", :value "x 4 21 y"}
{:process 5, :type :ok, :f :put, :key "5", :value "x 5 11 y"}
{:process 5, :type :invoke, :f :get, :key "4", :value nil}
{:process 5, :type :ok, :f :get, :key "4", :value "x 7 7 yx 5 1 yx 1 4 yx 2 6 yx 8 1 yx 5 10 y"}
{:process 5, :type :invoke, :f :get, :key "7", :value nil}
{:process 5, :type :ok, :f :get, :key "7", :value "x 7 11 y"}
{:process 5, :type :invoke, :f :get, :key "4", :value nil}
{:process 5, :type :ok, :f :get, :key "4", :value "x 7 7 yx 5 1 yx 1 4 yx 2 6 yx 8 1 yx 5 10 y"}
{:process 5, :type :invoke, :f :append, :key "0", :value "x 5 12 y"}
{:process 5, :type :ok, :f :append, :key "0", :value "x 5 12 y"}
{:process 5, :type :invoke, :f :get, :key "4", :value nil}
{:process 5, :type :ok, :f :get, :key "4", :value "x 7 7 yx 5 1 yx 1 4 yx 2 6 yx 8 1 yx 5 10 y"}
{:process 5, :type :invoke, :f :append, :key "5", :value "x 5 13 y"}
{:process 4, :type :ok, :f :put, :key "5", :value "x 4 21 y"}
{:process 7, :type :ok, :f :append, :key "6", :value "x 7 12 y"}
{:process 6, :type :ok, :f :get, :key "3", :value "x 8 0 yx 5 4 yx 5 8 y"}
{:process 5, :type :ok, :f :append, :key "5", :value "x 5 13 y"}
{:process 3, :type :ok, :f :get, :key "9", :value "x 4 4 yx 6 0 yx 3 0 yx 5 0 yx 7 3 yx 2 3 yx 8 2 yx 8 3 yx 6 3 y"}
{:process 0, :type :ok, :f :get, :key "1", :value "x 4 0 yx 4 1 yx 2 0 yx 2 1 yx 1 0 yx 4 15 yx 4 18 yx 5 3 y"}
{:process 8, :type :ok, :f :append, :key "0", :value "x 8 4 y"}
{:process 2, :type :ok, :f :append, :key "5", :value "x 2 9 y"}
{:process 9, :type :ok, :f :get, :key "4", :value "x 7 7 yx 5 1 yx 1 4 yx 2 6 yx 8 1 yx 5 10 y"}
{:process 1, :type :ok, :f :append, :key "5", :value "x 1 5 y"}
{:process 9, :type :invoke, :f :get, :key "8", :value nil}
{:process 3, :type :invoke, :f :append, :key "4", :value "x 3 0 y"}
{:process 4, :type :invoke, :f :get, :key "2", :value nil}
{:process 2, :type :invoke, :f :append, :key "4", :value "x 2 0 y"}
{:process 5, :type :invoke, :f :append, :key "8", :value "x 5 0 y"}
{:process 6, :type :invoke, :f :get, :key "6", :value nil}
{:process 0, :type :invoke, :f :put, :key "1", :value "x 0 0 y"}
{:process 7, :type :invoke, :f :append, :key "4", :value "x 7 0 y"}
{:process 8, :type :invoke, :f :append, :key "8", :value "x 8 0 y"}
{:process 1, :type :invoke, :f :append, :key "1", :value "x 1 0 y"}
{:process 8, :type :ok, :f :append, :key "8", :value "x 8 0 y"}
{:process 8, :type :invoke, :f :get, :key "6", :value nil}
{:process 8, :type :ok, :f :get, :key "6", :value "x 7 4 yx 4 11 yx 4 16 yx 4 17 yx 2 8 yx 7 12 y"}
{:process 8, :type :invoke, :f :get, :key "5", :value nil}
{:process 8, :type :ok, :f :get, :key "5", :value "x 5 11 yx 5 13 yx 2 9 y"}
{:process 8, :type :invoke, :f :append, :key "2", :value "x 8 1 y"}
{:process 8, :type :ok, :f :append, :key "2", :value "x 8 1 y"}
{:process 8, :type :invoke, :f :append, :key "1", :value "x 8 2 y"}
{:process 5, :type :ok, :f :append, :key "8", :value "x 5 0 y"}
{:process 5, :type :invoke, :f :append, :key "8", :value "x 5 1 y"}
{:process 5, :type :ok, :f :append, :key "8", :value "x 5 1 y"}
{:process 5, :type :invoke, :f :append, :key "8", :value "x 5 2 y"}
{:process 8, :type :ok, :f :append, :key "1", :value "x 8 2 y"}
{:process 8, :type :invoke, :f :append, :key "3", :value "x 8 3 y"}
{:process 8, :type :ok, :f :append, :key "3", :value "x 8 3 y"}
{:process 8, :type :invoke, :f :append, :key "2", :value "x 8 4 y"}
{:process 8, :type :ok, :f :append, :key "2", :value "x 8 4 y"}
{:process 8, :type :invoke, :f :get, :key "4", :value nil}
{:process 8, :type :ok, :f :get, :key "4", :value "x 7 7 yx 5 1 yx 1 4 yx 2 6 yx 8 1 yx 5 10 y"}
{:process 8, :type :invoke, :f :append, :key "5", :value "x 8 5 y"}
{:process 9, :type :ok, :f :get, :key "8", :value "x 4 8 yx 4 10 yx 0 1 yx 0 3 yx 3 4 yx 4 12 yx 5 9 yx 8 0 yx 5 0 yx 5 1 y"}
{:process 9, :type :invoke, :f :append, :key "7", :value "x 9 0 y"}
{:process 7, :type :ok, :f :append, :key "4", :value "x 7 0 y"}
{:process 7, :type :invoke, :f :get, :key "5", :value nil}
{:process 9, :type :ok, :f :append, :key "7", :value "x 9 0 y"}
{:process 9, :type :invoke, :f :append, :key "3", :value "x 9 1 y"}
{:process 8, :type :ok, :f :append, :key "5", :value "x 8 5 y"}
{:process 8, :type :invoke, :f :append, :key "7", :value "x 8 6 y"}
{:process 8, :type :ok, :f :append, :key "7", :value "x 8 6 y"}
{:process 8, :type :invoke, :f :get, :key "8", :value nil}
{:process 7, :type :ok, :f :get, :key "5", :value "x 5 11 yx 5 13 yx 2 9 yx 8 5 y"}
{:process 7, :type :invoke, :f :append, :key "3", :value "x 7 1 y"}
{:process 9, :type :ok, :f :append, :key "3", :value "x 9 1 y"}
{:process 9, :type :invoke, :f :get, :key "5", :value nil}
{:process 8, :type :ok, :f :get, :key "8", :value "x 4 8 yx 4 10 yx 0 1 yx 0 3 yx 3 4 yx 4 12 yx 5 9 yx 8 0 yx 5 0 yx 5 1 y"}
{:process 8, :type :invoke, :f :append, :key "3", :value "x 8 7 y"}
{:process 7, :type :ok, :f :append, :key "3", :value "x 7 1 y"}
{:process 7, :type :invoke, :f :get, :key "8", :value nil}
{:process 9, :type :ok, :f :get, :key "5", :value "x 5 11 yx 5 13 yx 2 9 yx 8 5 y"}
{:process 9, :type :invoke, :f :get, :key "1", :value nil}
{:process 7, :type :ok, :f :get, :key "8", :value "x 4 8 yx 4 10 yx 0 1 yx 0 3 yx 3 4 yx 4 12 yx 5 9 yx 8 0 yx 5 0 yx 5 1 y"}
{:process 7, :type :invoke, :f :get, :key "2", :value nil}
{:process 8, :type :ok, :f :append, :key "3", :value "x 8 7 y"}
{:process 8, :type :invoke, :f :get, :key "7", :value nil}
{:process 9, :type :ok, :f :get, :key "1", :value "x 4 0 yx 4 1 yx 2 0 yx 2 1 yx 1 0 yx 4 15 yx 4 18 yx 5 3 yx 8 2 y"}
{:process 9, :type :invoke, :f :get, :key "7", :value nil}
{:process 7, :type :ok, :f :get, :key "2", :value "x 4 6 yx 1 1 yx 6 2 yx 0 2 yx 7 8 yx 8 1 yx 8 4 y"}
{:process 7, :type :invoke, :f :append, :key "9", :value "x 7 2 y"}
{:process 7, :type :ok, :f :append, :key "9", :value "x 7 2 y"}
{:process 7, :type :invoke, :f :append, :key "9", :value "x 7 3 y"}
{:process 1, :type :ok, :f :append, :key "1", :value "x 1 0 y"}
{:process 1, :type :invoke, :f :append, :key "1", :value "x 1 1 y"}
{:process 8, :type :ok, :f :get, :key "7", :value "x 7 11 yx 9 0 yx 8 6 y"}
{:process 8, :type :invoke, :f :get, :key "1", :value nil}
{:process 1, :type :ok, :f :append, :key "1", :value "x 1 1 y"}
{:process 1, :type :invoke, :f :get, :key "6", :value nil}
{:process 8, :type :ok, :f :get, :key "1", :value "x 4 0 yx 4 1 yx 2 0 yx 2 1 yx 1 0 yx 4 15 yx 4 18 yx 5 3 yx 8 2 yx 1 0 yx 1 1 y"}
{:process 8, :type :invoke, :f :put, :key "8", :value "x 8 8 y"}
{:process 1, :type :ok, :f :get, :key "6", :value "x 7 4 yx 4 11 yx 4 16 yx 4 17 yx 2 8 yx 7 12 y"}
{:process 1, :type :invoke, :f :append, :key "7", :value "x 1 2 y"}
{:process 1, :type :ok, :f :append, :key "7", :value "x 1 2 y"}
{:process 1, :type :invoke, :f :append, :key "7", :value "x 1 3 y"}
{:process 3, :type :ok, :f :append, :key "4", :value "x 3 0 y"}
{:process 3, :type :invoke, :f :get, :key "5", :value nil}
{:process 1, :type :ok, :f :append, :key "7", :value "x 1 3 y"}
Download .txt
gitextract_2klmrfgy/

├── .circleci/
│   └── config.yml
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.md
│   │   ├── feature-requirement.md
│   │   └── question.md
│   └── pull_request_template.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── README.md
├── courses/
│   ├── README.md
│   ├── dss/
│   │   ├── .gitignore
│   │   ├── Cargo.toml
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── labcodec/
│   │   │   ├── Cargo.toml
│   │   │   ├── build.rs
│   │   │   ├── demonstration/
│   │   │   │   ├── README.md
│   │   │   │   └── expanded_fixture.rs
│   │   │   ├── proto/
│   │   │   │   └── fixture.proto
│   │   │   └── src/
│   │   │       └── lib.rs
│   │   ├── labrpc/
│   │   │   ├── Cargo.toml
│   │   │   ├── benches/
│   │   │   │   └── rpc.rs
│   │   │   ├── examples/
│   │   │   │   └── echo.rs
│   │   │   └── src/
│   │   │       ├── client.rs
│   │   │       ├── error.rs
│   │   │       ├── lib.rs
│   │   │       ├── macros.rs
│   │   │       ├── network.rs
│   │   │       └── server.rs
│   │   ├── linearizability/
│   │   │   ├── Cargo.toml
│   │   │   ├── src/
│   │   │   │   ├── bitset.rs
│   │   │   │   ├── lib.rs
│   │   │   │   ├── model.rs
│   │   │   │   └── models.rs
│   │   │   └── test_data/
│   │   │       ├── c01-bad.txt
│   │   │       ├── c01-ok.txt
│   │   │       ├── c10-bad.txt
│   │   │       ├── c10-ok.txt
│   │   │       ├── c50-bad.txt
│   │   │       └── c50-ok.txt
│   │   ├── percolator/
│   │   │   ├── Cargo.toml
│   │   │   ├── README.md
│   │   │   ├── build.rs
│   │   │   ├── proto/
│   │   │   │   └── msg.proto
│   │   │   └── src/
│   │   │       ├── client.rs
│   │   │       ├── lib.rs
│   │   │       ├── server.rs
│   │   │       ├── service.rs
│   │   │       └── tests.rs
│   │   └── raft/
│   │       ├── Cargo.toml
│   │       ├── README.md
│   │       ├── build.rs
│   │       └── src/
│   │           ├── kvraft/
│   │           │   ├── client.rs
│   │           │   ├── config.rs
│   │           │   ├── errors.rs
│   │           │   ├── mod.rs
│   │           │   ├── server.rs
│   │           │   └── tests.rs
│   │           ├── lib.rs
│   │           ├── proto/
│   │           │   ├── kvraft.proto
│   │           │   ├── mod.rs
│   │           │   └── raft.proto
│   │           └── raft/
│   │               ├── config.rs
│   │               ├── errors.rs
│   │               ├── mod.rs
│   │               ├── persister.rs
│   │               └── tests.rs
│   ├── rust/
│   │   ├── .gitignore
│   │   ├── CONTRIBUTING.md
│   │   ├── README.md
│   │   ├── building-blocks/
│   │   │   ├── bb-1.md
│   │   │   ├── bb-2.md
│   │   │   ├── bb-3.md
│   │   │   ├── bb-4.md
│   │   │   └── bb-5.md
│   │   ├── docs/
│   │   │   ├── etc/
│   │   │   │   ├── notes.md
│   │   │   │   └── parallel-diagrams.txt
│   │   │   ├── lesson-plan.md
│   │   │   ├── prerequisites.md
│   │   │   ├── roadmap.md
│   │   │   └── what-next.md
│   │   └── projects/
│   │       ├── project-1/
│   │       │   ├── Cargo.toml
│   │       │   ├── README.md
│   │       │   ├── src/
│   │       │   │   ├── bin/
│   │       │   │   │   └── kvs.rs
│   │       │   │   ├── kv.rs
│   │       │   │   └── lib.rs
│   │       │   └── tests/
│   │       │       └── tests.rs
│   │       ├── project-2/
│   │       │   ├── Cargo.toml
│   │       │   ├── README.md
│   │       │   ├── src/
│   │       │   │   ├── bin/
│   │       │   │   │   └── kvs.rs
│   │       │   │   ├── error.rs
│   │       │   │   ├── kv.rs
│   │       │   │   └── lib.rs
│   │       │   └── tests/
│   │       │       └── tests.rs
│   │       ├── project-3/
│   │       │   ├── Cargo.toml
│   │       │   ├── README.md
│   │       │   ├── benches/
│   │       │   │   └── engine_bench.rs
│   │       │   ├── src/
│   │       │   │   ├── bin/
│   │       │   │   │   ├── kvs-client.rs
│   │       │   │   │   └── kvs-server.rs
│   │       │   │   ├── client.rs
│   │       │   │   ├── common.rs
│   │       │   │   ├── engines/
│   │       │   │   │   ├── kvs.rs
│   │       │   │   │   ├── mod.rs
│   │       │   │   │   └── sled.rs
│   │       │   │   ├── error.rs
│   │       │   │   ├── lib.rs
│   │       │   │   └── server.rs
│   │       │   └── tests/
│   │       │       ├── cli.rs
│   │       │       └── kv_store.rs
│   │       ├── project-4/
│   │       │   ├── Cargo.toml
│   │       │   ├── README.md
│   │       │   ├── src/
│   │       │   │   ├── bin/
│   │       │   │   │   ├── kvs-client.rs
│   │       │   │   │   └── kvs-server.rs
│   │       │   │   ├── client.rs
│   │       │   │   ├── common.rs
│   │       │   │   ├── engines/
│   │       │   │   │   ├── kvs.rs
│   │       │   │   │   ├── mod.rs
│   │       │   │   │   └── sled.rs
│   │       │   │   ├── error.rs
│   │       │   │   ├── lib.rs
│   │       │   │   ├── server.rs
│   │       │   │   └── thread_pool/
│   │       │   │       ├── mod.rs
│   │       │   │       ├── naive.rs
│   │       │   │       ├── rayon.rs
│   │       │   │       └── shared_queue.rs
│   │       │   └── tests/
│   │       │       ├── cli.rs
│   │       │       ├── kv_store.rs
│   │       │       └── thread_pool.rs
│   │       └── project-5/
│   │           ├── Cargo.toml
│   │           ├── README.md
│   │           ├── src/
│   │           │   ├── bin/
│   │           │   │   ├── kvs-client.rs
│   │           │   │   └── kvs-server.rs
│   │           │   ├── client.rs
│   │           │   ├── common.rs
│   │           │   ├── engines/
│   │           │   │   ├── kvs.rs
│   │           │   │   ├── mod.rs
│   │           │   │   └── sled.rs
│   │           │   ├── error.rs
│   │           │   ├── lib.rs
│   │           │   ├── server.rs
│   │           │   └── thread_pool/
│   │           │       ├── mod.rs
│   │           │       ├── naive.rs
│   │           │       ├── rayon.rs
│   │           │       └── shared_queue.rs
│   │           └── tests/
│   │               ├── cli.rs
│   │               ├── kv_store.rs
│   │               └── thread_pool.rs
│   ├── tp101-intro-to-oss.md
│   ├── tp102-how-to-use-git-github.md
│   └── tp103-open-source-community.md
├── talent-challenge-program/
│   ├── MENTEE_APPLY_TEMPLATE.md
│   ├── PROJECT_IDEA_TEMPLATE.md
│   ├── README.md
│   ├── project-ideas.md
│   ├── s1.md
│   └── selected-projects.md
├── talent-challenge-program2021/
│   ├── MENTEE_APPLY_TEMPLATE.md
│   ├── PROJECT_IDEA_TEMPLATE.md
│   ├── README.md
│   ├── project-ideas.md
│   ├── schedule.md
│   └── selected-projects.md
├── talent-plan-1.0/
│   ├── 1.0-lp-tidb.md
│   ├── 1.0-lp-tikv.md
│   └── README-CN.md
└── tidb/
    ├── .gitignore
    ├── README.md
    ├── join/
    │   ├── Makefile
    │   ├── README.md
    │   ├── benchmark_test.go
    │   ├── go.mod
    │   ├── go.sum
    │   ├── join.go
    │   ├── join_example.go
    │   ├── join_test.go
    │   └── t/
    │       ├── r0.tbl
    │       ├── r1.tbl
    │       └── r2.tbl
    ├── mapreduce/
    │   ├── .gitignore
    │   ├── Makefile
    │   ├── README.md
    │   ├── casegen.go
    │   ├── go.mod
    │   ├── go.sum
    │   ├── mapreduce.go
    │   ├── urltop10.go
    │   ├── urltop10_example.go
    │   ├── urltop10_test.go
    │   └── utils.go
    └── mergesort/
        ├── Makefile
        ├── README.md
        ├── bench_test.go
        ├── go.mod
        ├── go.sum
        ├── mergesort.go
        └── mergesort_test.go
Download .txt
SYMBOL INDEX (869 symbols across 94 files)

FILE: courses/dss/labcodec/build.rs
  function main (line 1) | fn main() {

FILE: courses/dss/labcodec/demonstration/expanded_fixture.rs
  type Msg (line 2) | pub struct Msg {
    method clone (line 16) | fn clone(&self) -> Msg {
    method eq (line 37) | fn eq(&self, other: &Msg) -> bool {
    method ne (line 60) | fn ne(&self, other: &Msg) -> bool {
    method encode_raw (line 85) | fn encode_raw<B>(&self, buf: &mut B)
    method merge_field (line 101) | fn merge_field<B>(
    method encoded_len (line 147) | fn encoded_len(&self) -> usize {
    method clear (line 162) | fn clear(&mut self) {
    method fmt (line 180) | fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
    method r#type (line 240) | pub fn r#type(&self) -> msg::Type {
    method set_type (line 244) | pub fn set_type(&mut self, value: msg::Type) {
  method default (line 170) | fn default() -> Msg {
  type Type (line 250) | pub enum Type {
    method clone (line 260) | fn clone(&self) -> Type {
    method fmt (line 272) | fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
    method eq (line 298) | fn eq(&self, other: &Type) -> bool {
    method assert_receiver_is_total_eq (line 318) | fn assert_receiver_is_total_eq(&self) -> () {
    method hash (line 325) | fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
    method partial_cmp (line 338) | fn partial_cmp(&self, other: &Type) -> ::core::option::Option<::core::...
    method cmp (line 356) | fn cmp(&self, other: &Type) -> ::core::cmp::Ordering {
    method is_valid (line 372) | pub fn is_valid(value: i32) -> bool {
    method from_i32 (line 382) | pub fn from_i32(value: i32) -> ::std::option::Option<Type> {
    method default (line 393) | fn default() -> Type {
  function from (line 398) | fn from(value: Type) -> i32 {

FILE: courses/dss/labcodec/src/lib.rs
  type Message (line 4) | pub trait Message: prost::Message + Default {}
  type EncodeError (line 8) | pub type EncodeError = prost::EncodeError;
  type DecodeError (line 10) | pub type DecodeError = prost::DecodeError;
  function encode (line 13) | pub fn encode<M: Message>(message: &M, buf: &mut Vec<u8>) -> Result<(), ...
  function decode (line 20) | pub fn decode<M: Message>(buf: &[u8]) -> Result<M, DecodeError> {
  function test_basic_encode_decode (line 61) | fn test_basic_encode_decode() {
  function test_default (line 75) | fn test_default() {

FILE: courses/dss/labrpc/benches/rpc.rs
  type BenchArgs (line 20) | pub struct BenchArgs {
  type BenchReply (line 26) | pub struct BenchReply {
  type BenchInner (line 32) | struct BenchInner {
  type BenchService (line 36) | pub struct BenchService {
    method new (line 40) | fn new() -> BenchService {
  method handler (line 49) | async fn handler(&self, args: BenchArgs) -> Result<BenchReply> {
  function bench_suit (line 57) | fn bench_suit() -> (Network, Server, BenchService) {
  function bench_rpc (line 68) | fn bench_rpc(c: &mut Criterion) {

FILE: courses/dss/labrpc/examples/echo.rs
  type Echo (line 8) | pub struct Echo {
  type EchoService (line 21) | struct EchoService;
  method ping (line 25) | async fn ping(&self, input: Echo) -> Result<Echo> {
  function main (line 30) | fn main() {

FILE: courses/dss/labrpc/src/client.rs
  type Rpc (line 12) | pub struct Rpc {
    method take_resp_sender (line 21) | pub(crate) fn take_resp_sender(&mut self) -> Option<oneshot::Sender<Re...
    method fmt (line 27) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  type RpcHooks (line 35) | pub trait RpcHooks: Sync + Send + 'static {
    method before_dispatch (line 36) | fn before_dispatch(&self, fq_name: &str, req: &[u8]) -> Result<()>;
    method after_dispatch (line 37) | fn after_dispatch(&self, fq_name: &str, resp: Result<Vec<u8>>) -> Resu...
  type Client (line 41) | pub struct Client {
    method call (line 52) | pub fn call<Req, Rsp>(&self, fq_name: &'static str, req: &Req) -> RpcF...
    method set_hooks (line 85) | pub fn set_hooks(&self, hooks: Arc<dyn RpcHooks>) {
    method clear_hooks (line 89) | pub fn clear_hooks(&self) {

FILE: courses/dss/labrpc/src/error.rs
  type Error (line 8) | pub enum Error {
    method fmt (line 19) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    method source (line 25) | fn source(&self) -> Option<&(dyn error::Error + 'static)> {
  type Result (line 35) | pub type Result<T> = result::Result<T, Error>;

FILE: courses/dss/labrpc/src/lib.rs
  type JunkArgs (line 43) | pub struct JunkArgs {
  type JunkReply (line 48) | pub struct JunkReply {
  type JunkInner (line 54) | struct JunkInner {
  type JunkService (line 58) | struct JunkService {
    method new (line 62) | fn new() -> JunkService {
  method handler2 (line 70) | async fn handler2(&self, args: JunkArgs) -> Result<JunkReply> {
  method handler3 (line 76) | async fn handler3(&self, args: JunkArgs) -> Result<JunkReply> {
  method handler4 (line 82) | async fn handler4(&self, _: JunkArgs) -> Result<JunkReply> {
  function init_logger (line 89) | fn init_logger() {
  function test_service_dispatch (line 95) | fn test_service_dispatch() {
  function test_network_client_rpc (line 128) | fn test_network_client_rpc() {
  function junk_suit (line 186) | fn junk_suit() -> (Network, Server, JunkService) {
  function test_basic (line 198) | fn test_basic() {
  function test_disconnect (line 218) | fn test_disconnect() {
  function test_count (line 241) | fn test_count() {
  function test_concurrent_many (line 260) | fn test_concurrent_many() {
  function test_unreliable (line 304) | fn test_unreliable() {
  function test_concurrent_one (line 348) | fn test_concurrent_one() {
  function test_regression1 (line 397) | fn test_regression1() {
  function test_killed (line 460) | fn test_killed() {
  type Hooks (line 484) | struct Hooks {
  method before_dispatch (line 489) | fn before_dispatch(&self, _: &str, _: &[u8]) -> Result<()> {
  method after_dispatch (line 496) | fn after_dispatch(&self, _: &str, resp: Result<Vec<u8>>) -> Result<Vec<u...
  function test_rpc_hooks (line 506) | fn test_rpc_hooks() {

FILE: courses/dss/labrpc/src/network.rs
  type EndInfo (line 21) | struct EndInfo {
  type Endpoints (line 28) | struct Endpoints {
  type NetworkCore (line 37) | struct NetworkCore {
  type Network (line 51) | pub struct Network {
    method new (line 56) | pub fn new() -> Network {
    method create (line 62) | pub fn create() -> (Network, UnboundedReceiver<Rpc>) {
    method start (line 84) | fn start(&self, mut incoming: UnboundedReceiver<Rpc>) {
    method add_server (line 100) | pub fn add_server(&self, server: Server) {
    method delete_server (line 105) | pub fn delete_server(&self, name: &str) {
    method create_client (line 112) | pub fn create_client(&self, name: String) -> Client {
    method connect (line 127) | pub fn connect(&self, client_name: &str, server_name: &str) {
    method enable (line 134) | pub fn enable(&self, client_name: &str, enabled: bool) {
    method set_reliable (line 144) | pub fn set_reliable(&self, yes: bool) {
    method set_long_reordering (line 148) | pub fn set_long_reordering(&self, yes: bool) {
    method set_long_delays (line 152) | pub fn set_long_delays(&self, yes: bool) {
    method count (line 156) | pub fn count(&self, server_name: &str) -> usize {
    method total_count (line 161) | pub fn total_count(&self) -> usize {
    method end_info (line 165) | fn end_info(&self, client_name: &str) -> EndInfo {
    method is_server_dead (line 179) | fn is_server_dead(&self, client_name: &str, server_name: &str, server_...
    method process_rpc (line 187) | async fn process_rpc(&self, rpc: Rpc) -> Result<Vec<u8>> {
    method spawn (line 256) | pub fn spawn<F>(&self, f: F)
    method spawn_poller (line 264) | pub fn spawn_poller<F>(&self, f: F)
  function process_rpc (line 272) | async fn process_rpc(
  function server_dead (line 344) | async fn server_dead(

FILE: courses/dss/labrpc/src/server.rs
  type RpcFuture (line 12) | pub type RpcFuture<T> = BoxFuture<'static, T>;
  type Handler (line 14) | pub type Handler = dyn FnOnce(&[u8]) -> RpcFuture<Result<Vec<u8>>>;
  type HandlerFactory (line 16) | pub trait HandlerFactory: Sync + Send + 'static {
    method handler (line 17) | fn handler(&self, name: &'static str) -> Box<Handler>;
  type ServerBuilder (line 20) | pub struct ServerBuilder {
    method new (line 27) | pub fn new(name: String) -> ServerBuilder {
    method add_service (line 34) | pub fn add_service(
    method build (line 51) | pub fn build(self) -> Server {
  type ServerCore (line 63) | pub(crate) struct ServerCore {
  type Server (line 72) | pub struct Server {
    method count (line 77) | pub fn count(&self) -> usize {
    method name (line 81) | pub fn name(&self) -> &str {
    method dispatch (line 85) | pub(crate) fn dispatch(&self, fq_name: &'static str, req: &[u8]) -> Rp...
    method fmt (line 119) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

FILE: courses/dss/linearizability/src/bitset.rs
  type Bitset (line 4) | pub struct Bitset(Vec<u64>);
    method new (line 7) | pub fn new(bits: usize) -> Self {
    method set (line 12) | pub fn set(&mut self, pos: usize) {
    method clear (line 17) | pub fn clear(&mut self, pos: usize) {
    method popcnt (line 22) | fn popcnt(&self) -> usize {
    method hash (line 35) | pub fn hash(&self) -> u64 {
    method equals (line 43) | pub fn equals(&self, b2: &Bitset) -> bool {
  function bitset_index (line 58) | fn bitset_index(pos: usize) -> (usize, usize) {

FILE: courses/dss/linearizability/src/lib.rs
  type EntryKind (line 18) | enum EntryKind {
  type Entry (line 23) | struct Entry<T> {
  function make_entries (line 30) | fn make_entries<I: Debug, O: Debug>(history: Operations<I, O>) -> Vec<En...
  type LinkedNodes (line 50) | struct LinkedNodes<T: Debug> {
  function new (line 55) | pub fn new() -> Self {
  function head (line 59) | pub fn head(&self) -> Option<LinkNode<T>> {
  function from_entries (line 63) | pub fn from_entries(entries: Vec<Entry<T>>) -> Self {
  function len (line 93) | pub fn len(&self) -> usize {
  function push_front (line 103) | pub fn push_front(&mut self, new_head: LinkNode<T>) {
  type LinkNode (line 117) | type LinkNode<T> = Rc<RefCell<Node<T>>>;
  type Node (line 119) | struct Node<T: Debug> {
  function renumber (line 127) | fn renumber<T>(events: Vec<Event<T>>) -> Vec<Event<T>> {
  function convert_entries (line 144) | fn convert_entries<T>(events: Vec<Event<T>>) -> Vec<Entry<T>> {
  type CacheEntry (line 165) | struct CacheEntry<T> {
  function cache_contains (line 170) | fn cache_contains<M: Model>(
  type CallsEntry (line 185) | struct CallsEntry<V: Debug, T> {
  function lift (line 190) | fn lift<T: Debug>(entry: &LinkNode<T>) {
  function unlift (line 205) | fn unlift<T: Debug>(entry: &LinkNode<T>) {
  function check_single (line 222) | fn check_single<M: Model>(
  function check_operations (line 294) | pub fn check_operations<M: Model>(model: M, history: Operations<M::Input...
  function check_operations_timeout (line 300) | pub fn check_operations_timeout<M: Model>(
  function check_events (line 329) | pub fn check_events<M: Model>(model: M, history: Events<M::Input, M::Out...
  function check_events_timeout (line 335) | pub fn check_events_timeout<M: Model>(
  function wait_res (line 364) | fn wait_res(

FILE: courses/dss/linearizability/src/model.rs
  type Value (line 7) | pub enum Value<I: Debug, O: Debug> {
  function input (line 14) | pub fn input(&self) -> &I {
  function output (line 22) | pub fn output(&self) -> &O {
  type Operation (line 32) | pub struct Operation<I: Debug, O: Debug> {
  type EventKind (line 39) | pub enum EventKind {
  type Event (line 44) | pub struct Event<T> {
  type Operations (line 50) | pub type Operations<I, O> = Vec<Operation<I, O>>;
  type Events (line 51) | pub type Events<I, O> = Vec<Event<Value<I, O>>>;
  type Model (line 53) | pub trait Model: Clone + Send + 'static {
    method partition (line 62) | fn partition(
    method partition_event (line 69) | fn partition_event(
    method init (line 77) | fn init(&self) -> Self::State;
    method step (line 82) | fn step(
    method equal (line 91) | fn equal(&self, state1: &Self::State, state2: &Self::State) -> bool {

FILE: courses/dss/linearizability/src/models.rs
  type Op (line 6) | pub enum Op {
  type KvInput (line 13) | pub struct KvInput {
  type KvOutput (line 20) | pub struct KvOutput {
  type KvModel (line 25) | pub struct KvModel {}
  type State (line 28) | type State = String;
  type Input (line 29) | type Input = KvInput;
  type Output (line 30) | type Output = KvOutput;
  method partition (line 32) | fn partition(
  method partition_event (line 48) | fn partition_event(
  method init (line 74) | fn init(&self) -> Self::State {
  method step (line 80) | fn step(
  function check_kv (line 105) | fn check_kv(log_name: String, correct: bool) {
  function parse_kv_log (line 116) | fn parse_kv_log(
  function test_kv_1client_ok (line 238) | fn test_kv_1client_ok() {
  function test_kv_1client_bad (line 243) | fn test_kv_1client_bad() {
  function test_kv_10client_ok (line 248) | fn test_kv_10client_ok() {
  function test_kv_10client_bad (line 253) | fn test_kv_10client_bad() {
  function test_kv_50client_ok (line 258) | fn test_kv_50client_ok() {
  function test_kv_50client_bad (line 263) | fn test_kv_50client_bad() {

FILE: courses/dss/percolator/build.rs
  function main (line 1) | fn main() {

FILE: courses/dss/percolator/src/client.rs
  constant BACKOFF_TIME_MS (line 12) | const BACKOFF_TIME_MS: u64 = 100;
  constant RETRY_TIMES (line 14) | const RETRY_TIMES: usize = 3;
  type Client (line 20) | pub struct Client {
    method new (line 26) | pub fn new(tso_client: TSOClient, txn_client: TransactionClient) -> Cl...
    method get_timestamp (line 32) | pub fn get_timestamp(&self) -> Result<u64> {
    method begin (line 38) | pub fn begin(&mut self) {
    method get (line 44) | pub fn get(&self, key: Vec<u8>) -> Result<Vec<u8>> {
    method set (line 50) | pub fn set(&mut self, key: Vec<u8>, value: Vec<u8>) {
    method commit (line 56) | pub fn commit(&self) -> Result<bool> {

FILE: courses/dss/percolator/src/server.rs
  constant TTL (line 12) | const TTL: u64 = Duration::from_millis(100).as_nanos() as u64;
  type TimestampOracle (line 15) | pub struct TimestampOracle {
    method get_timestamp (line 22) | async fn get_timestamp(&self, _: TimestampRequest) -> labrpc::Result<T...
  type Key (line 29) | pub type Key = (Vec<u8>, u64);
  type Value (line 32) | pub enum Value {
  type Write (line 38) | pub struct Write(Vec<u8>, Vec<u8>);
  type Column (line 40) | pub enum Column {
  type KvTable (line 49) | pub struct KvTable {
    method read (line 59) | fn read(
    method write (line 72) | fn write(&mut self, key: Vec<u8>, column: Column, ts: u64, value: Valu...
    method erase (line 79) | fn erase(&mut self, key: Vec<u8>, column: Column, commit_ts: u64) {
  type MemoryStorage (line 88) | pub struct MemoryStorage {
    method get (line 95) | async fn get(&self, req: GetRequest) -> labrpc::Result<GetResponse> {
    method prewrite (line 101) | async fn prewrite(&self, req: PrewriteRequest) -> labrpc::Result<Prewr...
    method commit (line 107) | async fn commit(&self, req: CommitRequest) -> labrpc::Result<CommitRes...
    method back_off_maybe_clean_up_lock (line 114) | fn back_off_maybe_clean_up_lock(&self, start_ts: u64, key: Vec<u8>) {

FILE: courses/dss/percolator/src/tests.rs
  type CommitHooks (line 15) | struct CommitHooks {
  method before_dispatch (line 22) | fn before_dispatch(&self, fq_name: &str, req: &[u8]) -> Result<()> {
  method after_dispatch (line 32) | fn after_dispatch(&self, fq_name: &str, resp: Result<Vec<u8>>) -> Result...
  function init_logger (line 40) | fn init_logger() {
  function init (line 46) | fn init(num_clinet: usize) -> (Network, Vec<Client>, Arc<CommitHooks>) {
  function test_get_timestamp_under_unreliable_network (line 89) | fn test_get_timestamp_under_unreliable_network() {
  function test_predicate_many_preceders_read_predicates (line 121) | fn test_predicate_many_preceders_read_predicates() {
  function test_predicate_many_preceders_write_predicates (line 144) | fn test_predicate_many_preceders_write_predicates() {
  function test_lost_update (line 170) | fn test_lost_update() {
  function test_read_skew_read_only (line 196) | fn test_read_skew_read_only() {
  function test_read_skew_predicate_dependencies (line 224) | fn test_read_skew_predicate_dependencies() {
  function test_read_skew_write_predicate (line 250) | fn test_read_skew_write_predicate() {
  function test_write_skew (line 279) | fn test_write_skew() {
  function test_anti_dependency_cycles (line 308) | fn test_anti_dependency_cycles() {
  function test_commit_primary_drop_secondary_requests (line 336) | fn test_commit_primary_drop_secondary_requests() {
  function test_commit_primary_success (line 355) | fn test_commit_primary_success() {
  function test_commit_primary_success_without_response (line 374) | fn test_commit_primary_success_without_response() {
  function test_commit_primary_fail (line 393) | fn test_commit_primary_fail() {

FILE: courses/dss/raft/build.rs
  function main (line 1) | fn main() {

FILE: courses/dss/raft/src/kvraft/client.rs
  type Op (line 5) | enum Op {
  type Clerk (line 10) | pub struct Clerk {
    method fmt (line 17) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method new (line 23) | pub fn new(name: String, servers: Vec<KvClient>) -> Clerk {
    method get (line 35) | pub fn get(&self, key: String) -> String {
    method put_append (line 44) | fn put_append(&self, op: Op) {
    method put (line 49) | pub fn put(&self, key: String, value: String) {
    method append (line 53) | pub fn append(&self, key: String, value: String) {

FILE: courses/dss/raft/src/kvraft/config.rs
  function uniqstring (line 17) | fn uniqstring() -> String {
  type Servers (line 21) | struct Servers {
  function init_logger (line 27) | fn init_logger() {
  type Config (line 33) | pub struct Config {
    method new (line 54) | pub fn new(n: usize, unreliable: bool, maxraftstate: Option<usize>) ->...
    method op (line 88) | pub fn op(&self) {
    method rpc_total (line 92) | fn rpc_total(&self) -> usize {
    method check_timeout (line 96) | pub fn check_timeout(&self) {
    method log_size (line 104) | pub fn log_size(&self) -> usize {
    method snapshot_size (line 117) | pub fn snapshot_size(&self) -> usize {
    method connect (line 130) | fn connect(&self, i: usize, to: &[usize], servers: &Servers) {
    method disconnect (line 146) | fn disconnect(&self, i: usize, from: &[usize], servers: &Servers) {
    method all (line 165) | pub fn all(&self) -> Vec<usize> {
    method connect_all (line 169) | pub fn connect_all(&self) {
    method partition (line 177) | pub fn partition(&self, p1: &[usize], p2: &[usize]) {
    method make_client (line 193) | pub fn make_client(&self, to: &[usize]) -> client::Clerk {
    method delete_client (line 214) | pub fn delete_client(&self, ck: &client::Clerk) {
    method connect_client (line 218) | pub fn connect_client(&self, ck: &client::Clerk, to: &[usize]) {
    method connect_client_by_name (line 222) | pub fn connect_client_by_name(&self, ck_name: &str, to: &[usize]) {
    method shutdown_server (line 233) | pub fn shutdown_server(&self, i: usize) {
    method start_server (line 260) | pub fn start_server(&self, i: usize) {
    method leader (line 295) | pub fn leader(&self) -> Result<usize> {
    method make_partition (line 308) | pub fn make_partition(&self) -> (Vec<usize>, Vec<usize>) {
    method begin (line 328) | pub fn begin(&self, description: &str) {
    method end (line 340) | pub fn end(&self) {
  method drop (line 358) | fn drop(&mut self) {

FILE: courses/dss/raft/src/kvraft/errors.rs
  type Error (line 4) | pub enum Error {
    method fmt (line 9) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method source (line 15) | fn source(&self) -> Option<&(dyn error::Error + 'static)> {
  type Result (line 22) | pub type Result<T> = result::Result<T, Error>;

FILE: courses/dss/raft/src/kvraft/server.rs
  type KvServer (line 6) | pub struct KvServer {
    method new (line 15) | pub fn new(
    method __suppress_deadcode (line 33) | pub fn __suppress_deadcode(&mut self) {
  type Node (line 54) | pub struct Node {
    method new (line 59) | pub fn new(kv: KvServer) -> Node {
    method kill (line 68) | pub fn kill(&self) {
    method term (line 78) | pub fn term(&self) -> u64 {
    method is_leader (line 83) | pub fn is_leader(&self) -> bool {
    method get_state (line 87) | pub fn get_state(&self) -> raft::State {
  method get (line 98) | async fn get(&self, arg: GetRequest) -> labrpc::Result<GetReply> {
  method put_append (line 104) | async fn put_append(&self, arg: PutAppendRequest) -> labrpc::Result<PutA...

FILE: courses/dss/raft/src/kvraft/tests.rs
  constant RAFT_ELECTION_TIMEOUT (line 25) | const RAFT_ELECTION_TIMEOUT: Duration = Duration::from_millis(1000);
  constant LINEARIZABILITY_CHECK_TIMEOUT (line 27) | const LINEARIZABILITY_CHECK_TIMEOUT: Duration = Duration::from_millis(10...
  function get (line 30) | fn get(cfg: &Config, ck: &Clerk, key: &str) -> String {
  function put (line 36) | fn put(cfg: &Config, ck: &Clerk, key: &str, value: &str) {
  function append (line 41) | fn append(cfg: &Config, ck: &Clerk, key: &str, value: &str) {
  function check (line 46) | fn check(cfg: &Config, ck: &Clerk, key: &str, value: &str) {
  function spawn_clients_and_wait (line 54) | fn spawn_clients_and_wait<Func, Fact>(
  function next_value (line 85) | fn next_value(prev: String, val: &str) -> String {
  function check_clnt_appends (line 91) | fn check_clnt_appends(clnt: usize, v: String, count: usize) {
  function check_concurrent_appends (line 119) | fn check_concurrent_appends(v: String, counts: &[usize]) {
  function partitioner (line 148) | fn partitioner(
  function generic_test (line 189) | fn generic_test(
  function generic_test_linearizability (line 359) | fn generic_test_linearizability(
  function test_basic_3a (line 558) | fn test_basic_3a() {
  function test_concurrent_3a (line 564) | fn test_concurrent_3a() {
  function test_unreliable_3a (line 570) | fn test_unreliable_3a() {
  function test_unreliable_one_key_3a (line 576) | fn test_unreliable_one_key_3a() {
  function test_one_partition_3a (line 617) | fn test_one_partition_3a() {
  function test_many_partitions_one_client_3a (line 738) | fn test_many_partitions_one_client_3a() {
  function test_many_partitions_many_clients_3a (line 744) | fn test_many_partitions_many_clients_3a() {
  function test_persist_one_client_3a (line 750) | fn test_persist_one_client_3a() {
  function test_persist_concurrent_3a (line 756) | fn test_persist_concurrent_3a() {
  function test_persist_concurrent_unreliable_3a (line 762) | fn test_persist_concurrent_unreliable_3a() {
  function test_persist_partition_3a (line 768) | fn test_persist_partition_3a() {
  function test_persist_partition_unreliable_3a (line 774) | fn test_persist_partition_unreliable_3a() {
  function test_persist_partition_unreliable_linearizable_3a (line 780) | fn test_persist_partition_unreliable_linearizable_3a() {
  function test_snapshot_rpc_3b (line 790) | fn test_snapshot_rpc_3b() {
  function test_snapshot_size_3b (line 852) | fn test_snapshot_size_3b() {
  function test_snapshot_recover_3b (line 893) | fn test_snapshot_recover_3b() {
  function test_snapshot_recover_many_clients_3b (line 899) | fn test_snapshot_recover_many_clients_3b() {
  function test_snapshot_unreliable_3b (line 905) | fn test_snapshot_unreliable_3b() {
  function test_snapshot_unreliable_recover_3b (line 911) | fn test_snapshot_unreliable_recover_3b() {
  function test_snapshot_unreliable_recover_concurrent_partition_3b (line 917) | fn test_snapshot_unreliable_recover_concurrent_partition_3b() {
  function test_snapshot_unreliable_recover_concurrent_partition_linearizable_3b (line 923) | fn test_snapshot_unreliable_recover_concurrent_partition_linearizable_3b...

FILE: courses/dss/raft/src/lib.rs
  function your_code_here (line 13) | fn your_code_here<T>(_: T) -> ! {

FILE: courses/dss/raft/src/raft/config.rs
  constant SNAPSHOT_INTERVAL (line 16) | pub const SNAPSHOT_INTERVAL: u64 = 10;
  function uniqstring (line 18) | fn uniqstring() -> String {
  type Entry (line 25) | pub struct Entry {
  type Storage (line 30) | pub struct Storage {
    method n_committed (line 39) | pub fn n_committed(&self, index: u64) -> (usize, Option<Entry>) {
  function init_logger (line 59) | fn init_logger() {
  type Config (line 65) | pub struct Config {
    method new (line 92) | pub fn new(n: usize) -> Config {
    method new_with (line 96) | pub fn new_with(n: usize, unreliable: bool, snapshot: bool) -> Config {
    method rpc_count (line 139) | pub fn rpc_count(&self, server: usize) -> usize {
    method rpc_total (line 143) | fn rpc_total(&self) -> usize {
    method log_size (line 148) | pub fn log_size(&self) -> usize {
    method check_one_leader (line 158) | pub fn check_one_leader(&self) -> usize {
    method check_terms (line 199) | pub fn check_terms(&self) -> u64 {
    method check_no_leader (line 215) | pub fn check_no_leader(&self) {
    method check_timeout (line 226) | pub fn check_timeout(&self) {
    method n_committed (line 234) | pub fn n_committed(&self, index: u64) -> (usize, Option<Entry>) {
    method wait (line 241) | pub fn wait(&self, index: u64, n: usize, start_term: Option<u64>) -> O...
    method one (line 283) | pub fn one(&self, cmd: Entry, expected_servers: usize, retry: bool) ->...
    method begin (line 335) | pub fn begin(&mut self, description: &str) {
    method end (line 348) | pub fn end(&self) {
    method start1 (line 371) | pub fn start1(&mut self, i: usize) {
    method start1_snapshot (line 375) | pub fn start1_snapshot(&mut self, i: usize) {
    method start1_ext (line 379) | fn start1_ext(&mut self, i: usize, snapshot: bool) {
    method crash1 (line 465) | pub fn crash1(&mut self, i: usize) {
    method disconnect (line 486) | pub fn disconnect(&mut self, i: usize) {
    method connect (line 504) | pub fn connect(&mut self, i: usize) {
  method drop (line 528) | fn drop(&mut self) {

FILE: courses/dss/raft/src/raft/errors.rs
  type Error (line 4) | pub enum Error {
    method fmt (line 12) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    method source (line 18) | fn source(&self) -> Option<&(dyn error::Error + 'static)> {
  type Result (line 28) | pub type Result<T> = result::Result<T, Error>;

FILE: courses/dss/raft/src/raft/mod.rs
  type ApplyMsg (line 20) | pub enum ApplyMsg {
  type State (line 35) | pub struct State {
    method term (line 42) | pub fn term(&self) -> u64 {
    method is_leader (line 46) | pub fn is_leader(&self) -> bool {
  type Raft (line 52) | pub struct Raft {
    method new (line 74) | pub fn new(
    method persist (line 99) | fn persist(&mut self) {
    method restore (line 108) | fn restore(&mut self, data: &[u8]) {
    method send_request_vote (line 142) | fn send_request_vote(
    method start (line 163) | fn start<M>(&self, command: &M) -> Result<(u64, u64)>
    method cond_install_snapshot (line 181) | fn cond_install_snapshot(
    method snapshot (line 191) | fn snapshot(&mut self, index: u64, snapshot: &[u8]) {
    method __suppress_deadcode (line 200) | pub fn __suppress_deadcode(&mut self) {
  type Node (line 228) | pub struct Node {
    method new (line 234) | pub fn new(raft: Raft) -> Node {
    method start (line 251) | pub fn start<M>(&self, command: &M) -> Result<(u64, u64)>
    method term (line 262) | pub fn term(&self) -> u64 {
    method is_leader (line 270) | pub fn is_leader(&self) -> bool {
    method get_state (line 278) | pub fn get_state(&self) -> State {
    method kill (line 293) | pub fn kill(&self) {
    method cond_install_snapshot (line 301) | pub fn cond_install_snapshot(
    method snapshot (line 317) | pub fn snapshot(&self, index: u64, snapshot: &[u8]) {
  method request_vote (line 330) | async fn request_vote(&self, args: RequestVoteArgs) -> labrpc::Result<Re...

FILE: courses/dss/raft/src/raft/persister.rs
  type Persister (line 10) | pub trait Persister: Send + 'static {
    method raft_state (line 11) | fn raft_state(&self) -> Vec<u8>;
    method save_raft_state (line 12) | fn save_raft_state(&self, state: Vec<u8>);
    method save_state_and_snapshot (line 13) | fn save_state_and_snapshot(&self, state: Vec<u8>, snapshot: Vec<u8>);
    method snapshot (line 14) | fn snapshot(&self) -> Vec<u8>;
    method raft_state (line 18) | fn raft_state(&self) -> Vec<u8> {
    method save_raft_state (line 21) | fn save_raft_state(&self, state: Vec<u8>) {
    method save_state_and_snapshot (line 24) | fn save_state_and_snapshot(&self, state: Vec<u8>, snapshot: Vec<u8>) {
    method snapshot (line 27) | fn snapshot(&self) -> Vec<u8> {
    method raft_state (line 33) | fn raft_state(&self) -> Vec<u8> {
    method save_raft_state (line 36) | fn save_raft_state(&self, state: Vec<u8>) {
    method save_state_and_snapshot (line 39) | fn save_state_and_snapshot(&self, state: Vec<u8>, snapshot: Vec<u8>) {
    method snapshot (line 42) | fn snapshot(&self) -> Vec<u8> {
    method raft_state (line 64) | fn raft_state(&self) -> Vec<u8> {
    method save_raft_state (line 68) | fn save_raft_state(&self, state: Vec<u8>) {
    method save_state_and_snapshot (line 72) | fn save_state_and_snapshot(&self, state: Vec<u8>, snapshot: Vec<u8>) {
    method snapshot (line 77) | fn snapshot(&self) -> Vec<u8> {
  type SimplePersister (line 48) | pub struct SimplePersister {
    method new (line 56) | pub fn new() -> SimplePersister {
  function test_object_safety (line 87) | fn test_object_safety() {

FILE: courses/dss/raft/src/raft/tests.rs
  constant RAFT_ELECTION_TIMEOUT (line 19) | const RAFT_ELECTION_TIMEOUT: Duration = Duration::from_millis(1000);
  function random_entry (line 21) | fn random_entry(rnd: &mut ThreadRng) -> Entry {
  function test_initial_election_2a (line 28) | fn test_initial_election_2a() {
  function test_reelection_2a (line 56) | fn test_reelection_2a() {
  function test_many_election_2a (line 90) | fn test_many_election_2a() {
  function test_basic_agree_2b (line 124) | fn test_basic_agree_2b() {
  function test_fail_agree_2b (line 146) | fn test_fail_agree_2b() {
  function test_fail_no_agree_2b (line 177) | fn test_fail_no_agree_2b() {
  function test_concurrent_starts_2b (line 229) | fn test_concurrent_starts_2b() {
  function test_rejoin_2b (line 327) | fn test_rejoin_2b() {
  function test_backup_2b (line 374) | fn test_backup_2b() {
  function test_count_2b (line 453) | fn test_count_2b() {
  function test_persist1_2c (line 582) | fn test_persist1_2c() {
  function test_persist2_2c (line 628) | fn test_persist2_2c() {
  function test_persist3_2c (line 674) | fn test_persist3_2c() {
  function test_figure_8_2c (line 712) | fn test_figure_8_2c() {
  function test_unreliable_agree_2c (line 769) | fn test_unreliable_agree_2c() {
  function test_figure_8_unreliable_2c (line 813) | fn test_figure_8_unreliable_2c() {
  function internal_churn (line 888) | fn internal_churn(unreliable: bool) {
  function test_reliable_churn_2c (line 1041) | fn test_reliable_churn_2c() {
  function test_unreliable_churn_2c (line 1046) | fn test_unreliable_churn_2c() {
  function snap_common (line 1050) | fn snap_common(name: &str, disconnect: bool, reliable: bool, crash: bool) {
  function test_snapshot_basic_2d (line 1109) | fn test_snapshot_basic_2d() {
  function test_snapshot_install_2d (line 1114) | fn test_snapshot_install_2d() {
  function test_snapshot_install_unreliable_2d (line 1124) | fn test_snapshot_install_unreliable_2d() {
  function test_snapshot_install_crash_2d (line 1134) | fn test_snapshot_install_crash_2d() {
  function test_snapshot_install_unreliable_crash_2d (line 1139) | fn test_snapshot_install_unreliable_crash_2d() {

FILE: courses/rust/projects/project-1/src/bin/kvs.rs
  function main (line 4) | fn main() {

FILE: courses/rust/projects/project-1/src/kv.rs
  type KvStore (line 17) | pub struct KvStore {
    method new (line 23) | pub fn new() -> KvStore {
    method set (line 32) | pub fn set(&mut self, key: String, value: String) {
    method get (line 39) | pub fn get(&self, key: String) -> Option<String> {
    method remove (line 44) | pub fn remove(&mut self, key: String) {

FILE: courses/rust/projects/project-1/tests/tests.rs
  function cli_no_args (line 8) | fn cli_no_args() {
  function cli_version (line 14) | fn cli_version() {
  function cli_get (line 24) | fn cli_get() {
  function cli_set (line 35) | fn cli_set() {
  function cli_rm (line 46) | fn cli_rm() {
  function cli_invalid_get (line 56) | fn cli_invalid_get() {
  function cli_invalid_set (line 71) | fn cli_invalid_set() {
  function cli_invalid_rm (line 92) | fn cli_invalid_rm() {
  function cli_invalid_subcommand (line 107) | fn cli_invalid_subcommand() {
  function get_stored_value (line 117) | fn get_stored_value() {
  function overwrite_value (line 129) | fn overwrite_value() {
  function get_non_existent_value (line 141) | fn get_non_existent_value() {
  function remove_key (line 149) | fn remove_key() {

FILE: courses/rust/projects/project-2/src/bin/kvs.rs
  function main (line 6) | fn main() -> Result<()> {

FILE: courses/rust/projects/project-2/src/error.rs
  type KvsError (line 6) | pub enum KvsError {
    method from (line 23) | fn from(err: io::Error) -> KvsError {
    method from (line 29) | fn from(err: serde_json::Error) -> KvsError {
  type Result (line 35) | pub type Result<T> = std::result::Result<T, KvsError>;

FILE: courses/rust/projects/project-2/src/kv.rs
  constant COMPACTION_THRESHOLD (line 13) | const COMPACTION_THRESHOLD: u64 = 1024 * 1024;
  type KvStore (line 32) | pub struct KvStore {
    method open (line 54) | pub fn open(path: impl Into<PathBuf>) -> Result<KvStore> {
    method set (line 90) | pub fn set(&mut self, key: String, value: String) -> Result<()> {
    method get (line 117) | pub fn get(&mut self, key: String) -> Result<Option<String>> {
    method remove (line 142) | pub fn remove(&mut self, key: String) -> Result<()> {
    method compact (line 158) | pub fn compact(&mut self) -> Result<()> {
    method new_log_file (line 202) | fn new_log_file(&mut self, gen: u64) -> Result<BufWriterWithPos<File>> {
  function new_log_file (line 210) | fn new_log_file(
  function sorted_gen_list (line 228) | fn sorted_gen_list(path: &Path) -> Result<Vec<u64>> {
  function load (line 247) | fn load(
  function log_path (line 278) | fn log_path(dir: &Path, gen: u64) -> PathBuf {
  type Command (line 284) | enum Command {
    method set (line 290) | fn set(key: String, value: String) -> Command {
    method remove (line 294) | fn remove(key: String) -> Command {
  type CommandPos (line 300) | struct CommandPos {
    method from (line 307) | fn from((gen, range): (u64, Range<u64>)) -> Self {
  type BufReaderWithPos (line 316) | struct BufReaderWithPos<R: Read + Seek> {
  function new (line 322) | fn new(mut inner: R) -> Result<Self> {
  method read (line 332) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
  method seek (line 340) | fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
  type BufWriterWithPos (line 346) | struct BufWriterWithPos<W: Write + Seek> {
  function new (line 352) | fn new(mut inner: W) -> Result<Self> {
  method write (line 362) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  method flush (line 368) | fn flush(&mut self) -> io::Result<()> {
  method seek (line 374) | fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {

FILE: courses/rust/projects/project-2/tests/tests.rs
  function cli_no_args (line 11) | fn cli_no_args() {
  function cli_version (line 17) | fn cli_version() {
  function cli_get_non_existent_key (line 27) | fn cli_get_non_existent_key() {
  function cli_rm_non_existent_key (line 40) | fn cli_rm_non_existent_key() {
  function cli_set (line 53) | fn cli_set() {
  function cli_get_stored (line 65) | fn cli_get_stored() -> Result<()> {
  function cli_rm_stored (line 94) | fn cli_rm_stored() -> Result<()> {
  function cli_invalid_get (line 121) | fn cli_invalid_get() {
  function cli_invalid_set (line 136) | fn cli_invalid_set() {
  function cli_invalid_rm (line 157) | fn cli_invalid_rm() {
  function cli_invalid_subcommand (line 172) | fn cli_invalid_subcommand() {
  function get_stored_value (line 182) | fn get_stored_value() -> Result<()> {
  function overwrite_value (line 203) | fn overwrite_value() -> Result<()> {
  function get_non_existent_value (line 224) | fn get_non_existent_value() -> Result<()> {
  function remove_non_existent_key (line 240) | fn remove_non_existent_key() -> Result<()> {
  function remove_key (line 248) | fn remove_key() -> Result<()> {
  function compaction (line 260) | fn compaction() -> Result<()> {

FILE: courses/rust/projects/project-3/benches/engine_bench.rs
  function set_bench (line 7) | fn set_bench(c: &mut Criterion) {
  function get_bench (line 40) | fn get_bench(c: &mut Criterion) {

FILE: courses/rust/projects/project-3/src/bin/kvs-client.rs
  constant DEFAULT_LISTENING_ADDRESS (line 7) | const DEFAULT_LISTENING_ADDRESS: &str = "127.0.0.1:4000";
  constant ADDRESS_FORMAT (line 8) | const ADDRESS_FORMAT: &str = "IP:PORT";
  type Opt (line 17) | struct Opt {
  type Command (line 23) | enum Command {
  function main (line 67) | fn main() {
  function run (line 75) | fn run(opt: Opt) -> Result<()> {

FILE: courses/rust/projects/project-3/src/bin/kvs-server.rs
  constant DEFAULT_LISTENING_ADDRESS (line 11) | const DEFAULT_LISTENING_ADDRESS: &str = "127.0.0.1:4000";
  constant DEFAULT_ENGINE (line 12) | const DEFAULT_ENGINE: Engine = Engine::kvs;
  type Opt (line 16) | struct Opt {
  function main (line 43) | fn main() {
  function run (line 62) | fn run(opt: Opt) -> Result<()> {
  function run_with_engine (line 77) | fn run_with_engine<E: KvsEngine>(engine: E, addr: SocketAddr) -> Result<...
  function current_engine (line 82) | fn current_engine() -> Result<Option<Engine>> {

FILE: courses/rust/projects/project-3/src/client.rs
  type KvsClient (line 9) | pub struct KvsClient {
    method connect (line 16) | pub fn connect<A: ToSocketAddrs>(addr: A) -> Result<Self> {
    method get (line 26) | pub fn get(&mut self, key: String) -> Result<Option<String>> {
    method set (line 37) | pub fn set(&mut self, key: String, value: String) -> Result<()> {
    method remove (line 48) | pub fn remove(&mut self, key: String) -> Result<()> {

FILE: courses/rust/projects/project-3/src/common.rs
  type Request (line 4) | pub enum Request {
  type GetResponse (line 11) | pub enum GetResponse {
  type SetResponse (line 17) | pub enum SetResponse {
  type RemoveResponse (line 23) | pub enum RemoveResponse {

FILE: courses/rust/projects/project-3/src/engines/kvs.rs
  constant COMPACTION_THRESHOLD (line 14) | const COMPACTION_THRESHOLD: u64 = 1024 * 1024;
  type KvStore (line 34) | pub struct KvStore {
    method open (line 56) | pub fn open(path: impl Into<PathBuf>) -> Result<KvStore> {
    method compact (line 86) | pub fn compact(&mut self) -> Result<()> {
    method new_log_file (line 131) | fn new_log_file(&mut self, gen: u64) -> Result<BufWriterWithPos<File>> {
  method set (line 144) | fn set(&mut self, key: String, value: String) -> Result<()> {
  method get (line 167) | fn get(&mut self, key: String) -> Result<Option<String>> {
  method remove (line 192) | fn remove(&mut self, key: String) -> Result<()> {
  function new_log_file (line 211) | fn new_log_file(
  function sorted_gen_list (line 229) | fn sorted_gen_list(path: &Path) -> Result<Vec<u64>> {
  function load (line 248) | fn load(
  function log_path (line 279) | fn log_path(dir: &Path, gen: u64) -> PathBuf {
  type Command (line 285) | enum Command {
    method set (line 291) | fn set(key: String, value: String) -> Command {
    method remove (line 295) | fn remove(key: String) -> Command {
  type CommandPos (line 301) | struct CommandPos {
    method from (line 308) | fn from((gen, range): (u64, Range<u64>)) -> Self {
  type BufReaderWithPos (line 317) | struct BufReaderWithPos<R: Read + Seek> {
  function new (line 323) | fn new(mut inner: R) -> Result<Self> {
  method read (line 333) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
  method seek (line 341) | fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
  type BufWriterWithPos (line 347) | struct BufWriterWithPos<W: Write + Seek> {
  function new (line 353) | fn new(mut inner: W) -> Result<Self> {
  method write (line 363) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  method flush (line 369) | fn flush(&mut self) -> io::Result<()> {
  method seek (line 375) | fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {

FILE: courses/rust/projects/project-3/src/engines/mod.rs
  type KvsEngine (line 6) | pub trait KvsEngine {
    method set (line 10) | fn set(&mut self, key: String, value: String) -> Result<()>;
    method get (line 15) | fn get(&mut self, key: String) -> Result<Option<String>>;
    method remove (line 22) | fn remove(&mut self, key: String) -> Result<()>;

FILE: courses/rust/projects/project-3/src/engines/sled.rs
  type SledKvsEngine (line 7) | pub struct SledKvsEngine(Db);
    method new (line 11) | pub fn new(db: Db) -> Self {
  method set (line 17) | fn set(&mut self, key: String, value: String) -> Result<()> {
  method get (line 24) | fn get(&mut self, key: String) -> Result<Option<String>> {
  method remove (line 33) | fn remove(&mut self, key: String) -> Result<()> {

FILE: courses/rust/projects/project-3/src/error.rs
  type KvsError (line 7) | pub enum KvsError {
    method from (line 33) | fn from(err: io::Error) -> KvsError {
    method from (line 39) | fn from(err: serde_json::Error) -> KvsError {
    method from (line 45) | fn from(err: FromUtf8Error) -> KvsError {
    method from (line 51) | fn from(err: sled::Error) -> KvsError {
  type Result (line 57) | pub type Result<T> = std::result::Result<T, KvsError>;

FILE: courses/rust/projects/project-3/src/server.rs
  type KvsServer (line 9) | pub struct KvsServer<E: KvsEngine> {
  function new (line 15) | pub fn new(engine: E) -> Self {
  function run (line 20) | pub fn run<A: ToSocketAddrs>(mut self, addr: A) -> Result<()> {
  function serve (line 35) | fn serve(&mut self, tcp: TcpStream) -> Result<()> {

FILE: courses/rust/projects/project-3/tests/cli.rs
  function client_cli_no_args (line 12) | fn client_cli_no_args() {
  function client_cli_invalid_get (line 19) | fn client_cli_invalid_get() {
  function client_cli_invalid_set (line 51) | fn client_cli_invalid_set() {
  function client_cli_invalid_rm (line 90) | fn client_cli_invalid_rm() {
  function client_cli_invalid_subcommand (line 122) | fn client_cli_invalid_subcommand() {
  function client_cli_version (line 134) | fn client_cli_version() {
  function server_cli_version (line 145) | fn server_cli_version() {
  function cli_log_configuration (line 155) | fn cli_log_configuration() {
  function cli_wrong_engine (line 175) | fn cli_wrong_engine() {
  function cli_access_server (line 215) | fn cli_access_server(engine: &str, addr: &str) {
  function cli_access_server_kvs_engine (line 330) | fn cli_access_server_kvs_engine() {
  function cli_access_server_sled_engine (line 335) | fn cli_access_server_sled_engine() {

FILE: courses/rust/projects/project-3/tests/kv_store.rs
  function get_stored_value (line 7) | fn get_stored_value() -> Result<()> {
  function overwrite_value (line 28) | fn overwrite_value() -> Result<()> {
  function get_non_existent_value (line 49) | fn get_non_existent_value() -> Result<()> {
  function remove_non_existent_key (line 65) | fn remove_non_existent_key() -> Result<()> {
  function remove_key (line 73) | fn remove_key() -> Result<()> {
  function compaction (line 85) | fn compaction() -> Result<()> {

FILE: courses/rust/projects/project-4/src/bin/kvs-client.rs
  type Opt (line 14) | struct Opt {
  type Command (line 20) | enum Command {
  function main (line 64) | fn main() {
  function run (line 72) | fn run(opt: Opt) -> Result<()> {

FILE: courses/rust/projects/project-4/src/bin/kvs-server.rs
  constant DEFAULT_LISTENING_ADDRESS (line 13) | const DEFAULT_LISTENING_ADDRESS: &str = "127.0.0.1:4000";
  constant DEFAULT_ENGINE (line 14) | const DEFAULT_ENGINE: Engine = Engine::kvs;
  type Opt (line 18) | struct Opt {
  function main (line 45) | fn main() {
  function run (line 66) | fn run(opt: Opt) -> Result<()> {
  function run_with (line 87) | pub fn run_with<E: KvsEngine, P: ThreadPool>(engine: E, pool: P, addr: S...
  function current_engine (line 92) | fn current_engine() -> Result<Option<Engine>> {

FILE: courses/rust/projects/project-4/src/client.rs
  type KvsClient (line 9) | pub struct KvsClient {
    method connect (line 16) | pub fn connect<A: ToSocketAddrs>(addr: A) -> Result<Self> {
    method get (line 26) | pub fn get(&mut self, key: String) -> Result<Option<String>> {
    method set (line 37) | pub fn set(&mut self, key: String, value: String) -> Result<()> {
    method remove (line 48) | pub fn remove(&mut self, key: String) -> Result<()> {

FILE: courses/rust/projects/project-4/src/common.rs
  type Request (line 4) | pub enum Request {
  type GetResponse (line 11) | pub enum GetResponse {
  type SetResponse (line 17) | pub enum SetResponse {
  type RemoveResponse (line 23) | pub enum RemoveResponse {

FILE: courses/rust/projects/project-4/src/engines/kvs.rs
  constant COMPACTION_THRESHOLD (line 19) | const COMPACTION_THRESHOLD: u64 = 1024 * 1024;
  type KvStore (line 40) | pub struct KvStore {
    method open (line 57) | pub fn open(path: impl Into<PathBuf>) -> Result<KvStore> {
  method set (line 109) | fn set(&self, key: String, value: String) -> Result<()> {
  method get (line 116) | fn get(&self, key: String) -> Result<Option<String>> {
  method remove (line 135) | fn remove(&self, key: String) -> Result<()> {
  type KvStoreReader (line 146) | struct KvStoreReader {
    method close_stale_handles (line 160) | fn close_stale_handles(&self) {
    method read_and (line 172) | fn read_and<F, R>(&self, cmd_pos: CommandPos, f: F) -> Result<R>
    method read_command (line 192) | fn read_command(&self, cmd_pos: CommandPos) -> Result<Command> {
  method clone (line 200) | fn clone(&self) -> KvStoreReader {
  type KvStoreWriter (line 210) | struct KvStoreWriter {
    method set (line 222) | fn set(&mut self, key: String, value: String) -> Result<()> {
    method remove (line 241) | fn remove(&mut self, key: String) -> Result<()> {
    method compact (line 265) | fn compact(&mut self) -> Result<()> {
  function new_log_file (line 316) | fn new_log_file(path: &Path, gen: u64) -> Result<BufWriterWithPos<File>> {
  function sorted_gen_list (line 329) | fn sorted_gen_list(path: &Path) -> Result<Vec<u64>> {
  function load (line 348) | fn load(
  function log_path (line 380) | fn log_path(dir: &Path, gen: u64) -> PathBuf {
  type Command (line 386) | enum Command {
    method set (line 392) | fn set(key: String, value: String) -> Command {
    method remove (line 396) | fn remove(key: String) -> Command {
  type CommandPos (line 403) | struct CommandPos {
    method from (line 410) | fn from((gen, range): (u64, Range<u64>)) -> Self {
  type BufReaderWithPos (line 419) | struct BufReaderWithPos<R: Read + Seek> {
  function new (line 425) | fn new(mut inner: R) -> Result<Self> {
  method read (line 435) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
  method seek (line 443) | fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
  type BufWriterWithPos (line 449) | struct BufWriterWithPos<W: Write + Seek> {
  function new (line 455) | fn new(mut inner: W) -> Result<Self> {
  method write (line 465) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  method flush (line 471) | fn flush(&mut self) -> io::Result<()> {
  method seek (line 477) | fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {

FILE: courses/rust/projects/project-4/src/engines/mod.rs
  type KvsEngine (line 9) | pub trait KvsEngine: Clone + Send + 'static {
    method set (line 13) | fn set(&self, key: String, value: String) -> Result<()>;
    method get (line 18) | fn get(&self, key: String) -> Result<Option<String>>;
    method remove (line 25) | fn remove(&self, key: String) -> Result<()>;

FILE: courses/rust/projects/project-4/src/engines/sled.rs
  type SledKvsEngine (line 7) | pub struct SledKvsEngine(Db);
    method new (line 11) | pub fn new(db: Db) -> Self {
  method set (line 17) | fn set(&self, key: String, value: String) -> Result<()> {
  method get (line 24) | fn get(&self, key: String) -> Result<Option<String>> {
  method remove (line 33) | fn remove(&self, key: String) -> Result<()> {

FILE: courses/rust/projects/project-4/src/error.rs
  type KvsError (line 7) | pub enum KvsError {
    method from (line 33) | fn from(err: io::Error) -> KvsError {
    method from (line 39) | fn from(err: serde_json::Error) -> KvsError {
    method from (line 45) | fn from(err: FromUtf8Error) -> KvsError {
    method from (line 51) | fn from(err: sled::Error) -> KvsError {
  type Result (line 57) | pub type Result<T> = std::result::Result<T, KvsError>;

FILE: courses/rust/projects/project-4/src/server.rs
  type KvsServer (line 10) | pub struct KvsServer<E: KvsEngine, P: ThreadPool> {
  function new (line 17) | pub fn new(engine: E, pool: P) -> Self {
  function run (line 22) | pub fn run<A: ToSocketAddrs>(self, addr: A) -> Result<()> {
  function serve (line 39) | fn serve<E: KvsEngine>(engine: E, tcp: TcpStream) -> Result<()> {

FILE: courses/rust/projects/project-4/src/thread_pool/mod.rs
  type ThreadPool (line 15) | pub trait ThreadPool {
    method new (line 21) | fn new(threads: u32) -> Result<Self>
    method spawn (line 30) | fn spawn<F>(&self, job: F)

FILE: courses/rust/projects/project-4/src/thread_pool/naive.rs
  type NaiveThreadPool (line 8) | pub struct NaiveThreadPool;
  method new (line 11) | fn new(_threads: u32) -> Result<Self> {
  method spawn (line 15) | fn spawn<F>(&self, job: F)

FILE: courses/rust/projects/project-4/src/thread_pool/rayon.rs
  type RayonThreadPool (line 5) | pub struct RayonThreadPool(rayon::ThreadPool);
  method new (line 8) | fn new(threads: u32) -> Result<Self> {
  method spawn (line 16) | fn spawn<F>(&self, job: F)

FILE: courses/rust/projects/project-4/src/thread_pool/shared_queue.rs
  type SharedQueueThreadPool (line 19) | pub struct SharedQueueThreadPool {
  method new (line 24) | fn new(threads: u32) -> Result<Self> {
  method spawn (line 38) | fn spawn<F>(&self, job: F)
  type TaskReceiver (line 49) | struct TaskReceiver(Receiver<Box<dyn FnOnce() + Send + 'static>>);
  method drop (line 52) | fn drop(&mut self) {
  function run_tasks (line 62) | fn run_tasks(rx: TaskReceiver) {

FILE: courses/rust/projects/project-4/tests/cli.rs
  function client_cli_no_args (line 12) | fn client_cli_no_args() {
  function client_cli_invalid_get (line 19) | fn client_cli_invalid_get() {
  function client_cli_invalid_set (line 51) | fn client_cli_invalid_set() {
  function client_cli_invalid_rm (line 90) | fn client_cli_invalid_rm() {
  function client_cli_invalid_subcommand (line 122) | fn client_cli_invalid_subcommand() {
  function client_cli_version (line 134) | fn client_cli_version() {
  function server_cli_version (line 145) | fn server_cli_version() {
  function cli_log_configuration (line 155) | fn cli_log_configuration() {
  function cli_wrong_engine (line 175) | fn cli_wrong_engine() {
  function cli_access_server (line 215) | fn cli_access_server(engine: &str, addr: &str) {
  function cli_access_server_kvs_engine (line 330) | fn cli_access_server_kvs_engine() {
  function cli_access_server_sled_engine (line 335) | fn cli_access_server_sled_engine() {

FILE: courses/rust/projects/project-4/tests/kv_store.rs
  function get_stored_value (line 9) | fn get_stored_value() -> Result<()> {
  function overwrite_value (line 30) | fn overwrite_value() -> Result<()> {
  function get_non_existent_value (line 51) | fn get_non_existent_value() -> Result<()> {
  function remove_non_existent_key (line 67) | fn remove_non_existent_key() -> Result<()> {
  function remove_key (line 75) | fn remove_key() -> Result<()> {
  function compaction (line 87) | fn compaction() -> Result<()> {
  function concurrent_set (line 131) | fn concurrent_set() -> Result<()> {
  function concurrent_get (line 162) | fn concurrent_get() -> Result<()> {

FILE: courses/rust/projects/project-4/tests/thread_pool.rs
  function spawn_counter (line 9) | fn spawn_counter<P: ThreadPool>(pool: P) -> Result<()> {
  function spawn_panic_task (line 32) | fn spawn_panic_task<P: ThreadPool>() -> Result<()> {
  function naive_thread_pool_spawn_counter (line 50) | fn naive_thread_pool_spawn_counter() -> Result<()> {
  function shared_queue_thread_pool_spawn_counter (line 56) | fn shared_queue_thread_pool_spawn_counter() -> Result<()> {
  function rayon_thread_pool_spawn_counter (line 62) | fn rayon_thread_pool_spawn_counter() -> Result<()> {
  function shared_queue_thread_pool_panic_task (line 68) | fn shared_queue_thread_pool_panic_task() -> Result<()> {

FILE: courses/rust/projects/project-5/src/bin/kvs-client.rs
  type Opt (line 15) | struct Opt {
  type Command (line 21) | enum Command {
  function main (line 65) | fn main() {
  function run (line 73) | fn run(opt: Opt) -> Result<()> {

FILE: courses/rust/projects/project-5/src/bin/kvs-server.rs
  constant DEFAULT_LISTENING_ADDRESS (line 16) | const DEFAULT_LISTENING_ADDRESS: &str = "127.0.0.1:4000";
  constant DEFAULT_ENGINE (line 17) | const DEFAULT_ENGINE: Engine = Engine::kvs;
  type Opt (line 21) | struct Opt {
  function main (line 48) | fn main() {
  function run (line 67) | fn run(opt: Opt) -> Result<()> {
  function run_with (line 92) | pub fn run_with<E: KvsEngine>(engine: E, addr: SocketAddr) -> Result<()> {
  function current_engine (line 97) | fn current_engine() -> Result<Option<Engine>> {

FILE: courses/rust/projects/project-5/src/client.rs
  type KvsClient (line 11) | pub struct KvsClient {
    method connect (line 18) | pub fn connect(addr: SocketAddr) -> impl Future<Item = Self, Error = K...
    method get (line 35) | pub fn get(self, key: String) -> impl Future<Item = (Option<String>, S...
    method set (line 46) | pub fn set(self, key: String, value: String) -> impl Future<Item = Sel...
    method remove (line 57) | pub fn remove(self, key: String) -> impl Future<Item = Self, Error = K...
    method send_request (line 67) | fn send_request(

FILE: courses/rust/projects/project-5/src/common.rs
  type Request (line 4) | pub enum Request {
  type Response (line 11) | pub enum Response {

FILE: courses/rust/projects/project-5/src/engines/kvs.rs
  constant COMPACTION_THRESHOLD (line 22) | const COMPACTION_THRESHOLD: u64 = 1024 * 1024;
  type KvStore (line 45) | pub struct KvStore<P: ThreadPool> {
  function open (line 65) | pub fn open(path: impl Into<PathBuf>, concurrency: u32) -> Result<Self> {
  method set (line 125) | fn set(&self, key: String, value: String) -> Box<dyn Future<Item = (), E...
  method get (line 143) | fn get(&self, key: String) -> Box<dyn Future<Item = Option<String>, Erro...
  method remove (line 181) | fn remove(&self, key: String) -> Box<dyn Future<Item = (), Error = KvsEr...
  type KvStoreReader (line 203) | struct KvStoreReader {
    method close_stale_handles (line 217) | fn close_stale_handles(&self) {
    method read_and (line 229) | fn read_and<F, R>(&self, cmd_pos: CommandPos, f: F) -> Result<R>
    method read_command (line 249) | fn read_command(&self, cmd_pos: CommandPos) -> Result<Command> {
  method clone (line 257) | fn clone(&self) -> KvStoreReader {
  type KvStoreWriter (line 267) | struct KvStoreWriter {
    method set (line 279) | fn set(&mut self, key: String, value: String) -> Result<()> {
    method remove (line 298) | fn remove(&mut self, key: String) -> Result<()> {
    method compact (line 322) | fn compact(&mut self) -> Result<()> {
  function new_log_file (line 373) | fn new_log_file(path: &Path, gen: u64) -> Result<BufWriterWithPos<File>> {
  function sorted_gen_list (line 386) | fn sorted_gen_list(path: &Path) -> Result<Vec<u64>> {
  function load (line 405) | fn load(
  function log_path (line 437) | fn log_path(dir: &Path, gen: u64) -> PathBuf {
  type Command (line 443) | enum Command {
    method set (line 449) | fn set(key: String, value: String) -> Command {
    method remove (line 453) | fn remove(key: String) -> Command {
  type CommandPos (line 460) | struct CommandPos {
    method from (line 467) | fn from((gen, range): (u64, Range<u64>)) -> Self {
  type BufReaderWithPos (line 476) | struct BufReaderWithPos<R: Read + Seek> {
  function new (line 482) | fn new(mut inner: R) -> Result<Self> {
  method read (line 492) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
  method seek (line 500) | fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
  type BufWriterWithPos (line 506) | struct BufWriterWithPos<W: Write + Seek> {
  function new (line 512) | fn new(mut inner: W) -> Result<Self> {
  method write (line 522) | fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
  method flush (line 528) | fn flush(&mut self) -> io::Result<()> {
  method seek (line 534) | fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {

FILE: courses/rust/projects/project-5/src/engines/mod.rs
  type KvsEngine (line 11) | pub trait KvsEngine: Clone + Send + 'static {
    method set (line 15) | fn set(&self, key: String, value: String) -> Box<dyn Future<Item = (),...
    method get (line 20) | fn get(&self, key: String) -> Box<dyn Future<Item = Option<String>, Er...
    method remove (line 27) | fn remove(&self, key: String) -> Box<dyn Future<Item = (), Error = Kvs...

FILE: courses/rust/projects/project-5/src/engines/sled.rs
  type SledKvsEngine (line 9) | pub struct SledKvsEngine<P: ThreadPool> {
  function new (line 19) | pub fn new(db: Db, concurrency: u32) -> Result<Self> {
  method set (line 26) | fn set(&self, key: String, value: String) -> Box<dyn Future<Item = (), E...
  method get (line 45) | fn get(&self, key: String) -> Box<dyn Future<Item = Option<String>, Erro...
  method remove (line 66) | fn remove(&self, key: String) -> Box<dyn Future<Item = (), Error = KvsEr...

FILE: courses/rust/projects/project-5/src/error.rs
  type KvsError (line 7) | pub enum KvsError {
    method from (line 33) | fn from(err: io::Error) -> KvsError {
    method from (line 39) | fn from(err: serde_json::Error) -> KvsError {
    method from (line 45) | fn from(err: FromUtf8Error) -> KvsError {
    method from (line 51) | fn from(err: sled::Error) -> KvsError {
  type Result (line 57) | pub type Result<T> = std::result::Result<T, KvsError>;

FILE: courses/rust/projects/project-5/src/server.rs
  type KvsServer (line 10) | pub struct KvsServer<E: KvsEngine> {
  function new (line 16) | pub fn new(engine: E) -> Self {
  function run (line 21) | pub fn run(self, addr: SocketAddr) -> Result<()> {
  function serve (line 35) | fn serve<E: KvsEngine>(engine: E, tcp: TcpStream) -> impl Future<Item = ...

FILE: courses/rust/projects/project-5/src/thread_pool/mod.rs
  type ThreadPool (line 15) | pub trait ThreadPool: Clone + Send + 'static {
    method new (line 21) | fn new(threads: u32) -> Result<Self>
    method spawn (line 30) | fn spawn<F>(&self, job: F)

FILE: courses/rust/projects/project-5/src/thread_pool/naive.rs
  type NaiveThreadPool (line 9) | pub struct NaiveThreadPool;
  method new (line 12) | fn new(_threads: u32) -> Result<Self> {
  method spawn (line 16) | fn spawn<F>(&self, job: F)

FILE: courses/rust/projects/project-5/src/thread_pool/rayon.rs
  type RayonThreadPool (line 7) | pub struct RayonThreadPool(Arc<rayon::ThreadPool>);
  method new (line 10) | fn new(threads: u32) -> Result<Self> {
  method spawn (line 18) | fn spawn<F>(&self, job: F)

FILE: courses/rust/projects/project-5/src/thread_pool/shared_queue.rs
  type SharedQueueThreadPool (line 18) | pub struct SharedQueueThreadPool {
  method new (line 23) | fn new(threads: u32) -> Result<Self> {
  method spawn (line 37) | fn spawn<F>(&self, job: F)
  type TaskReceiver (line 48) | struct TaskReceiver(Receiver<Box<dyn FnOnce() + Send + 'static>>);
  method drop (line 51) | fn drop(&mut self) {
  function run_tasks (line 61) | fn run_tasks(rx: TaskReceiver) {

FILE: courses/rust/projects/project-5/tests/cli.rs
  function client_cli_no_args (line 12) | fn client_cli_no_args() {
  function client_cli_invalid_get (line 19) | fn client_cli_invalid_get() {
  function client_cli_invalid_set (line 51) | fn client_cli_invalid_set() {
  function client_cli_invalid_rm (line 90) | fn client_cli_invalid_rm() {
  function client_cli_invalid_subcommand (line 122) | fn client_cli_invalid_subcommand() {
  function client_cli_version (line 134) | fn client_cli_version() {
  function server_cli_version (line 145) | fn server_cli_version() {
  function cli_log_configuration (line 155) | fn cli_log_configuration() {
  function cli_wrong_engine (line 175) | fn cli_wrong_engine() {
  function cli_access_server (line 215) | fn cli_access_server(engine: &str, addr: &str) {
  function cli_access_server_kvs_engine (line 330) | fn cli_access_server_kvs_engine() {
  function cli_access_server_sled_engine (line 335) | fn cli_access_server_sled_engine() {

FILE: courses/rust/projects/project-5/tests/kv_store.rs
  function get_stored_value (line 10) | fn get_stored_value() -> Result<()> {
  function overwrite_value (line 43) | fn overwrite_value() -> Result<()> {
  function get_non_existent_value (line 76) | fn get_non_existent_value() -> Result<()> {
  function remove_non_existent_key (line 92) | fn remove_non_existent_key() -> Result<()> {
  function remove_key (line 100) | fn remove_key() -> Result<()> {
  function compaction (line 112) | fn compaction() -> Result<()> {
  function concurrent_set (line 156) | fn concurrent_set() -> Result<()> {
  function concurrent_get (line 187) | fn concurrent_get() -> Result<()> {

FILE: courses/rust/projects/project-5/tests/thread_pool.rs
  function spawn_counter (line 9) | fn spawn_counter<P: ThreadPool>(pool: P) -> Result<()> {
  function spawn_panic_task (line 32) | fn spawn_panic_task<P: ThreadPool>() -> Result<()> {
  function naive_thread_pool_spawn_counter (line 50) | fn naive_thread_pool_spawn_counter() -> Result<()> {
  function shared_queue_thread_pool_spawn_counter (line 56) | fn shared_queue_thread_pool_spawn_counter() -> Result<()> {
  function rayon_thread_pool_spawn_counter (line 62) | fn rayon_thread_pool_spawn_counter() -> Result<()> {
  function shared_queue_thread_pool_panic_task (line 68) | fn shared_queue_thread_pool_panic_task() -> Result<()> {

FILE: tidb/join/benchmark_test.go
  function BenchmarkJoin (line 5) | func BenchmarkJoin(b *testing.B) {
  function BenchmarkJoinExample (line 11) | func BenchmarkJoinExample(b *testing.B) {

FILE: tidb/join/join.go
  function Join (line 12) | func Join(f0, f1 string, offset0, offset1 []int) (sum uint64) {

FILE: tidb/join/join_example.go
  function JoinExample (line 14) | func JoinExample(f0, f1 string, offset0, offset1 []int) (sum uint64) {
  function readCSVFileIntoTbl (line 30) | func readCSVFileIntoTbl(f string) (tbl [][]string) {
  function buildHashTable (line 50) | func buildHashTable(data [][]string, offset []int) (hashtable *mvmap.MVM...
  function probe (line 68) | func probe(hashtable *mvmap.MVMap, row []string, offset []int) (rowIDs [...

FILE: tidb/join/join_test.go
  type joinTestSuite (line 9) | type joinTestSuite struct
    method TestJoin (line 17) | func (s *joinTestSuite) TestJoin(c *check.C) {
  function TestT (line 11) | func TestT(t *testing.T) {

FILE: tidb/mapreduce/casegen.go
  type DataSize (line 10) | type DataSize
    method String (line 18) | func (d DataSize) String() string {
  constant KB (line 13) | KB = 1 << 10
  constant MB (line 14) | MB = 1 << 20
  constant GB (line 15) | GB = 1 << 30
  type Case (line 30) | type Case struct
  type CaseGenF (line 36) | type CaseGenF
  function AllCaseGenFs (line 39) | func AllCaseGenFs() []CaseGenF {
  function genUniformCases (line 47) | func genUniformCases() []CaseGenF {
  function genPercentCases (line 92) | func genPercentCases() []CaseGenF {
  function CaseSingleURLPerFile (line 176) | func CaseSingleURLPerFile(dataFileDir string, totalDataSize, nMapFiles i...
  function genResult (line 213) | func genResult(rpath string, urlCount map[string]int) {
  function randomNURL (line 222) | func randomNURL(n int) ([]string, int) {
  function wrapLikeURL (line 239) | func wrapLikeURL(suffix string) string {

FILE: tidb/mapreduce/mapreduce.go
  type KeyValue (line 17) | type KeyValue struct
  type ReduceF (line 23) | type ReduceF
  type MapF (line 26) | type MapF
  type jobPhase (line 29) | type jobPhase
  constant mapPhase (line 32) | mapPhase    jobPhase = "mapPhase"
  constant reducePhase (line 33) | reducePhase          = "reducePhase"
  type task (line 36) | type task struct
  type MRCluster (line 50) | type MRCluster struct
    method NWorkers (line 73) | func (c *MRCluster) NWorkers() int { return c.nWorkers }
    method Start (line 76) | func (c *MRCluster) Start() {
    method worker (line 83) | func (c *MRCluster) worker() {
    method Shutdown (line 125) | func (c *MRCluster) Shutdown() {
    method Submit (line 131) | func (c *MRCluster) Submit(jobName, dataDir string, mapF MapF, reduceF...
    method run (line 137) | func (c *MRCluster) run(jobName, dataDir string, mapF MapF, reduceF Re...
  function init (line 63) | func init() {
  function GetMRCluster (line 68) | func GetMRCluster() *MRCluster {
  function ihash (line 165) | func ihash(s string) int {
  function reduceName (line 171) | func reduceName(dataDir, jobName string, mapTask int, reduceTask int) st...
  function mergeName (line 175) | func mergeName(dataDir, jobName string, reduceTask int) string {

FILE: tidb/mapreduce/urltop10.go
  function URLTop10 (line 4) | func URLTop10(nWorkers int) RoundsArgs {

FILE: tidb/mapreduce/urltop10_example.go
  function ExampleURLTop10 (line 15) | func ExampleURLTop10(nWorkers int) RoundsArgs {
  function ExampleURLCountMap (line 33) | func ExampleURLCountMap(filename string, contents string) []KeyValue {
  function ExampleURLCountReduce (line 47) | func ExampleURLCountReduce(key string, values []string) string {
  function ExampleURLTop10Map (line 52) | func ExampleURLTop10Map(filename string, contents string) []KeyValue {
  function ExampleURLTop10Reduce (line 62) | func ExampleURLTop10Reduce(key string, values []string) string {

FILE: tidb/mapreduce/urltop10_test.go
  function testDataScale (line 13) | func testDataScale() ([]DataSize, []int) {
  constant dataDir (line 20) | dataDir = "/tmp/mr_homework"
  function dataPrefix (line 23) | func dataPrefix(i int, ds DataSize, nMap int) string {
  function TestGenData (line 27) | func TestGenData(t *testing.T) {
  function TestCleanData (line 39) | func TestCleanData(t *testing.T) {
  function TestExampleURLTop (line 45) | func TestExampleURLTop(t *testing.T) {
  function TestURLTop (line 50) | func TestURLTop(t *testing.T) {
  function testURLTop (line 55) | func testURLTop(t *testing.T, rounds RoundsArgs) {

FILE: tidb/mapreduce/utils.go
  type RoundArgs (line 14) | type RoundArgs struct
  type RoundsArgs (line 21) | type RoundsArgs
  type urlCount (line 23) | type urlCount struct
  function TopN (line 29) | func TopN(urlCntMap map[string]int, n int) ([]string, []int) {
  function CheckFile (line 53) | func CheckFile(expected, got string) (string, bool) {
  function CreateFileAndBuf (line 73) | func CreateFileAndBuf(fpath string) (*os.File, *bufio.Writer) {
  function OpenFileAndBuf (line 84) | func OpenFileAndBuf(fpath string) (*os.File, *bufio.Reader) {
  function WriteToBuf (line 93) | func WriteToBuf(buf *bufio.Writer, strs ...string) {
  function SafeClose (line 102) | func SafeClose(f *os.File, buf *bufio.Writer) {
  function FileOrDirExist (line 114) | func FileOrDirExist(p string) bool {

FILE: tidb/mergesort/bench_test.go
  function BenchmarkMergeSort (line 8) | func BenchmarkMergeSort(b *testing.B) {
  function BenchmarkNormalSort (line 23) | func BenchmarkNormalSort(b *testing.B) {

FILE: tidb/mergesort/mergesort.go
  function MergeSort (line 5) | func MergeSort(src []int64) {

FILE: tidb/mergesort/mergesort_test.go
  function TestT (line 14) | func TestT(t *testing.T) {
  function prepare (line 18) | func prepare(src []int64) {
  type sortTestSuite (line 25) | type sortTestSuite struct
    method TestMergeSort (line 27) | func (s *sortTestSuite) TestMergeSort(c *check.C) {
Condensed preview — 195 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,767K chars).
[
  {
    "path": ".circleci/config.yml",
    "chars": 676,
    "preview": "version: 2.1\njobs:\n  dss:\n    docker:\n      - image: circleci/rust:stretch\n    environment:\n      RUST_BACKTRACE: \"1\"\n  "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.md",
    "chars": 319,
    "preview": "---\nname: \"\\U0001F41B Bug Report\"\nabout: something isn't working as expected\nlabels: type/bug\n---\n\n## Bug Report\n\nPlease"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-requirement.md",
    "chars": 386,
    "preview": "---\nname: \"\\U0001F680 Feature Request\"\nabout: I have a suggestion!\nlabels: type/enhancement\n---\n\n## Feature Request\n\nple"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.md",
    "chars": 420,
    "preview": "---\nname: \"\\U0001F914 Question\"\nabout: I have a question!\nlabels: type/question\n---\n\n## General Question\n\n## Tips\n\nExpec"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 668,
    "preview": "<!-- Thank you for contributing to talent-plan!\n\nPR Title Format:\n1. pkg [, pkg2, pkg3]: what's changed\n2. *: what's cha"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3381,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1704,
    "preview": "# Contributing Guide\n\nThanks for taking the time to contribute to Talent Plan! Contributions of any kind are welcome.\n\n#"
  },
  {
    "path": "README.md",
    "chars": 3864,
    "preview": "# Welcome to learn Talent Plan Courses!\n\n![Talent Plan Logo](media/talent-plan-logo.png)\n\nTalent Plan is an open source "
  },
  {
    "path": "courses/README.md",
    "chars": 702,
    "preview": "# All public courses\n\nHere we list all public courses of Talent Plan, including:\n\n- [TP 101: Introduction to open source"
  },
  {
    "path": "courses/dss/.gitignore",
    "chars": 39,
    "preview": "**/target\n**/*.rs.bk\n6.824-golabs-2018\n"
  },
  {
    "path": "courses/dss/Cargo.toml",
    "chars": 108,
    "preview": "[workspace]\nmembers = [\n    \"labcodec\",\n    \"labrpc\",\n    \"linearizability\",\n    \"raft\",\n    \"percolator\"\n]\n"
  },
  {
    "path": "courses/dss/Makefile",
    "chars": 710,
    "preview": "export RUSTFLAGS=-Dwarnings\nexport RUST_TEST_THREADS=1\nexport RUST_BACKTRACE=1\n\nLOG_LEVEL ?= raft=info,percolator=info\n\n"
  },
  {
    "path": "courses/dss/README.md",
    "chars": 1946,
    "preview": "# Distributed Systems in Rust\n\nA training course about the distributed systems in [Rust].\n\nSubjects covered include:\n\n- "
  },
  {
    "path": "courses/dss/labcodec/Cargo.toml",
    "chars": 170,
    "preview": "[package]\nname = \"labcodec\"\nversion = \"0.1.0\"\nbuild = \"build.rs\"\nedition = \"2018\"\npublish = false\n\n[dependencies]\nprost "
  },
  {
    "path": "courses/dss/labcodec/build.rs",
    "chars": 140,
    "preview": "fn main() {\n    prost_build::compile_protos(&[\"proto/fixture.proto\"], &[\"proto\"]).unwrap();\n    println!(\"cargo:rerun-if"
  },
  {
    "path": "courses/dss/labcodec/demonstration/README.md",
    "chars": 170,
    "preview": "# Demonstration\n\nExpanded version of generated rust files. Files in the folder are for the sake\nof understanding how pro"
  },
  {
    "path": "courses/dss/labcodec/demonstration/expanded_fixture.rs",
    "chars": 13738,
    "preview": "/// A simple protobuf message.\npub struct Msg {\n    #[prost(enumeration = \"msg::Type\", tag = \"1\")]\n    pub r#type: i32,\n"
  },
  {
    "path": "courses/dss/labcodec/proto/fixture.proto",
    "chars": 269,
    "preview": "syntax = \"proto3\";\n\npackage fixture;\n\n// A simple protobuf message.\nmessage Msg {\n    enum Type {\n        UNKNOWN = 0;\n "
  },
  {
    "path": "courses/dss/labcodec/src/lib.rs",
    "chars": 2335,
    "preview": "//! A thin wrapper of [prost](https://docs.rs/prost/0.6.1/prost/)\n\n/// A labcodec message.\npub trait Message: prost::Mes"
  },
  {
    "path": "courses/dss/labrpc/Cargo.toml",
    "chars": 411,
    "preview": "[package]\nname = \"labrpc\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n[dependencies]\nasync-trait = \"0.1\"\nfutures"
  },
  {
    "path": "courses/dss/labrpc/benches/rpc.rs",
    "chars": 2266,
    "preview": "use std::sync::{Arc, Mutex};\n\nuse criterion::{black_box, criterion_group, criterion_main, Criterion};\nuse futures::execu"
  },
  {
    "path": "courses/dss/labrpc/examples/echo.rs",
    "chars": 1112,
    "preview": "use futures::executor::block_on;\nuse prost_derive::Message;\n\nuse labrpc::*;\n\n/// A Hand-written protobuf messages\n#[deri"
  },
  {
    "path": "courses/dss/labrpc/src/client.rs",
    "chars": 2596,
    "preview": "use std::fmt;\nuse std::sync::{Arc, Mutex};\n\nuse futures::channel::mpsc::UnboundedSender;\nuse futures::channel::oneshot;\n"
  },
  {
    "path": "courses/dss/labrpc/src/error.rs",
    "chars": 786,
    "preview": "use std::{error, fmt, result};\n\nuse futures::channel::oneshot::Canceled;\n\nuse labcodec::{DecodeError, EncodeError};\n\n#[d"
  },
  {
    "path": "courses/dss/labrpc/src/lib.rs",
    "chars": 17003,
    "preview": "#![allow(clippy::new_without_default)]\n\nmod client;\nmod error;\n#[macro_use]\nmod macros;\nmod network;\nmod server;\n\npub us"
  },
  {
    "path": "courses/dss/labrpc/src/macros.rs",
    "chars": 4118,
    "preview": "#[macro_export]\nmacro_rules! service {\n    () => {\n        compile_error!(\"empty service is not allowed\");\n    };\n    (\n"
  },
  {
    "path": "courses/dss/labrpc/src/network.rs",
    "chars": 11610,
    "preview": "use std::collections::HashMap;\nuse std::future::Future;\nuse std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};\nuse "
  },
  {
    "path": "courses/dss/labrpc/src/server.rs",
    "chars": 3357,
    "preview": "use std::collections::hash_map::{Entry, HashMap};\nuse std::fmt;\nuse std::sync::atomic::{AtomicUsize, Ordering};\nuse std:"
  },
  {
    "path": "courses/dss/linearizability/Cargo.toml",
    "chars": 140,
    "preview": "[package]\nname = \"linearizability\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n[dev-dependencies]\nregex = \"1.3\"\n"
  },
  {
    "path": "courses/dss/linearizability/src/bitset.rs",
    "chars": 1542,
    "preview": "use std::num::Wrapping;\n\n#[derive(Clone)]\npub struct Bitset(Vec<u64>);\n\nimpl Bitset {\n    pub fn new(bits: usize) -> Sel"
  },
  {
    "path": "courses/dss/linearizability/src/lib.rs",
    "chars": 12014,
    "preview": "mod bitset;\npub mod model;\npub mod models;\n\nuse std::cell::{Ref, RefCell};\nuse std::collections::HashMap;\nuse std::fmt::"
  },
  {
    "path": "courses/dss/linearizability/src/model.rs",
    "chars": 2388,
    "preview": "use std::cmp::PartialEq;\nuse std::fmt::Debug;\nuse std::fmt::Display;\nuse std::marker::Send;\n\n#[derive(Debug)]\npub enum V"
  },
  {
    "path": "courses/dss/linearizability/src/models.rs",
    "chars": 8560,
    "preview": "use std::collections::HashMap;\n\nuse super::model::{EventKind, Events, Model, Operations};\n\n#[derive(Clone, Debug)]\npub e"
  },
  {
    "path": "courses/dss/linearizability/test_data/c01-bad.txt",
    "chars": 4803,
    "preview": "{:process 0, :type :invoke, :f :append, :key \"0\", :value \"x 0 0 y\"}\n{:process 0, :type :ok, :f :append, :key \"0\", :value"
  },
  {
    "path": "courses/dss/linearizability/test_data/c01-ok.txt",
    "chars": 7433,
    "preview": "{:process 0, :type :invoke, :f :append, :key \"0\", :value \"x 0 0 y\"}\n{:process 0, :type :ok, :f :append, :key \"0\", :value"
  },
  {
    "path": "courses/dss/linearizability/test_data/c10-bad.txt",
    "chars": 57338,
    "preview": "{:process 9, :type :invoke, :f :append, :key \"0\", :value \"x 9 0 y\"}\n{:process 4, :type :invoke, :f :append, :key \"1\", :v"
  },
  {
    "path": "courses/dss/linearizability/test_data/c10-ok.txt",
    "chars": 48766,
    "preview": "{:process 9, :type :invoke, :f :append, :key \"0\", :value \"x 9 0 y\"}\n{:process 2, :type :invoke, :f :append, :key \"1\", :v"
  },
  {
    "path": "courses/dss/linearizability/test_data/c50-bad.txt",
    "chars": 318119,
    "preview": "{:process 2, :type :invoke, :f :get, :key \"0\", :value nil}\n{:process 0, :type :invoke, :f :append, :key \"8\", :value \"x 0"
  },
  {
    "path": "courses/dss/linearizability/test_data/c50-ok.txt",
    "chars": 283725,
    "preview": "{:process 6, :type :invoke, :f :append, :key \"0\", :value \"x 6 0 y\"}\n{:process 18, :type :invoke, :f :append, :key \"1\", :"
  },
  {
    "path": "courses/dss/percolator/Cargo.toml",
    "chars": 416,
    "preview": "[package]\nname = \"percolator\"\nversion = \"0.1.0\"\nauthors = [\"Ryan Leung <rleungx@gmail.com>\"]\nedition = \"2018\"\nbuild = \"b"
  },
  {
    "path": "courses/dss/percolator/README.md",
    "chars": 2511,
    "preview": "# The Percolator lab\n\n## What is Percolator\n\nPercolator is a system built by Google for incremental processing on a very"
  },
  {
    "path": "courses/dss/percolator/build.rs",
    "chars": 136,
    "preview": "fn main() {\n    prost_build::compile_protos(&[\"proto/msg.proto\"], &[\"proto\"]).unwrap();\n    println!(\"cargo:rerun-if-cha"
  },
  {
    "path": "courses/dss/percolator/proto/msg.proto",
    "chars": 743,
    "preview": "// Protocol buffers are a flexible, efficient, automated mechanism for serializing structured data.\n// You can define ho"
  },
  {
    "path": "courses/dss/percolator/src/client.rs",
    "chars": 1646,
    "preview": "use labrpc::*;\n\nuse crate::service::{TSOClient, TransactionClient};\n\n// BACKOFF_TIME_MS is the wait time before retrying"
  },
  {
    "path": "courses/dss/percolator/src/lib.rs",
    "chars": 365,
    "preview": "#[allow(unused_imports)]\n#[macro_use]\nextern crate log;\n\n// After you finish the implementation, `#[allow(unused)]` shou"
  },
  {
    "path": "courses/dss/percolator/src/server.rs",
    "chars": 3010,
    "preview": "use std::collections::BTreeMap;\nuse std::sync::{Arc, Mutex};\nuse std::time::Duration;\n\nuse crate::msg::*;\nuse crate::ser"
  },
  {
    "path": "courses/dss/percolator/src/service.rs",
    "chars": 690,
    "preview": "use crate::msg::{\n    CommitRequest, CommitResponse, GetRequest, GetResponse, PrewriteRequest, PrewriteResponse,\n    Tim"
  },
  {
    "path": "courses/dss/percolator/src/tests.rs",
    "chars": 13347,
    "preview": "use std::sync::{\n    atomic::{AtomicBool, Ordering},\n    Arc,\n};\nuse std::thread;\nuse std::time::Duration;\n\nuse labrpc::"
  },
  {
    "path": "courses/dss/raft/Cargo.toml",
    "chars": 615,
    "preview": "[package]\nname = \"raft\"\nversion = \"0.1.0\"\nauthors = [\n    \"Neil Shen <overvenus@gmail.com>\",\n    \"ShuNing <nolouch@gmail"
  },
  {
    "path": "courses/dss/raft/README.md",
    "chars": 15828,
    "preview": "# The Raft lab\n\nThis is a series of labs on a key/value storage system built with the Raft\nconsensus algorithm. These la"
  },
  {
    "path": "courses/dss/raft/build.rs",
    "chars": 630,
    "preview": "fn main() {\n    let includes = &[std::path::PathBuf::from(\"src/proto\")];\n    let mut protos = Vec::new();\n    for includ"
  },
  {
    "path": "courses/dss/raft/src/kvraft/client.rs",
    "chars": 1528,
    "preview": "use std::fmt;\n\nuse crate::proto::kvraftpb::*;\n\nenum Op {\n    Put(String, String),\n    Append(String, String),\n}\n\npub str"
  },
  {
    "path": "courses/dss/raft/src/kvraft/config.rs",
    "chars": 11752,
    "preview": "use std::collections::HashMap;\nuse std::sync::atomic::{AtomicUsize, Ordering};\nuse std::sync::{Arc, Mutex};\nuse std::tim"
  },
  {
    "path": "courses/dss/raft/src/kvraft/errors.rs",
    "chars": 458,
    "preview": "use std::{error, fmt, result};\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub enum Error {\n    NoLeader,\n}\n\nimpl fmt::Displ"
  },
  {
    "path": "courses/dss/raft/src/kvraft/mod.rs",
    "chars": 101,
    "preview": "pub mod client;\n#[cfg(test)]\npub mod config;\npub mod errors;\npub mod server;\n#[cfg(test)]\nmod tests;\n"
  },
  {
    "path": "courses/dss/raft/src/kvraft/server.rs",
    "chars": 2865,
    "preview": "use futures::channel::mpsc::unbounded;\n\nuse crate::proto::kvraftpb::*;\nuse crate::raft;\n\npub struct KvServer {\n    pub r"
  },
  {
    "path": "courses/dss/raft/src/kvraft/tests.rs",
    "chars": 29475,
    "preview": "use std::sync::atomic::{AtomicUsize, Ordering};\nuse std::sync::mpsc;\nuse std::sync::Arc;\nuse std::sync::Mutex;\nuse std::"
  },
  {
    "path": "courses/dss/raft/src/lib.rs",
    "chars": 282,
    "preview": "#[allow(unused_imports)]\n#[macro_use]\nextern crate log;\n#[allow(unused_imports)]\n#[macro_use]\nextern crate prost_derive;"
  },
  {
    "path": "courses/dss/raft/src/proto/kvraft.proto",
    "chars": 525,
    "preview": "syntax = \"proto3\";\n\npackage kvraftpb;\n\nenum Op {\n    Unknown = 0;\n    Put = 1;\n    Append = 2;\n}\n\n/// Put or Append\nmess"
  },
  {
    "path": "courses/dss/raft/src/proto/mod.rs",
    "chars": 877,
    "preview": "pub mod raftpb {\n    include!(concat!(env!(\"OUT_DIR\"), \"/raftpb.rs\"));\n\n    labrpc::service! {\n        service raft {\n  "
  },
  {
    "path": "courses/dss/raft/src/proto/raft.proto",
    "chars": 247,
    "preview": "syntax = \"proto3\";\n\npackage raftpb;\n\n// Example RequestVote RPC arguments structure.\nmessage RequestVoteArgs {\n    // Yo"
  },
  {
    "path": "courses/dss/raft/src/raft/config.rs",
    "chars": 17822,
    "preview": "use std::collections::HashMap;\nuse std::sync::atomic::{AtomicUsize, Ordering};\nuse std::sync::{Arc, Mutex};\nuse std::thr"
  },
  {
    "path": "courses/dss/raft/src/raft/errors.rs",
    "chars": 671,
    "preview": "use std::{error, fmt, result};\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub enum Error {\n    Encode(labcodec::EncodeError"
  },
  {
    "path": "courses/dss/raft/src/raft/mod.rs",
    "chars": 10449,
    "preview": "use std::sync::mpsc::{sync_channel, Receiver};\nuse std::sync::Arc;\n\nuse futures::channel::mpsc::UnboundedSender;\n\n#[cfg("
  },
  {
    "path": "courses/dss/raft/src/raft/persister.rs",
    "chars": 3203,
    "preview": "//! Support for Raft and kvraft to save persistent\n//! Raft state (log &c) and k/v server snapshots.\n//!\n//! we will use"
  },
  {
    "path": "courses/dss/raft/src/raft/tests.rs",
    "chars": 31245,
    "preview": "#![allow(clippy::identity_op)]\n\nuse std::sync::atomic::{AtomicUsize, Ordering};\nuse std::sync::mpsc::{channel, Sender};\n"
  },
  {
    "path": "courses/rust/.gitignore",
    "chars": 11,
    "preview": "*~\ntarget/\n"
  },
  {
    "path": "courses/rust/CONTRIBUTING.md",
    "chars": 4278,
    "preview": "# Contributing to PNA Rust\n\nContributions of any kind are welcome.\n\nFile bugs on the [issue tracker], no matter how smal"
  },
  {
    "path": "courses/rust/README.md",
    "chars": 7275,
    "preview": "# Practical Networked Applications in Rust\n\nA training course about practical systems software construction in [Rust].\n\n"
  },
  {
    "path": "courses/rust/building-blocks/bb-1.md",
    "chars": 2325,
    "preview": "# PNA Rust &mdash; Building Blocks 1\n\nLet's learn some building blocks!\n\nPut your other projects and concerns aside. Tak"
  },
  {
    "path": "courses/rust/building-blocks/bb-2.md",
    "chars": 6079,
    "preview": "# PNA Rust &mdash; Building Blocks 2\n\nLet's learn some building blocks!\n\nPut your other projects and concerns aside. Tak"
  },
  {
    "path": "courses/rust/building-blocks/bb-3.md",
    "chars": 2699,
    "preview": "# PNA Rust &mdash; Building Blocks 3\n\nLet's learn some building blocks!\n\nPut your other projects and concerns aside. Tak"
  },
  {
    "path": "courses/rust/building-blocks/bb-4.md",
    "chars": 4063,
    "preview": "# PNA Rust &mdash; Building Blocks 4\n\nLet's learn some building blocks!\n\nPut your other projects and concerns aside. Tak"
  },
  {
    "path": "courses/rust/building-blocks/bb-5.md",
    "chars": 272,
    "preview": "# PNA Rust &mdash; Building Blocks 5\n\nLet's learn some building blocks!\n\nPut your other projects and concerns aside. Tak"
  },
  {
    "path": "courses/rust/docs/etc/notes.md",
    "chars": 7469,
    "preview": "# Implementors' notes\n\n## Desired subjects\n\nThis is a more full list of topics to cover than\nin the README.\n\n- error han"
  },
  {
    "path": "courses/rust/docs/etc/parallel-diagrams.txt",
    "chars": 2125,
    "preview": "Used in p4. Edited with asciiflow.com.\n\n\n           --> read/write reqs over time -->                         --> read/w"
  },
  {
    "path": "courses/rust/docs/lesson-plan.md",
    "chars": 13243,
    "preview": "# PNA Rust Lesson plan\n\nA training course about practical systems software construction in Rust.\n\nOver a series of proje"
  },
  {
    "path": "courses/rust/docs/prerequisites.md",
    "chars": 442,
    "preview": "# PNA Rust Prerequisites\n\nDon't meet all the [prerequisites][pre] to take this course? Here are some ideas\nfor how to pr"
  },
  {
    "path": "courses/rust/docs/roadmap.md",
    "chars": 239,
    "preview": "# PNA Rust Roadmap\n\nWe've got a lot of ideas about how to extend and expand this course. But the\nroadmap isn't written y"
  },
  {
    "path": "courses/rust/docs/what-next.md",
    "chars": 64,
    "preview": "# What's next now that you've completed PNA Rust?\n\nComing soon!\n"
  },
  {
    "path": "courses/rust/projects/project-1/Cargo.toml",
    "chars": 233,
    "preview": "[package]\nname = \"kvs\"\nversion = \"0.1.0\"\nauthors = [\"Yilin Chen <sticnarf@gmail.com>\"]\ndescription = \"A key-value store\""
  },
  {
    "path": "courses/rust/projects/project-1/README.md",
    "chars": 24353,
    "preview": "# PNA Rust Project 1: The Rust toolbox\n\n**Task**: Create an in-memory key/value store that passes simple tests and respo"
  },
  {
    "path": "courses/rust/projects/project-1/src/bin/kvs.rs",
    "chars": 1677,
    "preview": "use clap::{App, AppSettings, Arg, SubCommand};\nuse std::process::exit;\n\nfn main() {\n    let matches = App::new(env!(\"CAR"
  },
  {
    "path": "courses/rust/projects/project-1/src/kv.rs",
    "chars": 1192,
    "preview": "use std::collections::HashMap;\n\n/// The `KvStore` stores string key/value pairs.\n///\n/// Key/value pairs are stored in a"
  },
  {
    "path": "courses/rust/projects/project-1/src/lib.rs",
    "chars": 84,
    "preview": "#![deny(missing_docs)]\n//! A simple key/value store.\n\npub use kv::KvStore;\n\nmod kv;\n"
  },
  {
    "path": "courses/rust/projects/project-1/tests/tests.rs",
    "chars": 3593,
    "preview": "use assert_cmd::prelude::*;\nuse kvs::KvStore;\nuse predicates::str::contains;\nuse std::process::Command;\n\n// `kvs` with n"
  },
  {
    "path": "courses/rust/projects/project-2/Cargo.toml",
    "chars": 364,
    "preview": "[package]\nname = \"kvs\"\nversion = \"0.1.0\"\nauthors = [\"Yilin Chen <sticnarf@gmail.com>\"]\ndescription = \"A key-value store\""
  },
  {
    "path": "courses/rust/projects/project-2/README.md",
    "chars": 19901,
    "preview": "# PNA Rust Project 2: Log-structured file I/O\n\n**Task**: Create a _persistent_ key/value store that _can be accessed fro"
  },
  {
    "path": "courses/rust/projects/project-2/src/bin/kvs.rs",
    "chars": 2508,
    "preview": "use clap::{App, AppSettings, Arg, SubCommand};\nuse kvs::{KvStore, KvsError, Result};\nuse std::env::current_dir;\nuse std:"
  },
  {
    "path": "courses/rust/projects/project-2/src/error.rs",
    "chars": 892,
    "preview": "use failure::Fail;\nuse std::io;\n\n/// Error type for kvs.\n#[derive(Fail, Debug)]\npub enum KvsError {\n    /// IO error.\n  "
  },
  {
    "path": "courses/rust/projects/project-2/src/kv.rs",
    "chars": 11626,
    "preview": "use std::collections::{BTreeMap, HashMap};\nuse std::fs::{self, File, OpenOptions};\nuse std::io::{self, BufReader, BufWri"
  },
  {
    "path": "courses/rust/projects/project-2/src/lib.rs",
    "chars": 130,
    "preview": "#![deny(missing_docs)]\n//! A simple key/value store.\n\npub use error::{KvsError, Result};\npub use kv::KvStore;\n\nmod error"
  },
  {
    "path": "courses/rust/projects/project-2/tests/tests.rs",
    "chars": 8463,
    "preview": "use assert_cmd::prelude::*;\nuse kvs::{KvStore, Result};\nuse predicates::ord::eq;\nuse predicates::str::{contains, is_empt"
  },
  {
    "path": "courses/rust/projects/project-3/Cargo.toml",
    "chars": 515,
    "preview": "[package]\nname = \"kvs\"\nversion = \"0.1.0\"\nauthors = [\"Yilin Chen <sticnarf@gmail.com>\"]\ndescription = \"A key-value store\""
  },
  {
    "path": "courses/rust/projects/project-3/README.md",
    "chars": 19084,
    "preview": "# PNA Rust Project 3: Synchronous client-server networking\n\n**Task**: Create a _single-threaded_, persistent key/value s"
  },
  {
    "path": "courses/rust/projects/project-3/benches/engine_bench.rs",
    "chars": 2611,
    "preview": "use criterion::{criterion_group, criterion_main, BatchSize, Criterion};\nuse kvs::{KvStore, KvsEngine, SledKvsEngine};\nus"
  },
  {
    "path": "courses/rust/projects/project-3/src/bin/kvs-client.rs",
    "chars": 2761,
    "preview": "use clap::AppSettings;\nuse kvs::{KvsClient, Result};\nuse std::net::SocketAddr;\nuse std::process::exit;\nuse structopt::St"
  },
  {
    "path": "courses/rust/projects/project-3/src/bin/kvs-server.rs",
    "chars": 2494,
    "preview": "use clap::arg_enum;\nuse kvs::*;\nuse log::LevelFilter;\nuse log::{error, info, warn};\nuse std::env::current_dir;\nuse std::"
  },
  {
    "path": "courses/rust/projects/project-3/src/client.rs",
    "chars": 2120,
    "preview": "use crate::common::{GetResponse, RemoveResponse, Request, SetResponse};\nuse crate::{KvsError, Result};\nuse serde::Deseri"
  },
  {
    "path": "courses/rust/projects/project-3/src/common.rs",
    "chars": 496,
    "preview": "use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Serialize, Deserialize)]\npub enum Request {\n    Get { key: String "
  },
  {
    "path": "courses/rust/projects/project-3/src/engines/kvs.rs",
    "chars": 11553,
    "preview": "use std::collections::{BTreeMap, HashMap};\nuse std::fs::{self, File, OpenOptions};\nuse std::io::{self, BufReader, BufWri"
  },
  {
    "path": "courses/rust/projects/project-3/src/engines/mod.rs",
    "chars": 801,
    "preview": "//! This module provides various key value storage engines.\n\nuse crate::Result;\n\n/// Trait for a key value storage engin"
  },
  {
    "path": "courses/rust/projects/project-3/src/engines/sled.rs",
    "chars": 994,
    "preview": "use super::KvsEngine;\nuse crate::{KvsError, Result};\nuse sled::{Db, Tree};\n\n/// Wrapper of `sled::Db`\n#[derive(Clone)]\np"
  },
  {
    "path": "courses/rust/projects/project-3/src/error.rs",
    "chars": 1503,
    "preview": "use failure::Fail;\nuse std::io;\nuse std::string::FromUtf8Error;\n\n/// Error type for kvs\n#[derive(Fail, Debug)]\npub enum "
  },
  {
    "path": "courses/rust/projects/project-3/src/lib.rs",
    "chars": 257,
    "preview": "#![deny(missing_docs)]\n//! A simple key/value store.\n\npub use client::KvsClient;\npub use engines::{KvStore, KvsEngine, S"
  },
  {
    "path": "courses/rust/projects/project-3/src/server.rs",
    "chars": 2503,
    "preview": "use crate::common::{GetResponse, RemoveResponse, Request, SetResponse};\nuse crate::{KvsEngine, Result};\nuse log::{debug,"
  },
  {
    "path": "courses/rust/projects/project-3/tests/cli.rs",
    "chars": 9393,
    "preview": "use assert_cmd::prelude::*;\nuse predicates::str::{contains, is_empty};\nuse std::fs::{self, File};\nuse std::process::Comm"
  },
  {
    "path": "courses/rust/projects/project-3/tests/kv_store.rs",
    "chars": 4267,
    "preview": "use kvs::{KvStore, KvsEngine, Result};\nuse tempfile::TempDir;\nuse walkdir::WalkDir;\n\n// Should get previously stored val"
  },
  {
    "path": "courses/rust/projects/project-4/Cargo.toml",
    "chars": 671,
    "preview": "[package]\nname = \"kvs\"\nversion = \"0.1.0\"\nauthors = [\"Yilin Chen <sticnarf@gmail.com>\"]\ndescription = \"A key-value store\""
  },
  {
    "path": "courses/rust/projects/project-4/README.md",
    "chars": 58092,
    "preview": "# PNA Rust Project 4: Concurrency and parallelism\n\n**Task**: Create a _multi-threaded_, persistent key/value store serve"
  },
  {
    "path": "courses/rust/projects/project-4/src/bin/kvs-client.rs",
    "chars": 2578,
    "preview": "use clap::AppSettings;\nuse kvs::{KvsClient, Result};\nuse std::net::SocketAddr;\nuse std::process::exit;\nuse structopt::St"
  },
  {
    "path": "courses/rust/projects/project-4/src/bin/kvs-server.rs",
    "chars": 2696,
    "preview": "use clap::arg_enum;\nuse kvs::thread_pool::*;\nuse kvs::*;\nuse log::LevelFilter;\nuse log::{error, info, warn};\nuse std::en"
  },
  {
    "path": "courses/rust/projects/project-4/src/client.rs",
    "chars": 2120,
    "preview": "use crate::common::{GetResponse, RemoveResponse, Request, SetResponse};\nuse crate::{KvsError, Result};\nuse serde::Deseri"
  },
  {
    "path": "courses/rust/projects/project-4/src/common.rs",
    "chars": 496,
    "preview": "use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Serialize, Deserialize)]\npub enum Request {\n    Get { key: String "
  },
  {
    "path": "courses/rust/projects/project-4/src/engines/kvs.rs",
    "chars": 15381,
    "preview": "use std::cell::RefCell;\nuse std::collections::BTreeMap;\nuse std::ffi::OsStr;\nuse std::fs::{self, File, OpenOptions};\nuse"
  },
  {
    "path": "courses/rust/projects/project-4/src/engines/mod.rs",
    "chars": 751,
    "preview": "pub use self::kvs::KvStore;\npub use self::sled::SledKvsEngine;\nuse crate::Result;\n\nmod kvs;\nmod sled;\n\n/// Trait for a k"
  },
  {
    "path": "courses/rust/projects/project-4/src/engines/sled.rs",
    "chars": 982,
    "preview": "use super::KvsEngine;\nuse crate::{KvsError, Result};\nuse sled::{Db, Tree};\n\n/// Wrapper of `sled::Db`\n#[derive(Clone)]\np"
  },
  {
    "path": "courses/rust/projects/project-4/src/error.rs",
    "chars": 1503,
    "preview": "use failure::Fail;\nuse std::io;\nuse std::string::FromUtf8Error;\n\n/// Error type for kvs\n#[derive(Fail, Debug)]\npub enum "
  },
  {
    "path": "courses/rust/projects/project-4/src/lib.rs",
    "chars": 279,
    "preview": "#![deny(missing_docs)]\n//! A simple key/value store.\n\npub use client::KvsClient;\npub use engines::{KvStore, KvsEngine, S"
  },
  {
    "path": "courses/rust/projects/project-4/src/server.rs",
    "chars": 2537,
    "preview": "use crate::common::{GetResponse, RemoveResponse, Request, SetResponse};\nuse crate::thread_pool::ThreadPool;\nuse crate::{"
  },
  {
    "path": "courses/rust/projects/project-4/src/thread_pool/mod.rs",
    "chars": 1046,
    "preview": "//! This module provides various thread pools. All thread pools should implement\n//! the `ThreadPool` trait.\n\nuse crate:"
  },
  {
    "path": "courses/rust/projects/project-4/src/thread_pool/naive.rs",
    "chars": 434,
    "preview": "use std::thread;\n\nuse super::ThreadPool;\nuse crate::Result;\n\n/// It is actually not a thread pool. It spawns a new threa"
  },
  {
    "path": "courses/rust/projects/project-4/src/thread_pool/rayon.rs",
    "chars": 560,
    "preview": "use super::ThreadPool;\nuse crate::{KvsError, Result};\n\n/// Wrapper of rayon::ThreadPool\npub struct RayonThreadPool(rayon"
  },
  {
    "path": "courses/rust/projects/project-4/src/thread_pool/shared_queue.rs",
    "chars": 2077,
    "preview": "use std::thread;\n\nuse super::ThreadPool;\nuse crate::Result;\n\nuse crossbeam::channel::{self, Receiver, Sender};\n\nuse log:"
  },
  {
    "path": "courses/rust/projects/project-4/tests/cli.rs",
    "chars": 9393,
    "preview": "use assert_cmd::prelude::*;\nuse predicates::str::{contains, is_empty};\nuse std::fs::{self, File};\nuse std::process::Comm"
  },
  {
    "path": "courses/rust/projects/project-4/tests/kv_store.rs",
    "chars": 6656,
    "preview": "use kvs::{KvStore, KvsEngine, Result};\nuse std::sync::{Arc, Barrier};\nuse std::thread;\nuse tempfile::TempDir;\nuse walkdi"
  },
  {
    "path": "courses/rust/projects/project-4/tests/thread_pool.rs",
    "chars": 1693,
    "preview": "use std::sync::atomic::{AtomicUsize, Ordering};\nuse std::sync::Arc;\n\nuse kvs::thread_pool::*;\nuse kvs::Result;\n\nuse cros"
  },
  {
    "path": "courses/rust/projects/project-5/Cargo.toml",
    "chars": 734,
    "preview": "[package]\nname = \"kvs\"\nversion = \"0.1.0\"\nauthors = [\"Yilin Chen <sticnarf@gmail.com>\"]\ndescription = \"A key-value store\""
  },
  {
    "path": "courses/rust/projects/project-5/README.md",
    "chars": 8808,
    "preview": "# Project: Asynchrony\n\n**Task**: Create a multi-threaded, persistent key/value store server and client\nwith _asynchronou"
  },
  {
    "path": "courses/rust/projects/project-5/src/bin/kvs-client.rs",
    "chars": 2739,
    "preview": "use clap::AppSettings;\nuse kvs::{KvsClient, Result};\nuse std::net::SocketAddr;\nuse std::process::exit;\nuse structopt::St"
  },
  {
    "path": "courses/rust/projects/project-5/src/bin/kvs-server.rs",
    "chars": 2834,
    "preview": "#[macro_use]\nextern crate log;\n#[macro_use]\nextern crate clap;\n\nuse kvs::thread_pool::*;\nuse kvs::{KvStore, KvsEngine, K"
  },
  {
    "path": "courses/rust/projects/project-5/src/client.rs",
    "chars": 3649,
    "preview": "use crate::common::{Request, Response};\nuse crate::KvsError;\nuse std::net::SocketAddr;\nuse tokio::codec::{FramedRead, Fr"
  },
  {
    "path": "courses/rust/projects/project-5/src/common.rs",
    "chars": 320,
    "preview": "use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Serialize, Deserialize)]\npub enum Request {\n    Get { key: String "
  },
  {
    "path": "courses/rust/projects/project-5/src/engines/kvs.rs",
    "chars": 17729,
    "preview": "use std::cell::RefCell;\nuse std::collections::BTreeMap;\nuse std::ffi::OsStr;\nuse std::fs::{self, File, OpenOptions};\nuse"
  },
  {
    "path": "courses/rust/projects/project-5/src/engines/mod.rs",
    "chars": 905,
    "preview": "pub use self::kvs::KvStore;\npub use self::sled::SledKvsEngine;\nuse crate::KvsError;\n\nuse tokio::prelude::Future;\n\nmod kv"
  },
  {
    "path": "courses/rust/projects/project-5/src/engines/sled.rs",
    "chars": 2651,
    "preview": "use crate::thread_pool::ThreadPool;\nuse crate::{KvsEngine, KvsError, Result};\nuse sled::Db;\nuse tokio::prelude::*;\nuse t"
  },
  {
    "path": "courses/rust/projects/project-5/src/error.rs",
    "chars": 1503,
    "preview": "use failure::Fail;\nuse std::io;\nuse std::string::FromUtf8Error;\n\n/// Error type for kvs\n#[derive(Fail, Debug)]\npub enum "
  },
  {
    "path": "courses/rust/projects/project-5/src/lib.rs",
    "chars": 311,
    "preview": "#![deny(missing_docs)]\n//! A simple key/value store.\n\n#[macro_use]\nextern crate log;\n\npub use client::KvsClient;\npub use"
  },
  {
    "path": "courses/rust/projects/project-5/src/server.rs",
    "chars": 2318,
    "preview": "use crate::common::{Request, Response};\nuse crate::{KvsEngine, KvsError, Result};\nuse std::net::SocketAddr;\nuse tokio::c"
  },
  {
    "path": "courses/rust/projects/project-5/src/thread_pool/mod.rs",
    "chars": 1070,
    "preview": "//! This module provides various thread pools. All thread pools should implement\n//! the `ThreadPool` trait.\n\nuse crate:"
  },
  {
    "path": "courses/rust/projects/project-5/src/thread_pool/naive.rs",
    "chars": 451,
    "preview": "use std::thread;\n\nuse super::ThreadPool;\nuse crate::Result;\n\n/// It is actually not a thread pool. It spawns a new threa"
  },
  {
    "path": "courses/rust/projects/project-5/src/thread_pool/rayon.rs",
    "chars": 612,
    "preview": "use super::ThreadPool;\nuse crate::{KvsError, Result};\nuse std::sync::Arc;\n\n/// Wrapper of rayon::ThreadPool\n#[derive(Clo"
  },
  {
    "path": "courses/rust/projects/project-5/src/thread_pool/shared_queue.rs",
    "chars": 2068,
    "preview": "use std::thread;\n\nuse super::ThreadPool;\nuse crate::Result;\n\nuse crossbeam::channel::{self, Receiver, Sender};\n\n// Note "
  },
  {
    "path": "courses/rust/projects/project-5/tests/cli.rs",
    "chars": 9393,
    "preview": "use assert_cmd::prelude::*;\nuse predicates::str::{contains, is_empty};\nuse std::fs::{self, File};\nuse std::process::Comm"
  },
  {
    "path": "courses/rust/projects/project-5/tests/kv_store.rs",
    "chars": 7642,
    "preview": "use kvs::thread_pool::RayonThreadPool;\nuse kvs::{KvStore, KvsEngine, KvsError, Result};\nuse tempfile::TempDir;\nuse tokio"
  },
  {
    "path": "courses/rust/projects/project-5/tests/thread_pool.rs",
    "chars": 1693,
    "preview": "use std::sync::atomic::{AtomicUsize, Ordering};\nuse std::sync::Arc;\n\nuse kvs::thread_pool::*;\nuse kvs::Result;\n\nuse cros"
  },
  {
    "path": "courses/tp101-intro-to-oss.md",
    "chars": 4682,
    "preview": "# TP 101: Introduction to Open Source Software\n\nThis course includes a collection of some open source software related l"
  },
  {
    "path": "courses/tp102-how-to-use-git-github.md",
    "chars": 3153,
    "preview": "# TP 102: How to Use Git and GitHub\n\nGit and GitHub are commonly used tools in open source practice. Whether you are con"
  },
  {
    "path": "courses/tp103-open-source-community.md",
    "chars": 5120,
    "preview": "# TP 103: Build A Welcoming Community\n\nA welcoming community is an investment into your project’s future and reputation."
  },
  {
    "path": "talent-challenge-program/MENTEE_APPLY_TEMPLATE.md",
    "chars": 514,
    "preview": "# Mentee Apply Template\n\nMail to: talent-plan@tidb.io\n\n## Mail Subject: \n\nTCP Mentee Application - {project name} - {per"
  },
  {
    "path": "talent-challenge-program/PROJECT_IDEA_TEMPLATE.md",
    "chars": 133,
    "preview": "```\n#### TiDB Ecosystem Project Name\n##### Title\n- Description:\n- Recommended Skills:\n- Mentor(s):\n- Upstream Issue or R"
  },
  {
    "path": "talent-challenge-program/README.md",
    "chars": 3132,
    "preview": "# Talent Challenge Program\n\nTalent Challenge program is a platform that offers a structured remote mentoring program for"
  },
  {
    "path": "talent-challenge-program/project-ideas.md",
    "chars": 11055,
    "preview": "## Project ideas\n\nProject maintainers and mentors, please submit the ideas below section using the template. Project ide"
  },
  {
    "path": "talent-challenge-program/s1.md",
    "chars": 976,
    "preview": "# Talent Challenge Program Season 1\n\n_Status: ongoing_\n\n### Timeline\n_Note: this timeline is proposed and may be subject"
  },
  {
    "path": "talent-challenge-program/selected-projects.md",
    "chars": 7341,
    "preview": "## Selected Projects in Season 1\n\nSelected Projects in Season 1 are listed below. Mentee candidates who want to particip"
  },
  {
    "path": "talent-challenge-program2021/MENTEE_APPLY_TEMPLATE.md",
    "chars": 576,
    "preview": "# Mentee Application Form Template\n\nMail to: talent-plan@tidb.io\n\n## Mail Subject: \n\nTCP Mentee Application - {project n"
  },
  {
    "path": "talent-challenge-program2021/PROJECT_IDEA_TEMPLATE.md",
    "chars": 569,
    "preview": "```\n\n## Description\n\nwhat's the problem, how to solve it\n\n## Document Collection\n\n- Proposal doc: ${proposal doc}\n- Week"
  },
  {
    "path": "talent-challenge-program2021/README.md",
    "chars": 3188,
    "preview": "# Talent Challenge Program 2021\n\nTalent Challenge program is a platform that offers a structured remote mentoring progra"
  },
  {
    "path": "talent-challenge-program2021/project-ideas.md",
    "chars": 864,
    "preview": "## Project ideas\n\nProject maintainers and mentors, please submit the ideas below section using the template. Project ide"
  },
  {
    "path": "talent-challenge-program2021/schedule.md",
    "chars": 1820,
    "preview": "# Talent Challenge Program 2021 Schedule\n\n_Status: ongoing_\n\n### Timeline\n_Note: this timeline is proposed and may be su"
  },
  {
    "path": "talent-challenge-program2021/selected-projects.md",
    "chars": 3237,
    "preview": "## Selected Projects in Season 1\n\nSelected Projects in Sprint 1 are listed below. Mentee candidates who want to particip"
  },
  {
    "path": "talent-plan-1.0/1.0-lp-tidb.md",
    "chars": 2823,
    "preview": "# 路径 1:TiDB 方向\n\n## 课程目标\n* 掌握 Go 语言\n* 掌握分布式计算基本原理\n* 掌握数据库基础知识\n* 掌握优化器和执行引擎基本原理\n\n## 课程内容\n\n### Section 1 熟悉 Go 语言基础知识\n\n**学习"
  },
  {
    "path": "talent-plan-1.0/1.0-lp-tikv.md",
    "chars": 2070,
    "preview": "# 路径 2:TiKV 方向\n\n## 课程目标\n* 掌握 Rust 语言\n* 掌握分布式一致性算法 Raft\n* 掌握分布式存储基本原理\n\n## 课程内容\n\n### Section 1 熟悉 Rust 语言基础知识\n\n**学习资料:**\n\n"
  },
  {
    "path": "talent-plan-1.0/README-CN.md",
    "chars": 1064,
    "preview": "# Talent Plan Courses 1.0\n\nTalent Plan 1.0 课程中共有 2 条学习路径供大家选择,分别是:\n\n* 面向分布式关系型数据库 SQL 层的 [TiDB 方向](1.0-lp-tidb.md)\n* 面向分"
  },
  {
    "path": "tidb/.gitignore",
    "chars": 7,
    "preview": ".idea/\n"
  },
  {
    "path": "tidb/README.md",
    "chars": 136,
    "preview": "# Distributed Systems in Go\n\n* Week 1: [Merge Sort](./mergesort)\n* Week 2: [Map Reduce](./mapreduce)\n* Week 4: [Parallel"
  },
  {
    "path": "tidb/join/Makefile",
    "chars": 106,
    "preview": ".PHONY: all\n\nall: test bench\n\ntest:\n\tgo test\n\nbench:\n\tgo test -bench Benchmark -run xx -count 5 -benchmem\n"
  },
  {
    "path": "tidb/join/README.md",
    "chars": 3207,
    "preview": "## Introduction\n\nThis is the homework for PingCAP Talent Plan Online of week 4. This homework is a simplified version of"
  },
  {
    "path": "tidb/join/benchmark_test.go",
    "chars": 293,
    "preview": "package main\n\nimport \"testing\"\n\nfunc BenchmarkJoin(b *testing.B) {\n\tfor i := 0; i < b.N; i++ {\n\t\tJoin(\"./t/r0.tbl\", \"./t"
  },
  {
    "path": "tidb/join/go.mod",
    "chars": 140,
    "preview": "module join\n\ngo 1.12\n\nrequire (\n\tgithub.com/pingcap/check v0.0.0-20171206051426-1c287c953996\n\tgithub.com/pingcap/tidb v2"
  },
  {
    "path": "tidb/join/go.sum",
    "chars": 8861,
    "preview": "github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/apache/thrift v0.0.0"
  },
  {
    "path": "tidb/join/join.go",
    "chars": 530,
    "preview": "package main\n\n// Join accepts a join query of two relations, and returns the sum of\n// relation0.col0 in the final resul"
  },
  {
    "path": "tidb/join/join_example.go",
    "chars": 1892,
    "preview": "package main\n\nimport (\n\t\"encoding/csv\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"unsafe\"\n\n\t\"github.com/pingcap/tidb/util/mvmap\"\n)\n\n// Joi"
  },
  {
    "path": "tidb/join/join_test.go",
    "chars": 1258,
    "preview": "package main\n\nimport (\n\t\"testing\"\n\n\t\"github.com/pingcap/check\"\n)\n\ntype joinTestSuite struct{}\n\nfunc TestT(t *testing.T) "
  },
  {
    "path": "tidb/join/t/r0.tbl",
    "chars": 107156,
    "preview": "1,7277\n3,7506\n7,10488\n11,4923\n15,7803\n19,9251\n23,9239\n28,9961\n31,8944\n33,5726\n38,4517\n39,10350\n41,9926\n42,9587\n45,8220\n4"
  },
  {
    "path": "tidb/join/t/r1.tbl",
    "chars": 126213,
    "preview": "1,4363123,46773,6709\n2,1431076,902781,8246\n4,2792150,84359,8209\n8,4966517,375246,7436\n9,10590291,822710,6358\n14,5452431,"
  },
  {
    "path": "tidb/join/t/r2.tbl",
    "chars": 9543,
    "preview": "2,56746,1311922\n6,819360,6450995\n9,264752,5435660\n10,479664,7937731\n11,367646,5162612\n13,392351,4908357\n14,790354,509078"
  },
  {
    "path": "tidb/mapreduce/.gitignore",
    "chars": 7,
    "preview": ".idea/\n"
  },
  {
    "path": "tidb/mapreduce/Makefile",
    "chars": 235,
    "preview": ".PHONY: all\n\nall: test_example test_homework cleanup gendata\n\ntest_example:\n\tgo test -v -run=TestExampleURLTop\n\ntest_hom"
  },
  {
    "path": "tidb/mapreduce/README.md",
    "chars": 2139,
    "preview": "## Introduction\n\nThis is the Map-Reduce homework for PingCAP Talent Plan Online of week 2.\n\nThere is a uncompleted Map-R"
  },
  {
    "path": "tidb/mapreduce/casegen.go",
    "chars": 6087,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"path\"\n\t\"sort\"\n)\n\ntype DataSize int\n\nconst (\n\tKB = 1 << 10\n\tMB = 1 << 20\n\tGB"
  },
  {
    "path": "tidb/mapreduce/go.mod",
    "chars": 23,
    "preview": "module talent\n\ngo 1.12\n"
  },
  {
    "path": "tidb/mapreduce/go.sum",
    "chars": 114,
    "preview": "github.com/pingcap/talent-plan v0.0.0-20190408125936-2f97dda786d6 h1:Kr1alXUfrJVBcLQb9tbrZGpInKkBhGLZsuMKNfesH1I=\n"
  },
  {
    "path": "tidb/mapreduce/mapreduce.go",
    "chars": 4250,
    "preview": "package main\n\nimport (\n\t\"bufio\"\n\t\"encoding/json\"\n\t\"hash/fnv\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\t\"path\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"s"
  },
  {
    "path": "tidb/mapreduce/urltop10.go",
    "chars": 174,
    "preview": "package main\n\n// URLTop10 .\nfunc URLTop10(nWorkers int) RoundsArgs {\n\t// YOUR CODE HERE :)\n\t// And don't forget to docum"
  },
  {
    "path": "tidb/mapreduce/urltop10_example.go",
    "chars": 2124,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// ExampleURLTop10 generates RoundsArgs for getting the "
  },
  {
    "path": "tidb/mapreduce/urltop10_test.go",
    "chars": 2315,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"path\"\n\t\"runtime\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc testDataScale() ([]DataSize, []"
  },
  {
    "path": "tidb/mapreduce/utils.go",
    "chars": 2509,
    "preview": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// RoundArgs contains arguments "
  },
  {
    "path": "tidb/mergesort/Makefile",
    "chars": 107,
    "preview": ".PHONY: all\n\nall: test bench\n\ntest:\n\tgo test\n\nbench:\n\tgo test -bench Benchmark -run xx -count 5 -benchmem\n\n"
  },
  {
    "path": "tidb/mergesort/README.md",
    "chars": 1003,
    "preview": "## Introduction\n\nThis is the Merge Sort home work for PingCAP Talent Plan Online of week 1.\n\nThere are 16, 000, 000 int6"
  },
  {
    "path": "tidb/mergesort/bench_test.go",
    "chars": 658,
    "preview": "package main\n\nimport (\n\t\"sort\"\n\t\"testing\"\n)\n\nfunc BenchmarkMergeSort(b *testing.B) {\n\tnumElements := 16 << 20\n\tsrc := ma"
  },
  {
    "path": "tidb/mergesort/go.mod",
    "chars": 119,
    "preview": "module pingcap/talentplan/tidb/mergesort\n\ngo 1.12\n\nrequire github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8\n"
  },
  {
    "path": "tidb/mergesort/go.sum",
    "chars": 223,
    "preview": "github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8 h1:USx2/E1bX46VG32FIw034Au6seQ2fY9NEILmNh/UlQg=\ngithub.com/p"
  },
  {
    "path": "tidb/mergesort/mergesort.go",
    "chars": 158,
    "preview": "package main\n\n// MergeSort performs the merge sort algorithm.\n// Please supplement this function to accomplish the home "
  },
  {
    "path": "tidb/mergesort/mergesort_test.go",
    "chars": 773,
    "preview": "package main\n\nimport (\n\t\"math/rand\"\n\t\"sort\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/pingcap/check\"\n)\n\nvar _ = check.Suite(&sort"
  }
]

About this extraction

This page contains the full source code of the pingcap/talent-plan GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 195 files (1.6 MB), approximately 674.3k tokens, and a symbol index with 869 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!