Full Code of etcd-io/dbtester for AI

master 4c8e30b24d6d cached
1452 files
28.6 MB
7.6M tokens
85654 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (30,258K chars total). Download the full file to get everything.
Repository: etcd-io/dbtester
Branch: master
Commit: 4c8e30b24d6d
Files: 1452
Total size: 28.6 MB

Directory structure:
gitextract_jgj486as/

├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── DCO
├── Gopkg.toml
├── LICENSE
├── NOTICE
├── README.md
├── agent/
│   ├── agent_cetcd.go
│   ├── agent_consul.go
│   ├── agent_etcd.go
│   ├── agent_zetcd.go
│   ├── agent_zookeeper.go
│   ├── command.go
│   ├── doc.go
│   ├── server.go
│   ├── server_system_metrics.go
│   ├── upload_log.go
│   └── util.go
├── analyze/
│   ├── 01_read_raw_data_to_test_data.go
│   ├── 02_read_all_metrics_to_analyze_data.go
│   ├── 03_read_benchmark_metrics_to_analyze_data.go
│   ├── 04_aggregate_all_analyze_data.go
│   ├── 05_plot.go
│   ├── command.go
│   ├── doc.go
│   ├── logger.go
│   └── util.go
├── broadcast_request.go
├── cmd/
│   └── dbtester/
│       └── main.go
├── code-of-conduct.md
├── config-dbtester-gcloud-key.json
├── config_dbtester.go
├── config_dbtester_test.go
├── config_dbtester_test.yaml
├── control/
│   ├── command.go
│   └── logger.go
├── dbtesterpb/
│   ├── config_analyze_machine.pb.go
│   ├── config_analyze_machine.proto
│   ├── config_client_machine.pb.go
│   ├── config_client_machine.proto
│   ├── database_id.pb.go
│   ├── database_id.proto
│   ├── flag_cetcd.pb.go
│   ├── flag_cetcd.proto
│   ├── flag_consul.pb.go
│   ├── flag_consul.proto
│   ├── flag_etcd.pb.go
│   ├── flag_etcd.proto
│   ├── flag_zetcd.pb.go
│   ├── flag_zetcd.proto
│   ├── flag_zookeeper.pb.go
│   ├── flag_zookeeper.proto
│   ├── message.pb.go
│   ├── message.proto
│   └── util.go
├── find_ranges.go
├── find_ranges_test.go
├── pkg/
│   ├── fileinspect/
│   │   ├── fileinspect.go
│   │   └── fileinspect_test.go
│   ├── ntp/
│   │   ├── ntp.go
│   │   └── ntp_test.go
│   └── remotestorage/
│       ├── doc.go
│       ├── example/
│       │   ├── agent.log
│       │   ├── key.json
│       │   └── main.go
│       ├── op.go
│       ├── uploader.go
│       └── util.go
├── readme.go
├── report.go
├── report_save_upload.go
├── scripts/
│   ├── dbtester-google-cloud.sh
│   ├── genproto.sh
│   ├── install-cetcd.sh
│   ├── install-consul.sh
│   ├── install-etcd.sh
│   ├── install-go.sh
│   ├── install-zetcd.sh
│   ├── install-zookeeper-ubuntu.sh
│   ├── tests.sh
│   └── updatedep.sh
├── stress.go
├── stress_client.go
├── stress_client_consul.go
├── stress_client_etcdv3.go
├── stress_client_zookeeper.go
├── test-configs/
│   ├── read-3M-same-keys-1K-client.yaml
│   ├── read-3M-same-keys-best-throughput-etcd.yaml
│   ├── read-3M-same-keys-best-throughput.yaml
│   ├── write-100K-keys-1-client.yaml
│   ├── write-1M-keys-1000QPS.yaml
│   ├── write-1M-keys-best-throughput.yaml
│   ├── write-1M-keys-client-variable.yaml
│   └── write-too-many-keys.yaml
├── test-results/
│   ├── 2017Q1-00-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2017Q1-01-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2017Q2-01-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2017Q2-02-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2018Q1-01-etcd/
│   │   └── README.md
│   ├── 2018Q1-02-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2018Q1-03-etcd-kubemark/
│   │   └── README.md
│   ├── 2018Q1-04-etcd-zookeeper/
│   │   └── README.md
│   ├── 2018Q2-01-etcd-client-balancer/
│   │   ├── README.md
│   │   ├── read-3M-same-keys-best-throughput.yaml
│   │   └── write-1M-keys-best-throughput.yaml
│   └── 2018Q2-02-etcd-client-balancer/
│       ├── README.md
│       ├── read-3M-same-keys-best-throughput.yaml
│       └── write-1M-keys-best-throughput.yaml
├── util.go
├── util_test.go
└── vendor/
    ├── bitbucket.org/
    │   └── zombiezen/
    │       └── gopdf/
    │           ├── LICENSE
    │           └── pdf/
    │               ├── canvas.go
    │               ├── doc.go
    │               ├── encode.go
    │               ├── image.go
    │               ├── marshal.go
    │               ├── metrics.go
    │               ├── objects.go
    │               ├── pdf.go
    │               ├── stream.go
    │               └── text.go
    ├── cloud.google.com/
    │   └── go/
    │       ├── LICENSE
    │       ├── cloud.go
    │       ├── compute/
    │       │   └── metadata/
    │       │       └── metadata.go
    │       ├── iam/
    │       │   └── iam.go
    │       ├── internal/
    │       │   ├── annotate.go
    │       │   ├── optional/
    │       │   │   └── optional.go
    │       │   ├── retry.go
    │       │   └── version/
    │       │       └── version.go
    │       └── storage/
    │           ├── acl.go
    │           ├── bucket.go
    │           ├── copy.go
    │           ├── doc.go
    │           ├── go110.go
    │           ├── go17.go
    │           ├── iam.go
    │           ├── invoke.go
    │           ├── not_go110.go
    │           ├── not_go17.go
    │           ├── notifications.go
    │           ├── reader.go
    │           ├── storage.go
    │           └── writer.go
    ├── github.com/
    │   ├── ajstarks/
    │   │   └── svgo/
    │   │       ├── LICENSE
    │   │       ├── doc.go
    │   │       └── svg.go
    │   ├── cheggaaa/
    │   │   └── pb/
    │   │       ├── LICENSE
    │   │       ├── format.go
    │   │       ├── pb.go
    │   │       ├── pb_appengine.go
    │   │       ├── pb_win.go
    │   │       ├── pb_x.go
    │   │       ├── pool.go
    │   │       ├── pool_win.go
    │   │       ├── pool_x.go
    │   │       ├── reader.go
    │   │       ├── runecount.go
    │   │       ├── termios_bsd.go
    │   │       └── termios_sysv.go
    │   ├── coreos/
    │   │   ├── etcd/
    │   │   │   ├── LICENSE
    │   │   │   ├── NOTICE
    │   │   │   ├── auth/
    │   │   │   │   ├── authpb/
    │   │   │   │   │   └── auth.pb.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── jwt.go
    │   │   │   │   ├── nop.go
    │   │   │   │   ├── range_perm_cache.go
    │   │   │   │   ├── simple_token.go
    │   │   │   │   └── store.go
    │   │   │   ├── client/
    │   │   │   │   ├── auth_role.go
    │   │   │   │   ├── auth_user.go
    │   │   │   │   ├── cancelreq.go
    │   │   │   │   ├── client.go
    │   │   │   │   ├── cluster_error.go
    │   │   │   │   ├── curl.go
    │   │   │   │   ├── discover.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── keys.generated.go
    │   │   │   │   ├── keys.go
    │   │   │   │   ├── members.go
    │   │   │   │   └── util.go
    │   │   │   ├── clientv3/
    │   │   │   │   ├── auth.go
    │   │   │   │   ├── balancer/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   └── grpc1.7-health.go
    │   │   │   │   ├── client.go
    │   │   │   │   ├── cluster.go
    │   │   │   │   ├── compact_op.go
    │   │   │   │   ├── compare.go
    │   │   │   │   ├── config.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── kv.go
    │   │   │   │   ├── lease.go
    │   │   │   │   ├── logger.go
    │   │   │   │   ├── maintenance.go
    │   │   │   │   ├── op.go
    │   │   │   │   ├── options.go
    │   │   │   │   ├── ready_wait.go
    │   │   │   │   ├── retry.go
    │   │   │   │   ├── sort.go
    │   │   │   │   ├── txn.go
    │   │   │   │   └── watch.go
    │   │   │   ├── etcdserver/
    │   │   │   │   ├── api/
    │   │   │   │   │   ├── capability.go
    │   │   │   │   │   ├── cluster.go
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   └── v3rpc/
    │   │   │   │   │       ├── auth.go
    │   │   │   │   │       ├── codec.go
    │   │   │   │   │       ├── grpc.go
    │   │   │   │   │       ├── header.go
    │   │   │   │   │       ├── interceptor.go
    │   │   │   │   │       ├── key.go
    │   │   │   │   │       ├── lease.go
    │   │   │   │   │       ├── maintenance.go
    │   │   │   │   │       ├── member.go
    │   │   │   │   │       ├── metrics.go
    │   │   │   │   │       ├── quota.go
    │   │   │   │   │       ├── rpctypes/
    │   │   │   │   │       │   ├── doc.go
    │   │   │   │   │       │   ├── error.go
    │   │   │   │   │       │   ├── md.go
    │   │   │   │   │       │   └── metadatafields.go
    │   │   │   │   │       ├── util.go
    │   │   │   │   │       └── watch.go
    │   │   │   │   ├── apply.go
    │   │   │   │   ├── apply_auth.go
    │   │   │   │   ├── apply_v2.go
    │   │   │   │   ├── backend.go
    │   │   │   │   ├── cluster_util.go
    │   │   │   │   ├── config.go
    │   │   │   │   ├── consistent_index.go
    │   │   │   │   ├── corrupt.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── errors.go
    │   │   │   │   ├── etcdserverpb/
    │   │   │   │   │   ├── etcdserver.pb.go
    │   │   │   │   │   ├── raft_internal.pb.go
    │   │   │   │   │   ├── raft_internal_stringer.go
    │   │   │   │   │   └── rpc.pb.go
    │   │   │   │   ├── metrics.go
    │   │   │   │   ├── quota.go
    │   │   │   │   ├── raft.go
    │   │   │   │   ├── server.go
    │   │   │   │   ├── server_access_control.go
    │   │   │   │   ├── snapshot_merge.go
    │   │   │   │   ├── storage.go
    │   │   │   │   ├── util.go
    │   │   │   │   ├── v2_server.go
    │   │   │   │   └── v3_server.go
    │   │   │   ├── main.go
    │   │   │   ├── mvcc/
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── index.go
    │   │   │   │   ├── key_index.go
    │   │   │   │   ├── kv.go
    │   │   │   │   ├── kv_view.go
    │   │   │   │   ├── kvstore.go
    │   │   │   │   ├── kvstore_compaction.go
    │   │   │   │   ├── kvstore_txn.go
    │   │   │   │   ├── metrics.go
    │   │   │   │   ├── metrics_txn.go
    │   │   │   │   ├── mvccpb/
    │   │   │   │   │   └── kv.pb.go
    │   │   │   │   ├── revision.go
    │   │   │   │   ├── util.go
    │   │   │   │   ├── watchable_store.go
    │   │   │   │   ├── watchable_store_txn.go
    │   │   │   │   ├── watcher.go
    │   │   │   │   └── watcher_group.go
    │   │   │   ├── pkg/
    │   │   │   │   ├── cpuutil/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   └── endian.go
    │   │   │   │   ├── logutil/
    │   │   │   │   │   ├── discard_logger.go
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   ├── logger.go
    │   │   │   │   │   ├── merge_logger.go
    │   │   │   │   │   ├── package_logger.go
    │   │   │   │   │   ├── zap_grpc.go
    │   │   │   │   │   ├── zap_journal.go
    │   │   │   │   │   └── zap_raft.go
    │   │   │   │   ├── netutil/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   ├── isolate_linux.go
    │   │   │   │   │   ├── isolate_stub.go
    │   │   │   │   │   ├── netutil.go
    │   │   │   │   │   ├── routes.go
    │   │   │   │   │   └── routes_linux.go
    │   │   │   │   ├── report/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   ├── report.go
    │   │   │   │   │   ├── timeseries.go
    │   │   │   │   │   └── weighted.go
    │   │   │   │   ├── systemd/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   └── journal.go
    │   │   │   │   └── types/
    │   │   │   │       ├── doc.go
    │   │   │   │       ├── id.go
    │   │   │   │       ├── set.go
    │   │   │   │       ├── slice.go
    │   │   │   │       ├── urls.go
    │   │   │   │       └── urlsmap.go
    │   │   │   └── raft/
    │   │   │       ├── doc.go
    │   │   │       ├── log.go
    │   │   │       ├── log_unstable.go
    │   │   │       ├── logger.go
    │   │   │       ├── node.go
    │   │   │       ├── progress.go
    │   │   │       ├── raft.go
    │   │   │       ├── raftpb/
    │   │   │       │   └── raft.pb.go
    │   │   │       ├── rawnode.go
    │   │   │       ├── read_only.go
    │   │   │       ├── status.go
    │   │   │       ├── storage.go
    │   │   │       └── util.go
    │   │   ├── go-systemd/
    │   │   │   ├── LICENSE
    │   │   │   └── journal/
    │   │   │       └── journal.go
    │   │   └── pkg/
    │   │       ├── LICENSE
    │   │       ├── NOTICE
    │   │       └── capnslog/
    │   │           ├── formatters.go
    │   │           ├── glog_formatter.go
    │   │           ├── init.go
    │   │           ├── init_windows.go
    │   │           ├── journald_formatter.go
    │   │           ├── log_hijack.go
    │   │           ├── logmap.go
    │   │           ├── pkg_logger.go
    │   │           └── syslog_formatter.go
    │   ├── dustin/
    │   │   └── go-humanize/
    │   │       ├── LICENSE
    │   │       ├── big.go
    │   │       ├── bigbytes.go
    │   │       ├── bytes.go
    │   │       ├── comma.go
    │   │       ├── commaf.go
    │   │       ├── ftoa.go
    │   │       ├── humanize.go
    │   │       ├── number.go
    │   │       ├── ordinals.go
    │   │       ├── si.go
    │   │       └── times.go
    │   ├── gogo/
    │   │   └── protobuf/
    │   │       ├── LICENSE
    │   │       ├── gogoproto/
    │   │       │   ├── doc.go
    │   │       │   ├── gogo.pb.go
    │   │       │   └── helper.go
    │   │       ├── proto/
    │   │       │   ├── clone.go
    │   │       │   ├── decode.go
    │   │       │   ├── decode_gogo.go
    │   │       │   ├── duration.go
    │   │       │   ├── duration_gogo.go
    │   │       │   ├── encode.go
    │   │       │   ├── encode_gogo.go
    │   │       │   ├── equal.go
    │   │       │   ├── extensions.go
    │   │       │   ├── extensions_gogo.go
    │   │       │   ├── lib.go
    │   │       │   ├── lib_gogo.go
    │   │       │   ├── message_set.go
    │   │       │   ├── pointer_reflect.go
    │   │       │   ├── pointer_reflect_gogo.go
    │   │       │   ├── pointer_unsafe.go
    │   │       │   ├── pointer_unsafe_gogo.go
    │   │       │   ├── properties.go
    │   │       │   ├── properties_gogo.go
    │   │       │   ├── skip_gogo.go
    │   │       │   ├── text.go
    │   │       │   ├── text_gogo.go
    │   │       │   ├── text_parser.go
    │   │       │   ├── timestamp.go
    │   │       │   └── timestamp_gogo.go
    │   │       └── protoc-gen-gogo/
    │   │           ├── descriptor/
    │   │           │   ├── descriptor.go
    │   │           │   ├── descriptor.pb.go
    │   │           │   ├── descriptor_gostring.gen.go
    │   │           │   └── helper.go
    │   │           ├── doc.go
    │   │           └── main.go
    │   ├── golang/
    │   │   ├── freetype/
    │   │   │   ├── LICENSE
    │   │   │   ├── freetype.go
    │   │   │   ├── licenses/
    │   │   │   │   ├── ftl.txt
    │   │   │   │   └── gpl.txt
    │   │   │   ├── raster/
    │   │   │   │   ├── geom.go
    │   │   │   │   ├── paint.go
    │   │   │   │   ├── raster.go
    │   │   │   │   └── stroke.go
    │   │   │   └── truetype/
    │   │   │       ├── face.go
    │   │   │       ├── glyph.go
    │   │   │       ├── hint.go
    │   │   │       ├── opcodes.go
    │   │   │       └── truetype.go
    │   │   └── protobuf/
    │   │       ├── LICENSE
    │   │       ├── proto/
    │   │       │   ├── clone.go
    │   │       │   ├── decode.go
    │   │       │   ├── encode.go
    │   │       │   ├── equal.go
    │   │       │   ├── extensions.go
    │   │       │   ├── lib.go
    │   │       │   ├── message_set.go
    │   │       │   ├── pointer_reflect.go
    │   │       │   ├── pointer_unsafe.go
    │   │       │   ├── properties.go
    │   │       │   ├── text.go
    │   │       │   └── text_parser.go
    │   │       ├── protoc-gen-go/
    │   │       │   ├── descriptor/
    │   │       │   │   └── descriptor.pb.go
    │   │       │   ├── doc.go
    │   │       │   ├── link_grpc.go
    │   │       │   └── main.go
    │   │       └── ptypes/
    │   │           ├── any/
    │   │           │   └── any.pb.go
    │   │           ├── any.go
    │   │           ├── doc.go
    │   │           ├── duration/
    │   │           │   └── duration.pb.go
    │   │           ├── duration.go
    │   │           ├── timestamp/
    │   │           │   └── timestamp.pb.go
    │   │           └── timestamp.go
    │   ├── googleapis/
    │   │   └── gax-go/
    │   │       ├── LICENSE
    │   │       ├── call_option.go
    │   │       ├── gax.go
    │   │       ├── header.go
    │   │       └── invoke.go
    │   ├── gyuho/
    │   │   ├── dataframe/
    │   │   │   ├── LICENSE
    │   │   │   ├── column.go
    │   │   │   ├── dataframe.go
    │   │   │   ├── doc.go
    │   │   │   ├── sorter.go
    │   │   │   ├── util.go
    │   │   │   ├── value.go
    │   │   │   ├── value_data_type.go
    │   │   │   ├── value_sort.go
    │   │   │   ├── value_string.go
    │   │   │   └── value_time.go
    │   │   └── linux-inspect/
    │   │       ├── LICENSE
    │   │       ├── df/
    │   │       │   ├── df.go
    │   │       │   ├── doc.go
    │   │       │   ├── generated.go
    │   │       │   └── schema.go
    │   │       ├── inspect/
    │   │       │   ├── binary_search.go
    │   │       │   ├── doc.go
    │   │       │   ├── ds.go
    │   │       │   ├── ns.go
    │   │       │   ├── op.go
    │   │       │   ├── proc.go
    │   │       │   ├── proc_csv.go
    │   │       │   ├── proc_csv_interpolate.go
    │   │       │   ├── ps.go
    │   │       │   └── ss.go
    │   │       ├── pkg/
    │   │       │   ├── fileutil/
    │   │       │   │   └── fileutil.go
    │   │       │   └── timeutil/
    │   │       │       └── timeutil.go
    │   │       ├── proc/
    │   │       │   ├── diskstats.go
    │   │       │   ├── doc.go
    │   │       │   ├── generated.go
    │   │       │   ├── io.go
    │   │       │   ├── list.go
    │   │       │   ├── load_avg.go
    │   │       │   ├── net_dev.go
    │   │       │   ├── net_tcp.go
    │   │       │   ├── parse_ip.go
    │   │       │   ├── schema.go
    │   │       │   ├── stat.go
    │   │       │   ├── status.go
    │   │       │   ├── uptime.go
    │   │       │   └── utils.go
    │   │       ├── schema/
    │   │       │   └── schema.go
    │   │       └── top/
    │   │           ├── doc.go
    │   │           ├── generated.go
    │   │           ├── parse.go
    │   │           ├── schema.go
    │   │           ├── stream.go
    │   │           └── top.go
    │   ├── hashicorp/
    │   │   ├── consul/
    │   │   │   ├── LICENSE
    │   │   │   ├── api/
    │   │   │   │   ├── acl.go
    │   │   │   │   ├── agent.go
    │   │   │   │   ├── api.go
    │   │   │   │   ├── catalog.go
    │   │   │   │   ├── coordinate.go
    │   │   │   │   ├── event.go
    │   │   │   │   ├── health.go
    │   │   │   │   ├── kv.go
    │   │   │   │   ├── lock.go
    │   │   │   │   ├── operator.go
    │   │   │   │   ├── operator_area.go
    │   │   │   │   ├── operator_autopilot.go
    │   │   │   │   ├── operator_keyring.go
    │   │   │   │   ├── operator_raft.go
    │   │   │   │   ├── operator_segment.go
    │   │   │   │   ├── prepared_query.go
    │   │   │   │   ├── raw.go
    │   │   │   │   ├── semaphore.go
    │   │   │   │   ├── session.go
    │   │   │   │   ├── snapshot.go
    │   │   │   │   └── status.go
    │   │   │   └── main.go
    │   │   ├── go-cleanhttp/
    │   │   │   ├── LICENSE
    │   │   │   ├── cleanhttp.go
    │   │   │   ├── doc.go
    │   │   │   └── handlers.go
    │   │   ├── go-rootcerts/
    │   │   │   ├── LICENSE
    │   │   │   ├── doc.go
    │   │   │   ├── rootcerts.go
    │   │   │   ├── rootcerts_base.go
    │   │   │   └── rootcerts_darwin.go
    │   │   └── serf/
    │   │       ├── LICENSE
    │   │       └── coordinate/
    │   │           ├── client.go
    │   │           ├── config.go
    │   │           ├── coordinate.go
    │   │           └── phantom.go
    │   ├── inconshreveable/
    │   │   └── mousetrap/
    │   │       ├── LICENSE
    │   │       ├── trap_others.go
    │   │       ├── trap_windows.go
    │   │       └── trap_windows_1.4.go
    │   ├── kr/
    │   │   └── pty/
    │   │       ├── License
    │   │       ├── doc.go
    │   │       ├── ioctl.go
    │   │       ├── ioctl_bsd.go
    │   │       ├── pty_darwin.go
    │   │       ├── pty_dragonfly.go
    │   │       ├── pty_freebsd.go
    │   │       ├── pty_linux.go
    │   │       ├── pty_unsupported.go
    │   │       ├── run.go
    │   │       ├── types.go
    │   │       ├── types_dragonfly.go
    │   │       ├── types_freebsd.go
    │   │       ├── util.go
    │   │       ├── ztypes_386.go
    │   │       ├── ztypes_amd64.go
    │   │       ├── ztypes_arm.go
    │   │       ├── ztypes_arm64.go
    │   │       ├── ztypes_dragonfly_amd64.go
    │   │       ├── ztypes_freebsd_386.go
    │   │       ├── ztypes_freebsd_amd64.go
    │   │       ├── ztypes_freebsd_arm.go
    │   │       ├── ztypes_mipsx.go
    │   │       ├── ztypes_ppc64.go
    │   │       ├── ztypes_ppc64le.go
    │   │       └── ztypes_s390x.go
    │   ├── llgcode/
    │   │   └── draw2d/
    │   │       ├── LICENSE
    │   │       ├── draw2d.go
    │   │       ├── draw2dbase/
    │   │       │   ├── curve.go
    │   │       │   ├── dasher.go
    │   │       │   ├── demux_flattener.go
    │   │       │   ├── flattener.go
    │   │       │   ├── line.go
    │   │       │   ├── stack_gc.go
    │   │       │   ├── stroker.go
    │   │       │   └── text.go
    │   │       ├── draw2dimg/
    │   │       │   ├── fileutil.go
    │   │       │   ├── ftgc.go
    │   │       │   ├── ftpath.go
    │   │       │   └── text.go
    │   │       ├── font.go
    │   │       ├── gc.go
    │   │       ├── matrix.go
    │   │       └── path.go
    │   ├── mattn/
    │   │   └── go-runewidth/
    │   │       ├── LICENSE
    │   │       ├── runewidth.go
    │   │       ├── runewidth_js.go
    │   │       ├── runewidth_posix.go
    │   │       └── runewidth_windows.go
    │   ├── mitchellh/
    │   │   └── go-homedir/
    │   │       ├── LICENSE
    │   │       └── homedir.go
    │   ├── olekukonko/
    │   │   └── tablewriter/
    │   │       ├── LICENCE.md
    │   │       ├── csv.go
    │   │       ├── table.go
    │   │       ├── table_with_color.go
    │   │       ├── util.go
    │   │       └── wrap.go
    │   ├── samuel/
    │   │   └── go-zookeeper/
    │   │       ├── LICENSE
    │   │       └── zk/
    │   │           ├── conn.go
    │   │           ├── constants.go
    │   │           ├── dnshostprovider.go
    │   │           ├── flw.go
    │   │           ├── lock.go
    │   │           ├── server_help.go
    │   │           ├── server_java.go
    │   │           ├── structs.go
    │   │           └── util.go
    │   └── spf13/
    │       ├── cobra/
    │       │   ├── LICENSE.txt
    │       │   ├── args.go
    │       │   ├── bash_completions.go
    │       │   ├── cobra.go
    │       │   ├── command.go
    │       │   ├── command_notwin.go
    │       │   ├── command_win.go
    │       │   └── zsh_completions.go
    │       └── pflag/
    │           ├── LICENSE
    │           ├── bool.go
    │           ├── bool_slice.go
    │           ├── count.go
    │           ├── duration.go
    │           ├── flag.go
    │           ├── float32.go
    │           ├── float64.go
    │           ├── golangflag.go
    │           ├── int.go
    │           ├── int32.go
    │           ├── int64.go
    │           ├── int8.go
    │           ├── int_slice.go
    │           ├── ip.go
    │           ├── ip_slice.go
    │           ├── ipmask.go
    │           ├── ipnet.go
    │           ├── string.go
    │           ├── string_array.go
    │           ├── string_slice.go
    │           ├── uint.go
    │           ├── uint16.go
    │           ├── uint32.go
    │           ├── uint64.go
    │           ├── uint8.go
    │           └── uint_slice.go
    ├── go.uber.org/
    │   ├── atomic/
    │   │   ├── LICENSE.txt
    │   │   ├── atomic.go
    │   │   └── string.go
    │   ├── multierr/
    │   │   ├── LICENSE.txt
    │   │   └── error.go
    │   └── zap/
    │       ├── LICENSE.txt
    │       ├── array.go
    │       ├── buffer/
    │       │   ├── buffer.go
    │       │   └── pool.go
    │       ├── config.go
    │       ├── doc.go
    │       ├── encoder.go
    │       ├── error.go
    │       ├── field.go
    │       ├── flag.go
    │       ├── global.go
    │       ├── http_handler.go
    │       ├── internal/
    │       │   ├── bufferpool/
    │       │   │   └── bufferpool.go
    │       │   ├── color/
    │       │   │   └── color.go
    │       │   └── exit/
    │       │       └── exit.go
    │       ├── level.go
    │       ├── logger.go
    │       ├── options.go
    │       ├── stacktrace.go
    │       ├── sugar.go
    │       ├── time.go
    │       ├── writer.go
    │       └── zapcore/
    │           ├── console_encoder.go
    │           ├── core.go
    │           ├── doc.go
    │           ├── encoder.go
    │           ├── entry.go
    │           ├── error.go
    │           ├── field.go
    │           ├── hook.go
    │           ├── json_encoder.go
    │           ├── level.go
    │           ├── level_strings.go
    │           ├── marshaler.go
    │           ├── memory_encoder.go
    │           ├── sampler.go
    │           ├── tee.go
    │           └── write_syncer.go
    ├── golang.org/
    │   └── x/
    │       ├── image/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── draw/
    │       │   │   ├── draw.go
    │       │   │   ├── gen.go
    │       │   │   ├── go1_8.go
    │       │   │   ├── go1_9.go
    │       │   │   ├── impl.go
    │       │   │   └── scale.go
    │       │   ├── font/
    │       │   │   └── font.go
    │       │   ├── math/
    │       │   │   ├── f64/
    │       │   │   │   └── f64.go
    │       │   │   └── fixed/
    │       │   │       └── fixed.go
    │       │   └── tiff/
    │       │       ├── buffer.go
    │       │       ├── compress.go
    │       │       ├── consts.go
    │       │       ├── lzw/
    │       │       │   └── reader.go
    │       │       ├── reader.go
    │       │       └── writer.go
    │       ├── net/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── context/
    │       │   │   ├── context.go
    │       │   │   ├── ctxhttp/
    │       │   │   │   ├── ctxhttp.go
    │       │   │   │   └── ctxhttp_pre17.go
    │       │   │   ├── go17.go
    │       │   │   ├── go19.go
    │       │   │   ├── pre_go17.go
    │       │   │   └── pre_go19.go
    │       │   ├── http2/
    │       │   │   ├── ciphers.go
    │       │   │   ├── client_conn_pool.go
    │       │   │   ├── configure_transport.go
    │       │   │   ├── databuffer.go
    │       │   │   ├── errors.go
    │       │   │   ├── flow.go
    │       │   │   ├── frame.go
    │       │   │   ├── go16.go
    │       │   │   ├── go17.go
    │       │   │   ├── go17_not18.go
    │       │   │   ├── go18.go
    │       │   │   ├── go19.go
    │       │   │   ├── gotrack.go
    │       │   │   ├── headermap.go
    │       │   │   ├── hpack/
    │       │   │   │   ├── encode.go
    │       │   │   │   ├── hpack.go
    │       │   │   │   ├── huffman.go
    │       │   │   │   └── tables.go
    │       │   │   ├── http2.go
    │       │   │   ├── not_go16.go
    │       │   │   ├── not_go17.go
    │       │   │   ├── not_go18.go
    │       │   │   ├── not_go19.go
    │       │   │   ├── pipe.go
    │       │   │   ├── server.go
    │       │   │   ├── transport.go
    │       │   │   ├── write.go
    │       │   │   ├── writesched.go
    │       │   │   ├── writesched_priority.go
    │       │   │   └── writesched_random.go
    │       │   ├── idna/
    │       │   │   ├── idna.go
    │       │   │   ├── punycode.go
    │       │   │   ├── tables.go
    │       │   │   ├── trie.go
    │       │   │   └── trieval.go
    │       │   ├── internal/
    │       │   │   └── timeseries/
    │       │   │       └── timeseries.go
    │       │   ├── lex/
    │       │   │   └── httplex/
    │       │   │       └── httplex.go
    │       │   └── trace/
    │       │       ├── events.go
    │       │       ├── histogram.go
    │       │       ├── trace.go
    │       │       ├── trace_go16.go
    │       │       └── trace_go17.go
    │       ├── oauth2/
    │       │   ├── LICENSE
    │       │   ├── google/
    │       │   │   ├── appengine.go
    │       │   │   ├── appengine_hook.go
    │       │   │   ├── appengineflex_hook.go
    │       │   │   ├── default.go
    │       │   │   ├── google.go
    │       │   │   ├── jwt.go
    │       │   │   └── sdk.go
    │       │   ├── internal/
    │       │   │   ├── client_appengine.go
    │       │   │   ├── doc.go
    │       │   │   ├── oauth2.go
    │       │   │   ├── token.go
    │       │   │   └── transport.go
    │       │   ├── jws/
    │       │   │   └── jws.go
    │       │   ├── jwt/
    │       │   │   └── jwt.go
    │       │   ├── oauth2.go
    │       │   ├── token.go
    │       │   └── transport.go
    │       ├── sys/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   └── unix/
    │       │       ├── affinity_linux.go
    │       │       ├── asm_darwin_386.s
    │       │       ├── asm_darwin_amd64.s
    │       │       ├── asm_darwin_arm.s
    │       │       ├── asm_darwin_arm64.s
    │       │       ├── asm_dragonfly_amd64.s
    │       │       ├── asm_freebsd_386.s
    │       │       ├── asm_freebsd_amd64.s
    │       │       ├── asm_freebsd_arm.s
    │       │       ├── asm_linux_386.s
    │       │       ├── asm_linux_amd64.s
    │       │       ├── asm_linux_arm.s
    │       │       ├── asm_linux_arm64.s
    │       │       ├── asm_linux_mips64x.s
    │       │       ├── asm_linux_mipsx.s
    │       │       ├── asm_linux_ppc64x.s
    │       │       ├── asm_linux_s390x.s
    │       │       ├── asm_netbsd_386.s
    │       │       ├── asm_netbsd_amd64.s
    │       │       ├── asm_netbsd_arm.s
    │       │       ├── asm_openbsd_386.s
    │       │       ├── asm_openbsd_amd64.s
    │       │       ├── asm_openbsd_arm.s
    │       │       ├── asm_solaris_amd64.s
    │       │       ├── bluetooth_linux.go
    │       │       ├── cap_freebsd.go
    │       │       ├── constants.go
    │       │       ├── dev_darwin.go
    │       │       ├── dev_dragonfly.go
    │       │       ├── dev_freebsd.go
    │       │       ├── dev_linux.go
    │       │       ├── dev_netbsd.go
    │       │       ├── dev_openbsd.go
    │       │       ├── dirent.go
    │       │       ├── endian_big.go
    │       │       ├── endian_little.go
    │       │       ├── env_unix.go
    │       │       ├── errors_freebsd_386.go
    │       │       ├── errors_freebsd_amd64.go
    │       │       ├── errors_freebsd_arm.go
    │       │       ├── flock.go
    │       │       ├── flock_linux_32bit.go
    │       │       ├── gccgo.go
    │       │       ├── gccgo_c.c
    │       │       ├── gccgo_linux_amd64.go
    │       │       ├── mkpost.go
    │       │       ├── openbsd_pledge.go
    │       │       ├── pagesize_unix.go
    │       │       ├── race.go
    │       │       ├── race0.go
    │       │       ├── sockcmsg_linux.go
    │       │       ├── sockcmsg_unix.go
    │       │       ├── str.go
    │       │       ├── syscall.go
    │       │       ├── syscall_bsd.go
    │       │       ├── syscall_darwin.go
    │       │       ├── syscall_darwin_386.go
    │       │       ├── syscall_darwin_amd64.go
    │       │       ├── syscall_darwin_arm.go
    │       │       ├── syscall_darwin_arm64.go
    │       │       ├── syscall_dragonfly.go
    │       │       ├── syscall_dragonfly_amd64.go
    │       │       ├── syscall_freebsd.go
    │       │       ├── syscall_freebsd_386.go
    │       │       ├── syscall_freebsd_amd64.go
    │       │       ├── syscall_freebsd_arm.go
    │       │       ├── syscall_linux.go
    │       │       ├── syscall_linux_386.go
    │       │       ├── syscall_linux_amd64.go
    │       │       ├── syscall_linux_amd64_gc.go
    │       │       ├── syscall_linux_arm.go
    │       │       ├── syscall_linux_arm64.go
    │       │       ├── syscall_linux_mips64x.go
    │       │       ├── syscall_linux_mipsx.go
    │       │       ├── syscall_linux_ppc64x.go
    │       │       ├── syscall_linux_s390x.go
    │       │       ├── syscall_linux_sparc64.go
    │       │       ├── syscall_netbsd.go
    │       │       ├── syscall_netbsd_386.go
    │       │       ├── syscall_netbsd_amd64.go
    │       │       ├── syscall_netbsd_arm.go
    │       │       ├── syscall_openbsd.go
    │       │       ├── syscall_openbsd_386.go
    │       │       ├── syscall_openbsd_amd64.go
    │       │       ├── syscall_openbsd_arm.go
    │       │       ├── syscall_solaris.go
    │       │       ├── syscall_solaris_amd64.go
    │       │       ├── syscall_unix.go
    │       │       ├── syscall_unix_gc.go
    │       │       ├── timestruct.go
    │       │       ├── types_darwin.go
    │       │       ├── types_dragonfly.go
    │       │       ├── types_freebsd.go
    │       │       ├── types_netbsd.go
    │       │       ├── types_openbsd.go
    │       │       ├── types_solaris.go
    │       │       ├── zerrors_darwin_386.go
    │       │       ├── zerrors_darwin_amd64.go
    │       │       ├── zerrors_darwin_arm.go
    │       │       ├── zerrors_darwin_arm64.go
    │       │       ├── zerrors_dragonfly_amd64.go
    │       │       ├── zerrors_freebsd_386.go
    │       │       ├── zerrors_freebsd_amd64.go
    │       │       ├── zerrors_freebsd_arm.go
    │       │       ├── zerrors_linux_386.go
    │       │       ├── zerrors_linux_amd64.go
    │       │       ├── zerrors_linux_arm.go
    │       │       ├── zerrors_linux_arm64.go
    │       │       ├── zerrors_linux_mips.go
    │       │       ├── zerrors_linux_mips64.go
    │       │       ├── zerrors_linux_mips64le.go
    │       │       ├── zerrors_linux_mipsle.go
    │       │       ├── zerrors_linux_ppc64.go
    │       │       ├── zerrors_linux_ppc64le.go
    │       │       ├── zerrors_linux_s390x.go
    │       │       ├── zerrors_linux_sparc64.go
    │       │       ├── zerrors_netbsd_386.go
    │       │       ├── zerrors_netbsd_amd64.go
    │       │       ├── zerrors_netbsd_arm.go
    │       │       ├── zerrors_openbsd_386.go
    │       │       ├── zerrors_openbsd_amd64.go
    │       │       ├── zerrors_openbsd_arm.go
    │       │       ├── zerrors_solaris_amd64.go
    │       │       ├── zptrace386_linux.go
    │       │       ├── zptracearm_linux.go
    │       │       ├── zptracemips_linux.go
    │       │       ├── zptracemipsle_linux.go
    │       │       ├── zsyscall_darwin_386.go
    │       │       ├── zsyscall_darwin_amd64.go
    │       │       ├── zsyscall_darwin_arm.go
    │       │       ├── zsyscall_darwin_arm64.go
    │       │       ├── zsyscall_dragonfly_amd64.go
    │       │       ├── zsyscall_freebsd_386.go
    │       │       ├── zsyscall_freebsd_amd64.go
    │       │       ├── zsyscall_freebsd_arm.go
    │       │       ├── zsyscall_linux_386.go
    │       │       ├── zsyscall_linux_amd64.go
    │       │       ├── zsyscall_linux_arm.go
    │       │       ├── zsyscall_linux_arm64.go
    │       │       ├── zsyscall_linux_mips.go
    │       │       ├── zsyscall_linux_mips64.go
    │       │       ├── zsyscall_linux_mips64le.go
    │       │       ├── zsyscall_linux_mipsle.go
    │       │       ├── zsyscall_linux_ppc64.go
    │       │       ├── zsyscall_linux_ppc64le.go
    │       │       ├── zsyscall_linux_s390x.go
    │       │       ├── zsyscall_linux_sparc64.go
    │       │       ├── zsyscall_netbsd_386.go
    │       │       ├── zsyscall_netbsd_amd64.go
    │       │       ├── zsyscall_netbsd_arm.go
    │       │       ├── zsyscall_openbsd_386.go
    │       │       ├── zsyscall_openbsd_amd64.go
    │       │       ├── zsyscall_openbsd_arm.go
    │       │       ├── zsyscall_solaris_amd64.go
    │       │       ├── zsysctl_openbsd_386.go
    │       │       ├── zsysctl_openbsd_amd64.go
    │       │       ├── zsysctl_openbsd_arm.go
    │       │       ├── zsysnum_darwin_386.go
    │       │       ├── zsysnum_darwin_amd64.go
    │       │       ├── zsysnum_darwin_arm.go
    │       │       ├── zsysnum_darwin_arm64.go
    │       │       ├── zsysnum_dragonfly_amd64.go
    │       │       ├── zsysnum_freebsd_386.go
    │       │       ├── zsysnum_freebsd_amd64.go
    │       │       ├── zsysnum_freebsd_arm.go
    │       │       ├── zsysnum_linux_386.go
    │       │       ├── zsysnum_linux_amd64.go
    │       │       ├── zsysnum_linux_arm.go
    │       │       ├── zsysnum_linux_arm64.go
    │       │       ├── zsysnum_linux_mips.go
    │       │       ├── zsysnum_linux_mips64.go
    │       │       ├── zsysnum_linux_mips64le.go
    │       │       ├── zsysnum_linux_mipsle.go
    │       │       ├── zsysnum_linux_ppc64.go
    │       │       ├── zsysnum_linux_ppc64le.go
    │       │       ├── zsysnum_linux_s390x.go
    │       │       ├── zsysnum_linux_sparc64.go
    │       │       ├── zsysnum_netbsd_386.go
    │       │       ├── zsysnum_netbsd_amd64.go
    │       │       ├── zsysnum_netbsd_arm.go
    │       │       ├── zsysnum_openbsd_386.go
    │       │       ├── zsysnum_openbsd_amd64.go
    │       │       ├── zsysnum_openbsd_arm.go
    │       │       ├── ztypes_darwin_386.go
    │       │       ├── ztypes_darwin_amd64.go
    │       │       ├── ztypes_darwin_arm.go
    │       │       ├── ztypes_darwin_arm64.go
    │       │       ├── ztypes_dragonfly_amd64.go
    │       │       ├── ztypes_freebsd_386.go
    │       │       ├── ztypes_freebsd_amd64.go
    │       │       ├── ztypes_freebsd_arm.go
    │       │       ├── ztypes_linux_386.go
    │       │       ├── ztypes_linux_amd64.go
    │       │       ├── ztypes_linux_arm.go
    │       │       ├── ztypes_linux_arm64.go
    │       │       ├── ztypes_linux_mips.go
    │       │       ├── ztypes_linux_mips64.go
    │       │       ├── ztypes_linux_mips64le.go
    │       │       ├── ztypes_linux_mipsle.go
    │       │       ├── ztypes_linux_ppc64.go
    │       │       ├── ztypes_linux_ppc64le.go
    │       │       ├── ztypes_linux_s390x.go
    │       │       ├── ztypes_linux_sparc64.go
    │       │       ├── ztypes_netbsd_386.go
    │       │       ├── ztypes_netbsd_amd64.go
    │       │       ├── ztypes_netbsd_arm.go
    │       │       ├── ztypes_openbsd_386.go
    │       │       ├── ztypes_openbsd_amd64.go
    │       │       ├── ztypes_openbsd_arm.go
    │       │       └── ztypes_solaris_amd64.go
    │       ├── text/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── collate/
    │       │   │   ├── build/
    │       │   │   │   ├── builder.go
    │       │   │   │   ├── colelem.go
    │       │   │   │   ├── contract.go
    │       │   │   │   ├── order.go
    │       │   │   │   ├── table.go
    │       │   │   │   └── trie.go
    │       │   │   ├── collate.go
    │       │   │   ├── index.go
    │       │   │   ├── maketables.go
    │       │   │   ├── option.go
    │       │   │   ├── sort.go
    │       │   │   └── tables.go
    │       │   ├── doc.go
    │       │   ├── gen.go
    │       │   ├── internal/
    │       │   │   ├── colltab/
    │       │   │   │   ├── collelem.go
    │       │   │   │   ├── colltab.go
    │       │   │   │   ├── contract.go
    │       │   │   │   ├── iter.go
    │       │   │   │   ├── numeric.go
    │       │   │   │   ├── table.go
    │       │   │   │   ├── trie.go
    │       │   │   │   └── weighter.go
    │       │   │   ├── gen/
    │       │   │   │   ├── code.go
    │       │   │   │   └── gen.go
    │       │   │   ├── gen.go
    │       │   │   ├── internal.go
    │       │   │   ├── match.go
    │       │   │   ├── tables.go
    │       │   │   ├── tag/
    │       │   │   │   └── tag.go
    │       │   │   ├── triegen/
    │       │   │   │   ├── compact.go
    │       │   │   │   ├── print.go
    │       │   │   │   └── triegen.go
    │       │   │   └── ucd/
    │       │   │       └── ucd.go
    │       │   ├── language/
    │       │   │   ├── common.go
    │       │   │   ├── coverage.go
    │       │   │   ├── doc.go
    │       │   │   ├── gen.go
    │       │   │   ├── gen_common.go
    │       │   │   ├── gen_index.go
    │       │   │   ├── go1_1.go
    │       │   │   ├── go1_2.go
    │       │   │   ├── index.go
    │       │   │   ├── language.go
    │       │   │   ├── lookup.go
    │       │   │   ├── match.go
    │       │   │   ├── parse.go
    │       │   │   ├── tables.go
    │       │   │   └── tags.go
    │       │   ├── secure/
    │       │   │   ├── bidirule/
    │       │   │   │   ├── bidirule.go
    │       │   │   │   ├── bidirule10.0.0.go
    │       │   │   │   └── bidirule9.0.0.go
    │       │   │   └── doc.go
    │       │   ├── transform/
    │       │   │   └── transform.go
    │       │   └── unicode/
    │       │       ├── bidi/
    │       │       │   ├── bidi.go
    │       │       │   ├── bracket.go
    │       │       │   ├── core.go
    │       │       │   ├── gen.go
    │       │       │   ├── gen_ranges.go
    │       │       │   ├── gen_trieval.go
    │       │       │   ├── prop.go
    │       │       │   ├── tables10.0.0.go
    │       │       │   ├── tables9.0.0.go
    │       │       │   └── trieval.go
    │       │       ├── cldr/
    │       │       │   ├── base.go
    │       │       │   ├── cldr.go
    │       │       │   ├── collate.go
    │       │       │   ├── decode.go
    │       │       │   ├── makexml.go
    │       │       │   ├── resolve.go
    │       │       │   ├── slice.go
    │       │       │   └── xml.go
    │       │       ├── doc.go
    │       │       ├── norm/
    │       │       │   ├── composition.go
    │       │       │   ├── forminfo.go
    │       │       │   ├── input.go
    │       │       │   ├── iter.go
    │       │       │   ├── maketables.go
    │       │       │   ├── normalize.go
    │       │       │   ├── readwriter.go
    │       │       │   ├── tables10.0.0.go
    │       │       │   ├── tables9.0.0.go
    │       │       │   ├── transform.go
    │       │       │   ├── trie.go
    │       │       │   └── triegen.go
    │       │       └── rangetable/
    │       │           ├── gen.go
    │       │           ├── merge.go
    │       │           ├── rangetable.go
    │       │           ├── tables10.0.0.go
    │       │           └── tables9.0.0.go
    │       └── time/
    │           ├── LICENSE
    │           ├── PATENTS
    │           └── rate/
    │               ├── rate.go
    │               ├── rate_go16.go
    │               └── rate_go17.go
    ├── gonum.org/
    │   └── v1/
    │       ├── gonum/
    │       │   ├── LICENSE
    │       │   ├── blas/
    │       │   │   ├── blas.go
    │       │   │   ├── blas64/
    │       │   │   │   ├── blas64.go
    │       │   │   │   ├── conv.go
    │       │   │   │   ├── conv_symmetric.go
    │       │   │   │   └── doc.go
    │       │   │   ├── doc.go
    │       │   │   └── gonum/
    │       │   │       ├── cmplx.go
    │       │   │       ├── dgemm.go
    │       │   │       ├── doc.go
    │       │   │       ├── general_double.go
    │       │   │       ├── general_single.go
    │       │   │       ├── gonum.go
    │       │   │       ├── level1cmplx128.go
    │       │   │       ├── level1double.go
    │       │   │       ├── level1double_ddot.go
    │       │   │       ├── level1single.go
    │       │   │       ├── level1single_dsdot.go
    │       │   │       ├── level1single_sdot.go
    │       │   │       ├── level1single_sdsdot.go
    │       │   │       ├── level2cmplx128.go
    │       │   │       ├── level2double.go
    │       │   │       ├── level2single.go
    │       │   │       ├── level3double.go
    │       │   │       ├── level3single.go
    │       │   │       └── sgemm.go
    │       │   ├── floats/
    │       │   │   ├── doc.go
    │       │   │   └── floats.go
    │       │   ├── internal/
    │       │   │   ├── asm/
    │       │   │   │   ├── c128/
    │       │   │   │   │   ├── axpyinc_amd64.s
    │       │   │   │   │   ├── axpyincto_amd64.s
    │       │   │   │   │   ├── axpyunitary_amd64.s
    │       │   │   │   │   ├── axpyunitaryto_amd64.s
    │       │   │   │   │   ├── doc.go
    │       │   │   │   │   ├── dotcinc_amd64.s
    │       │   │   │   │   ├── dotcunitary_amd64.s
    │       │   │   │   │   ├── dotuinc_amd64.s
    │       │   │   │   │   ├── dotuunitary_amd64.s
    │       │   │   │   │   ├── dscalinc_amd64.s
    │       │   │   │   │   ├── dscalunitary_amd64.s
    │       │   │   │   │   ├── scal.go
    │       │   │   │   │   ├── scalUnitary_amd64.s
    │       │   │   │   │   ├── scalinc_amd64.s
    │       │   │   │   │   ├── stubs_amd64.go
    │       │   │   │   │   └── stubs_noasm.go
    │       │   │   │   ├── f32/
    │       │   │   │   │   ├── axpyinc_amd64.s
    │       │   │   │   │   ├── axpyincto_amd64.s
    │       │   │   │   │   ├── axpyunitary_amd64.s
    │       │   │   │   │   ├── axpyunitaryto_amd64.s
    │       │   │   │   │   ├── ddotinc_amd64.s
    │       │   │   │   │   ├── ddotunitary_amd64.s
    │       │   │   │   │   ├── doc.go
    │       │   │   │   │   ├── dotinc_amd64.s
    │       │   │   │   │   ├── dotunitary_amd64.s
    │       │   │   │   │   ├── scal.go
    │       │   │   │   │   ├── stubs_amd64.go
    │       │   │   │   │   └── stubs_noasm.go
    │       │   │   │   └── f64/
    │       │   │   │       ├── abssum_amd64.s
    │       │   │   │       ├── abssuminc_amd64.s
    │       │   │   │       ├── add_amd64.s
    │       │   │   │       ├── addconst_amd64.s
    │       │   │   │       ├── axpy.go
    │       │   │   │       ├── axpyinc_amd64.s
    │       │   │   │       ├── axpyincto_amd64.s
    │       │   │   │       ├── axpyunitary_amd64.s
    │       │   │   │       ├── axpyunitaryto_amd64.s
    │       │   │   │       ├── cumprod_amd64.s
    │       │   │   │       ├── cumsum_amd64.s
    │       │   │   │       ├── div_amd64.s
    │       │   │   │       ├── divto_amd64.s
    │       │   │   │       ├── doc.go
    │       │   │   │       ├── dot.go
    │       │   │   │       ├── dot_amd64.s
    │       │   │   │       ├── l1norm_amd64.s
    │       │   │   │       ├── linfnorm_amd64.s
    │       │   │   │       ├── scal.go
    │       │   │   │       ├── scalinc_amd64.s
    │       │   │   │       ├── scalincto_amd64.s
    │       │   │   │       ├── scalunitary_amd64.s
    │       │   │   │       ├── scalunitaryto_amd64.s
    │       │   │   │       ├── stubs_amd64.go
    │       │   │   │       └── stubs_noasm.go
    │       │   │   └── math32/
    │       │   │       ├── doc.go
    │       │   │       ├── math.go
    │       │   │       ├── signbit.go
    │       │   │       ├── sqrt.go
    │       │   │       ├── sqrt_amd64.go
    │       │   │       └── sqrt_amd64.s
    │       │   ├── lapack/
    │       │   │   ├── gonum/
    │       │   │   │   ├── dbdsqr.go
    │       │   │   │   ├── dgebak.go
    │       │   │   │   ├── dgebal.go
    │       │   │   │   ├── dgebd2.go
    │       │   │   │   ├── dgebrd.go
    │       │   │   │   ├── dgecon.go
    │       │   │   │   ├── dgeev.go
    │       │   │   │   ├── dgehd2.go
    │       │   │   │   ├── dgehrd.go
    │       │   │   │   ├── dgelq2.go
    │       │   │   │   ├── dgelqf.go
    │       │   │   │   ├── dgels.go
    │       │   │   │   ├── dgeql2.go
    │       │   │   │   ├── dgeqp3.go
    │       │   │   │   ├── dgeqr2.go
    │       │   │   │   ├── dgeqrf.go
    │       │   │   │   ├── dgerq2.go
    │       │   │   │   ├── dgerqf.go
    │       │   │   │   ├── dgesvd.go
    │       │   │   │   ├── dgetf2.go
    │       │   │   │   ├── dgetrf.go
    │       │   │   │   ├── dgetri.go
    │       │   │   │   ├── dgetrs.go
    │       │   │   │   ├── dggsvd3.go
    │       │   │   │   ├── dggsvp3.go
    │       │   │   │   ├── dhseqr.go
    │       │   │   │   ├── dlabrd.go
    │       │   │   │   ├── dlacn2.go
    │       │   │   │   ├── dlacpy.go
    │       │   │   │   ├── dlae2.go
    │       │   │   │   ├── dlaev2.go
    │       │   │   │   ├── dlaexc.go
    │       │   │   │   ├── dlags2.go
    │       │   │   │   ├── dlahqr.go
    │       │   │   │   ├── dlahr2.go
    │       │   │   │   ├── dlaln2.go
    │       │   │   │   ├── dlange.go
    │       │   │   │   ├── dlanst.go
    │       │   │   │   ├── dlansy.go
    │       │   │   │   ├── dlantr.go
    │       │   │   │   ├── dlanv2.go
    │       │   │   │   ├── dlapll.go
    │       │   │   │   ├── dlapmt.go
    │       │   │   │   ├── dlapy2.go
    │       │   │   │   ├── dlaqp2.go
    │       │   │   │   ├── dlaqps.go
    │       │   │   │   ├── dlaqr04.go
    │       │   │   │   ├── dlaqr1.go
    │       │   │   │   ├── dlaqr23.go
    │       │   │   │   ├── dlaqr5.go
    │       │   │   │   ├── dlarf.go
    │       │   │   │   ├── dlarfb.go
    │       │   │   │   ├── dlarfg.go
    │       │   │   │   ├── dlarft.go
    │       │   │   │   ├── dlarfx.go
    │       │   │   │   ├── dlartg.go
    │       │   │   │   ├── dlas2.go
    │       │   │   │   ├── dlascl.go
    │       │   │   │   ├── dlaset.go
    │       │   │   │   ├── dlasq1.go
    │       │   │   │   ├── dlasq2.go
    │       │   │   │   ├── dlasq3.go
    │       │   │   │   ├── dlasq4.go
    │       │   │   │   ├── dlasq5.go
    │       │   │   │   ├── dlasq6.go
    │       │   │   │   ├── dlasr.go
    │       │   │   │   ├── dlasrt.go
    │       │   │   │   ├── dlassq.go
    │       │   │   │   ├── dlasv2.go
    │       │   │   │   ├── dlaswp.go
    │       │   │   │   ├── dlasy2.go
    │       │   │   │   ├── dlatrd.go
    │       │   │   │   ├── dlatrs.go
    │       │   │   │   ├── doc.go
    │       │   │   │   ├── dorg2l.go
    │       │   │   │   ├── dorg2r.go
    │       │   │   │   ├── dorgbr.go
    │       │   │   │   ├── dorghr.go
    │       │   │   │   ├── dorgl2.go
    │       │   │   │   ├── dorglq.go
    │       │   │   │   ├── dorgql.go
    │       │   │   │   ├── dorgqr.go
    │       │   │   │   ├── dorgtr.go
    │       │   │   │   ├── dorm2r.go
    │       │   │   │   ├── dormbr.go
    │       │   │   │   ├── dormhr.go
    │       │   │   │   ├── dorml2.go
    │       │   │   │   ├── dormlq.go
    │       │   │   │   ├── dormqr.go
    │       │   │   │   ├── dormr2.go
    │       │   │   │   ├── dpbtf2.go
    │       │   │   │   ├── dpocon.go
    │       │   │   │   ├── dpotf2.go
    │       │   │   │   ├── dpotrf.go
    │       │   │   │   ├── drscl.go
    │       │   │   │   ├── dsteqr.go
    │       │   │   │   ├── dsterf.go
    │       │   │   │   ├── dsyev.go
    │       │   │   │   ├── dsytd2.go
    │       │   │   │   ├── dsytrd.go
    │       │   │   │   ├── dtgsja.go
    │       │   │   │   ├── dtrcon.go
    │       │   │   │   ├── dtrevc3.go
    │       │   │   │   ├── dtrexc.go
    │       │   │   │   ├── dtrti2.go
    │       │   │   │   ├── dtrtri.go
    │       │   │   │   ├── dtrtrs.go
    │       │   │   │   ├── general.go
    │       │   │   │   ├── iladlc.go
    │       │   │   │   ├── iladlr.go
    │       │   │   │   ├── ilaenv.go
    │       │   │   │   └── iparmq.go
    │       │   │   ├── lapack.go
    │       │   │   └── lapack64/
    │       │   │       ├── doc.go
    │       │   │       └── lapack64.go
    │       │   └── mat/
    │       │       ├── band.go
    │       │       ├── cholesky.go
    │       │       ├── cmatrix.go
    │       │       ├── consts.go
    │       │       ├── dense.go
    │       │       ├── dense_arithmetic.go
    │       │       ├── doc.go
    │       │       ├── eigen.go
    │       │       ├── errors.go
    │       │       ├── format.go
    │       │       ├── gsvd.go
    │       │       ├── hogsvd.go
    │       │       ├── index_bound_checks.go
    │       │       ├── index_no_bound_checks.go
    │       │       ├── inner.go
    │       │       ├── io.go
    │       │       ├── lq.go
    │       │       ├── lu.go
    │       │       ├── matrix.go
    │       │       ├── offset.go
    │       │       ├── offset_appengine.go
    │       │       ├── pool.go
    │       │       ├── product.go
    │       │       ├── qr.go
    │       │       ├── shadow.go
    │       │       ├── solve.go
    │       │       ├── svd.go
    │       │       ├── symband.go
    │       │       ├── symmetric.go
    │       │       ├── triangular.go
    │       │       └── vector.go
    │       └── plot/
    │           ├── LICENSE
    │           ├── align.go
    │           ├── axis.go
    │           ├── doc.go
    │           ├── labelling.go
    │           ├── legend.go
    │           ├── palette/
    │           │   ├── hsva.go
    │           │   ├── palette.go
    │           │   └── reverse.go
    │           ├── plot.go
    │           ├── plotter/
    │           │   ├── barchart.go
    │           │   ├── boxplot.go
    │           │   ├── colorbar.go
    │           │   ├── conrec.go
    │           │   ├── contour.go
    │           │   ├── errbars.go
    │           │   ├── functions.go
    │           │   ├── glyphbox.go
    │           │   ├── grid.go
    │           │   ├── heat.go
    │           │   ├── histogram.go
    │           │   ├── image.go
    │           │   ├── johnson.go
    │           │   ├── labels.go
    │           │   ├── line.go
    │           │   ├── palettethumbnailer.go
    │           │   ├── plotter.go
    │           │   ├── polygon.go
    │           │   ├── quartile.go
    │           │   ├── sankey.go
    │           │   ├── scatter.go
    │           │   └── volcano_example.go
    │           ├── plotutil/
    │           │   ├── add.go
    │           │   ├── errorpoints.go
    │           │   ├── main.go
    │           │   └── plotutil.go
    │           ├── tools/
    │           │   └── bezier/
    │           │       └── bezier.go
    │           └── vg/
    │               ├── draw/
    │               │   └── canvas.go
    │               ├── font.go
    │               ├── font_syscall.go
    │               ├── fonts/
    │               │   ├── fonts.go
    │               │   ├── liberation_fonts_generated.go
    │               │   └── mk-fonts.go
    │               ├── geom.go
    │               ├── len.go
    │               ├── vg.go
    │               ├── vgeps/
    │               │   └── vgeps.go
    │               ├── vgimg/
    │               │   └── vgimg.go
    │               ├── vgpdf/
    │               │   └── vgpdf.go
    │               └── vgsvg/
    │                   └── vgsvg.go
    ├── google.golang.org/
    │   ├── api/
    │   │   ├── LICENSE
    │   │   ├── gensupport/
    │   │   │   ├── backoff.go
    │   │   │   ├── buffer.go
    │   │   │   ├── doc.go
    │   │   │   ├── header.go
    │   │   │   ├── json.go
    │   │   │   ├── jsonfloat.go
    │   │   │   ├── media.go
    │   │   │   ├── params.go
    │   │   │   ├── resumable.go
    │   │   │   ├── retry.go
    │   │   │   └── send.go
    │   │   ├── googleapi/
    │   │   │   ├── googleapi.go
    │   │   │   ├── internal/
    │   │   │   │   └── uritemplates/
    │   │   │   │       ├── LICENSE
    │   │   │   │       ├── uritemplates.go
    │   │   │   │       └── utils.go
    │   │   │   ├── transport/
    │   │   │   │   └── apikey.go
    │   │   │   └── types.go
    │   │   ├── internal/
    │   │   │   ├── creds.go
    │   │   │   ├── pool.go
    │   │   │   └── settings.go
    │   │   ├── iterator/
    │   │   │   └── iterator.go
    │   │   ├── option/
    │   │   │   └── option.go
    │   │   ├── storage/
    │   │   │   └── v1/
    │   │   │       └── storage-gen.go
    │   │   └── transport/
    │   │       ├── dial.go
    │   │       └── http/
    │   │           ├── dial.go
    │   │           └── dial_appengine.go
    │   ├── appengine/
    │   │   ├── LICENSE
    │   │   ├── appengine.go
    │   │   ├── appengine_vm.go
    │   │   ├── errors.go
    │   │   ├── identity.go
    │   │   ├── internal/
    │   │   │   ├── api.go
    │   │   │   ├── api_classic.go
    │   │   │   ├── api_common.go
    │   │   │   ├── app_id.go
    │   │   │   ├── app_identity/
    │   │   │   │   └── app_identity_service.pb.go
    │   │   │   ├── base/
    │   │   │   │   └── api_base.pb.go
    │   │   │   ├── datastore/
    │   │   │   │   └── datastore_v3.pb.go
    │   │   │   ├── identity.go
    │   │   │   ├── identity_classic.go
    │   │   │   ├── identity_vm.go
    │   │   │   ├── internal.go
    │   │   │   ├── log/
    │   │   │   │   └── log_service.pb.go
    │   │   │   ├── main.go
    │   │   │   ├── main_vm.go
    │   │   │   ├── metadata.go
    │   │   │   ├── modules/
    │   │   │   │   └── modules_service.pb.go
    │   │   │   ├── net.go
    │   │   │   ├── remote_api/
    │   │   │   │   └── remote_api.pb.go
    │   │   │   ├── transaction.go
    │   │   │   └── urlfetch/
    │   │   │       └── urlfetch_service.pb.go
    │   │   ├── namespace.go
    │   │   ├── timeout.go
    │   │   └── urlfetch/
    │   │       └── urlfetch.go
    │   ├── genproto/
    │   │   ├── LICENSE
    │   │   ├── googleapis/
    │   │   │   ├── api/
    │   │   │   │   ├── annotations/
    │   │   │   │   │   ├── annotations.pb.go
    │   │   │   │   │   └── http.pb.go
    │   │   │   │   ├── authorization_config.pb.go
    │   │   │   │   └── experimental.pb.go
    │   │   │   ├── iam/
    │   │   │   │   └── v1/
    │   │   │   │       ├── iam_policy.pb.go
    │   │   │   │       └── policy.pb.go
    │   │   │   └── rpc/
    │   │   │       └── status/
    │   │   │           └── status.pb.go
    │   │   └── regen.go
    │   └── grpc/
    │       ├── LICENSE
    │       ├── backoff.go
    │       ├── balancer/
    │       │   └── balancer.go
    │       ├── balancer.go
    │       ├── balancer_conn_wrappers.go
    │       ├── balancer_v1_wrapper.go
    │       ├── call.go
    │       ├── clientconn.go
    │       ├── codec.go
    │       ├── codes/
    │       │   ├── code_string.go
    │       │   └── codes.go
    │       ├── connectivity/
    │       │   └── connectivity.go
    │       ├── credentials/
    │       │   ├── credentials.go
    │       │   ├── credentials_util_go17.go
    │       │   ├── credentials_util_go18.go
    │       │   └── credentials_util_pre_go17.go
    │       ├── doc.go
    │       ├── grpclb/
    │       │   └── grpc_lb_v1/
    │       │       ├── doc.go
    │       │       └── messages/
    │       │           └── messages.pb.go
    │       ├── grpclb.go
    │       ├── grpclog/
    │       │   ├── grpclog.go
    │       │   ├── logger.go
    │       │   └── loggerv2.go
    │       ├── health/
    │       │   ├── grpc_health_v1/
    │       │   │   └── health.pb.go
    │       │   └── health.go
    │       ├── interceptor.go
    │       ├── internal/
    │       │   └── internal.go
    │       ├── keepalive/
    │       │   └── keepalive.go
    │       ├── metadata/
    │       │   └── metadata.go
    │       ├── naming/
    │       │   ├── dns_resolver.go
    │       │   ├── go17.go
    │       │   ├── go18.go
    │       │   └── naming.go
    │       ├── peer/
    │       │   └── peer.go
    │       ├── picker_wrapper.go
    │       ├── pickfirst.go
    │       ├── proxy.go
    │       ├── resolver/
    │       │   └── resolver.go
    │       ├── resolver_conn_wrapper.go
    │       ├── rpc_util.go
    │       ├── server.go
    │       ├── stats/
    │       │   ├── handlers.go
    │       │   └── stats.go
    │       ├── status/
    │       │   └── status.go
    │       ├── stream.go
    │       ├── tap/
    │       │   └── tap.go
    │       ├── trace.go
    │       └── transport/
    │           ├── bdp_estimator.go
    │           ├── control.go
    │           ├── handler_server.go
    │           ├── http2_client.go
    │           ├── http2_server.go
    │           ├── http_util.go
    │           ├── log.go
    │           └── transport.go
    └── gopkg.in/
        └── yaml.v2/
            ├── LICENSE
            ├── LICENSE.libyaml
            ├── apic.go
            ├── decode.go
            ├── emitterc.go
            ├── encode.go
            ├── parserc.go
            ├── readerc.go
            ├── resolve.go
            ├── scannerc.go
            ├── sorter.go
            ├── writerc.go
            ├── yaml.go
            ├── yamlh.go
            └── yamlprivateh.go

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

================================================
FILE: .gitignore
================================================
# See http://help.github.com/ignore-files/ for more about ignoring files.

# IDEs and editors
/.idea
*.iml
/.vscode

#System Files
.DS_Store

# Ignore everything in vendor/, except for *.go files,
# LICENSE and COPYING. Ignore Go tests.
# https://github.com/golang/dep/issues/120#issuecomment-306518546
vendor/**/*
!vendor/**/
!vendor/**/*.go
!vendor/**/*.c
!vendor/**/*.cpp
!vendor/**/*.s
!vendor/**/COPYING*
!vendor/**/PATENTS*
!vendor/**/NOTICE*
!vendor/**/LICENSE*
vendor/**/*_test.go


================================================
FILE: .travis.yml
================================================
language: go

sudo: false

go:
- 1.10.3

script:
- ./scripts/tests.sh


================================================
FILE: CONTRIBUTING.md
================================================
# How to Contribute

CoreOS projects are [Apache 2.0 licensed](LICENSE) and accept contributions via
GitHub pull requests.  This document outlines some of the conventions on
development workflow, commit message formatting, contact points and other
resources to make it easier to get your contribution accepted.

# Certificate of Origin

By contributing to this project you agree to the Developer Certificate of
Origin (DCO). This document was created by the Linux Kernel community and is a
simple statement that you, as a contributor, have the legal right to make the
contribution. See the [DCO](DCO) file for details.

# Email and Chat

The project currently uses the general etcd email list and Slack channel:
- Email: [etcd-dev](https://groups.google.com/g/etcd-dev)
- Slack: [#etcd](https://kubernetes.slack.com/messages/C3HD8ARJ5/details/) channel on Kubernetes ([get an invite](http://slack.kubernetes.io/))

Please avoid emailing maintainers found in the MAINTAINERS file directly. They
are very busy and read the mailing lists.

## Getting Started

- Fork the repository on GitHub
- Read the [README](README.md) for build and test instructions
- Play with the project, submit bugs, submit patches!

## Contribution Flow

This is a rough outline of what a contributor's workflow looks like:

- Create a topic branch from where you want to base your work (usually master).
- Make commits of logical units.
- Make sure your commit messages are in the proper format (see below).
- Push your changes to a topic branch in your fork of the repository.
- Make sure the tests pass, and add any new tests as appropriate.
- Submit a pull request to the original repository.

Thanks for your contributions!

### Coding Style

CoreOS projects written in Go follow a set of style guidelines that we've documented 
[here](https://github.com/coreos/docs/tree/master/golang). Please follow them when 
working on your contributions.

### Format of the Commit Message

We follow a rough convention for commit messages that is designed to answer two
questions: what changed and why. The subject line should feature the what and
the body of the commit should describe the why.

```
scripts: add the test-cluster command

this uses tmux to setup a test cluster that you can easily kill and
start for debugging.

Fixes #38
```

The format can be described more formally as follows:

```
<subsystem>: <what changed>
<BLANK LINE>
<why this change was made>
<BLANK LINE>
<footer>
```

The first line is the subject and should be no longer than 70 characters, the
second line is always blank, and other lines should be wrapped at 80 characters.
This allows the message to be easier to read on GitHub as well as in various
git tools.


================================================
FILE: DCO
================================================
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.


================================================
FILE: Gopkg.toml
================================================
################################
# Direct dependencies


# master
[[constraint]]
  name = "github.com/coreos/etcd"
  source = "https://github.com/coreos/etcd"
  revision = "b241e383fde587fb5b5f5f9188589f4a7e467ccc"

# v1.7.5
[[constraint]]
  name = "google.golang.org/grpc"
  source = "https://github.com/grpc/grpc-go"
  revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e"


[[constraint]]
  name = "go.uber.org/zap"
  version = "v1.8.0"

[[constraint]]
  name = "github.com/gogo/protobuf"
  source = "https://github.com/gogo/protobuf"
  revision = "160de10b2537169b5ae3e7e221d28269ef40d311"

[[constraint]]
  name = "github.com/golang/protobuf"
  source = "https://github.com/golang/protobuf"
  revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"


[[constraint]]
  name = "golang.org/x/net"
  source = "https://github.com/golang/net"
  revision = "434ec0c7fe3742c984919a691b2018a6e9694425"

[[constraint]]
  name = "golang.org/x/time"
  source = "https://github.com/golang/time"
  revision = "6dc17368e09b0e8634d71cac8168d853e869a0c7"


[[constraint]]
  name = "gopkg.in/yaml.v2"
  source = "https://github.com/go-yaml/yaml"
  revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4"

[[constraint]]
  name = "github.com/dustin/go-humanize"
  source = "https://github.com/dustin/go-humanize"
  revision = "02af3965c54e8cacf948b97fef38925c4120652c"

[[constraint]]
  name = "github.com/spf13/cobra"
  source = "https://github.com/spf13/cobra"
  revision = "b95ab734e27d33e0d8fbabf71ca990568d4e2020"

[[constraint]]
  name = "github.com/olekukonko/tablewriter"
  source = "https://github.com/olekukonko/tablewriter"
  revision = "d4647c9c7a84d847478d890b816b7d8b62b0b279"

[[constraint]]
  name = "github.com/cheggaaa/pb"
  source = "https://github.com/cheggaaa/pb"
  revision = "18d384da9bdc1e5a08fc2a62a494c321d9ae74ea"



[[constraint]]
  name = "github.com/samuel/go-zookeeper"
  source = "https://github.com/samuel/go-zookeeper"
  revision = "471cd4e61d7a78ece1791fa5faa0345dc8c7d5a5"


[[constraint]]
  name = "github.com/hashicorp/consul"
  source = "https://github.com/hashicorp/consul"
  revision = "b55059fc3d0327c92c41431e57dfd2df3f956b03"


[[constraint]]
  name = "github.com/gyuho/dataframe"
  source = "https://github.com/gyuho/dataframe"
  revision = "008fc241adc41d4bd5c54b9f6564ef16407c030e"

[[constraint]]
  name = "github.com/gyuho/linux-inspect"
  source = "https://github.com/gyuho/linux-inspect"
  revision = "997067d2074a699295cf069e19e745e14db9bcf3"


[[constraint]]
  name = "gonum.org/v1/plot"
  source = "https://github.com/gonum/plot"
  revision = "8e90bd1840aacc281e54298e39ac0ae2be794419"


[[constraint]]
  name = "github.com/coreos/pkg"
  source = "https://github.com/coreos/pkg"
  revision = "97fdf19511ea361ae1c100dd393cc47f8dcfa1e1"


[[constraint]]
  name = "golang.org/x/oauth2"
  source = "https://github.com/golang/oauth2"
  revision = "30785a2c434e431ef7c507b54617d6a951d5f2b4"

[[constraint]]
  name = "google.golang.org/api"
  source = "https://github.com/google/google-api-go-client"
  revision = "e5c227fa33ebccc5a430d863efae400431fc0e85"

[[constraint]]
  name = "google.golang.org/appengine"
  source = "https://github.com/golang/appengine"
  revision = "5bee14b453b4c71be47ec1781b0fa61c2ea182db"

[[constraint]]
  name = "cloud.google.com/go"
  source = "https://github.com/GoogleCloudPlatform/google-cloud-go"
  revision = "2a6493c7a9214bf56c1003bd97443d505cc7e952"


################################


################################
# Transitive dependencies, and overrides


# v1.3.1-coreos.6
[[override]]
  name = "github.com/coreos/bbolt"
  source = "https://github.com/coreos/bbolt"
  revision = "48ea1b39c25fc1bab3506fbc712ecbaa842c4d2d"

# v1.3.0
[[override]]
  name = "github.com/grpc-ecosystem/grpc-gateway"
  source = "https://github.com/grpc-ecosystem/grpc-gateway"
  revision = "92583770e3f01b09a0d3e9bdf64321d8bebd48f2"


################################


================================================
FILE: LICENSE
================================================
Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.



================================================
FILE: NOTICE
================================================
CoreOS Project
Copyright 2015 CoreOS, Inc

This product includes software developed at CoreOS, Inc.
(http://www.coreos.com/).


================================================
FILE: README.md
================================================
# dbtester

[![Build Status](https://img.shields.io/travis/etcd-io/dbtester.svg?style=flat-square)](https://travis-ci.com/etcd-io/dbtester) [![Godoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/github.com/etcd-io/dbtester)

Distributed database benchmark tester: etcd, Zookeeper, Consul, zetcd, cetcd

It includes github.com/golang/freetype, which is based in part on the work of the FreeType Team.

<br><br><hr>
##### Performance Analysis

- Latest test results can be found at https://github.com/etcd-io/dbtester/tree/master/test-results
- Exploring Performance of etcd, Zookeeper and Consul Consistent Key-value Datastores (February 17, 2017)
  - https://coreos.com/blog/performance-of-etcd.html


<br><br><hr>
##### Project

![dbtester system architecture](./dbtester.png)

- Database Agent
  - https://github.com/etcd-io/dbtester/tree/master/agent
- Database Client
  - https://github.com/etcd-io/dbtester/tree/master/control
- System Metrics
  - https://github.com/gyuho/linux-inspect
- Test Data Analysis
  - https://github.com/etcd-io/dbtester/tree/master/analyze
  - https://github.com/gyuho/dataframe
  - https://github.com/gonum/plot

For etcd, we recommend [etcd benchmark tool](https://github.com/coreos/etcd/tree/master/tools/benchmark).

All logs and results can be found at https://github.com/etcd-io/dbtester/tree/master/test-results or https://console.cloud.google.com/storage/browser/dbtester-results/?authuser=0&project=etcd-development.


<br><br><hr>
##### Noticeable Warnings: Zookeeper

Snapshot, when writing 1-million entries (256-byte key, 1KB value value), with 500 concurrent clients

```
# snapshot warnings
cd 2017Q1-00-etcd-zookeeper-consul/02-write-1M-keys-best-throughput
grep -r -i fsync-ing\ the zookeeper-r3.4.9-java8-* | less

2017-02-10 18:55:38,997 [myid:3] - WARN  [SyncThread:3:SyncRequestProcessor@148] - Too busy to snap, skipping
2017-02-10 18:55:38,998 [myid:3] - INFO  [SyncThread:3:FileTxnLog@203] - Creating new log file: log.1000c0c51
2017-02-10 18:55:40,855 [myid:3] - INFO  [SyncThread:3:FileTxnLog@203] - Creating new log file: log.1000cd2e6
2017-02-10 18:55:40,855 [myid:3] - INFO  [Snapshot Thread:FileTxnSnapLog@240] - Snapshotting: 0x1000cd1ca to /home/gyuho/zookeeper/zookeeper.data/version-2/snapshot.1000cd1ca
2017-02-10 18:55:46,382 [myid:3] - WARN  [SyncThread:3:FileTxnLog@338] - fsync-ing the write ahead log in SyncThread:3 took 1062ms which will adversely effect operation latency. See the ZooKeeper troubleshooting guide
2017-02-10 18:55:47,471 [myid:3] - WARN  [SyncThread:3:FileTxnLog@338] - fsync-ing the write ahead log in SyncThread:3 took 1084ms which will adversely effect operation latency. See the ZooKeeper troubleshooting guide
2017-02-10 18:55:49,425 [myid:3] - WARN  [SyncThread:3:FileTxnLog@338] - fsync-ing the write ahead log in SyncThread:3 took 1142ms which will adversely effect operation latency. See the ZooKeeper troubleshooting guide
2017-02-10 18:55:51,188 [myid:3] - WARN  [SyncThread:3:FileTxnLog@338] - fsync-ing the write ahead log in SyncThread:3 took 1201ms which will adversely effect operation latency. See the ZooKeeper troubleshooting guide
2017-02-10 18:55:52,292 [myid:3] - WARN  [SyncThread:3:FileTxnLog@338] - fsync-ing the write ahead log in SyncThread:3 took 1102ms which will adversely effect operation latency. See the ZooKeeper troubleshooting guide
```

When writing more than 2-million entries (256-byte key, 1KB value value) with 500 concurrent clients

```
# leader election
cd 2017Q1-00-etcd-zookeeper-consul/04-write-too-many-keys
grep -r -i election\ took  zookeeper-r3.4.9-java8-* | less

# leader election is taking more than 10 seconds...
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:22:16,549 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Follower@61] - FOLLOWING - LEADER ELECTION TOOK - 22978
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:23:02,279 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 10210
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:23:14,498 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 203
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:23:36,303 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 9791
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:23:52,151 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 3836
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:24:13,849 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 9686
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:24:29,694 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 3573
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:24:51,392 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 8686
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:25:07,231 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 3827
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:25:28,940 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 9697
zookeeper-r3.4.9-java8-2-database.log:2017-02-10 19:25:44,772 [myid:2] - INFO  [QuorumPeer[myid=2]/0:0:0:0:0:0:0:0:2181:Leader@361] - LEADING - LEADER ELECTION TOOK - 3820
```


<br><br><hr>
##### Noticeable Warnings: Consul

Snapshot, when writing 1-million entries (256-byte key, 1KB value value), with 500 concurrent clients

```
# snapshot warnings
cd 2017Q1-00-etcd-zookeeper-consul/02-write-1M-keys-best-throughput
grep -r -i installed\ remote consul-v0.7.4-go1.7.5-* | less

    2017/02/10 18:58:43 [INFO] snapshot: Creating new snapshot at /home/gyuho/consul.data/raft/snapshots/2-900345-1486753123478.tmp
    2017/02/10 18:58:45 [INFO] snapshot: reaping snapshot /home/gyuho/consul.data/raft/snapshots/2-849399-1486753096972
    2017/02/10 18:58:46 [INFO] raft: Copied 1223270573 bytes to local snapshot
    2017/02/10 18:58:55 [INFO] raft: Compacting logs from 868354 to 868801
    2017/02/10 18:58:56 [INFO] raft: Installed remote snapshot
    2017/02/10 18:58:57 [INFO] snapshot: Creating new snapshot at /home/gyuho/consul.data/raft/snapshots/2-911546-1486753137827.tmp
    2017/02/10 18:58:59 [INFO] consul.fsm: snapshot created in 32.255µs
    2017/02/10 18:59:01 [INFO] snapshot: reaping snapshot /home/gyuho/consul.data/raft/snapshots/2-873921-1486753116619
    2017/02/10 18:59:02 [INFO] raft: Copied 1238491373 bytes to local snapshot
    2017/02/10 18:59:11 [INFO] raft: Compacting logs from 868802 to 868801
    2017/02/10 18:59:11 [INFO] raft: Installed remote snapshot
```

Logs do not tell much but average latency spikes (e.g. from 70.27517 ms to 10407.900082 ms)



<img src="https://storage.googleapis.com/dbtester-results/2017Q2-02-etcd-zookeeper-consul/2017Q2-01-write-1M-cpu-client-scaling.png" alt="2017Q2-01-write-1M-cpu-client-scaling">

<img src="https://storage.googleapis.com/dbtester-results/2017Q2-02-etcd-zookeeper-consul/2017Q2-02-write-1M-network-traffic-best-throughput.png" alt="2017Q2-02-write-1M-network-traffic-best-throughput">

<img src="https://storage.googleapis.com/dbtester-results/2017Q2-02-etcd-zookeeper-consul/2017Q2-01-write-1M-throughput-client-scaling.png" alt="2017Q2-01-write-1M-throughput-client-scaling">

<img src="https://storage.googleapis.com/dbtester-results/2017Q2-02-etcd-zookeeper-consul/2017Q2-02-write-1M-latency-best-throughput.png" alt="2017Q2-02-write-1M-latency-best-throughput">


<br><br><hr>
##### Write 1M keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns, Zookeeper 700, Consul 500 clients)

- Google Cloud Compute Engine
- 4 machines of 16 vCPUs + 60 GB Memory + 300 GB SSD (1 for client)
- Ubuntu 17.10 (GNU/Linux kernel 4.13.0-25-generic)
- `ulimit -n` is 120000
- etcd v3.3.0 (Go 1.9.2)
- Zookeeper r3.5.3-beta
  - Java 8
  - javac 1.8.0_151
  - Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
  - Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
  - `/usr/bin/java -Djute.maxbuffer=33554432 -Xms50G -Xmx50G`
- Consul v1.0.2 (Go 1.9.2)


```
+---------------------------------------+---------------------+-----------------------------+-----------------------+
|                                       | etcd-v3.3.0-go1.9.2 | zookeeper-r3.5.3-beta-java8 | consul-v1.0.2-go1.9.2 |
+---------------------------------------+---------------------+-----------------------------+-----------------------+
|                         TOTAL-SECONDS |         28.3623 sec |                 59.2167 sec |          178.9443 sec |
|                  TOTAL-REQUEST-NUMBER |           1,000,000 |                   1,000,000 |             1,000,000 |
|                        MAX-THROUGHPUT |      37,330 req/sec |              25,124 req/sec |        15,865 req/sec |
|                        AVG-THROUGHPUT |      35,258 req/sec |              16,842 req/sec |         5,588 req/sec |
|                        MIN-THROUGHPUT |      13,505 req/sec |                  20 req/sec |             0 req/sec |
|                       FASTEST-LATENCY |           4.6073 ms |                   2.9094 ms |            11.6604 ms |
|                           AVG-LATENCY |          28.2625 ms |                  30.9499 ms |            89.4351 ms |
|                       SLOWEST-LATENCY |         117.4918 ms |                4564.6788 ms |          4616.2947 ms |
|                           Latency p10 |        13.508626 ms |                 9.068163 ms |          30.408863 ms |
|                           Latency p25 |        16.869586 ms |                 9.351597 ms |          34.224021 ms |
|                           Latency p50 |        22.167478 ms |                10.093377 ms |          39.881181 ms |
|                           Latency p75 |        34.855941 ms |                14.951189 ms |          52.644787 ms |
|                           Latency p90 |        54.613394 ms |                28.497256 ms |         118.340402 ms |
|                           Latency p95 |        59.785127 ms |                72.671788 ms |         229.129526 ms |
|                           Latency p99 |        74.139638 ms |               273.218523 ms |        1495.660763 ms |
|                         Latency p99.9 |        97.385495 ms |              2526.873285 ms |        3499.225138 ms |
|      SERVER-TOTAL-NETWORK-RX-DATA-SUM |              5.1 GB |                      4.6 GB |                5.6 GB |
|      SERVER-TOTAL-NETWORK-TX-DATA-SUM |              3.8 GB |                      3.6 GB |                4.4 GB |
|           CLIENT-TOTAL-NETWORK-RX-SUM |              252 MB |                      357 MB |                206 MB |
|           CLIENT-TOTAL-NETWORK-TX-SUM |              1.5 GB |                      1.4 GB |                1.5 GB |
|                  SERVER-MAX-CPU-USAGE |            446.83 % |                   1122.00 % |              426.33 % |
|               SERVER-MAX-MEMORY-USAGE |              1.1 GB |                       15 GB |                4.6 GB |
|                  CLIENT-MAX-CPU-USAGE |            606.00 % |                    314.00 % |              215.00 % |
|               CLIENT-MAX-MEMORY-USAGE |               96 MB |                      2.4 GB |                 86 MB |
|                    CLIENT-ERROR-COUNT |                   0 |                       2,652 |                     0 |
|  SERVER-AVG-READS-COMPLETED-DELTA-SUM |                   0 |                         237 |                     2 |
|    SERVER-AVG-SECTORS-READS-DELTA-SUM |                   0 |                           0 |                     0 |
| SERVER-AVG-WRITES-COMPLETED-DELTA-SUM |             108,067 |                     157,034 |               675,072 |
|  SERVER-AVG-SECTORS-WRITTEN-DELTA-SUM |          20,449,360 |                  16,480,488 |           106,836,768 |
|           SERVER-AVG-DISK-SPACE-USAGE |              2.6 GB |                      6.9 GB |                2.9 GB |
+---------------------------------------+---------------------+-----------------------------+-----------------------+


zookeeper__r3_5_3_beta errors:
"zk: connection closed" (count 2,264)
"zk: could not connect to a server" (count 388)
```


<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-LATENCY-MS.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-LATENCY-MS">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-LATENCY-MS-BY-KEY.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-LATENCY-MS-BY-KEY">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-LATENCY-MS-BY-KEY-ERROR-POINTS.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-LATENCY-MS-BY-KEY-ERROR-POINTS">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-THROUGHPUT.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-THROUGHPUT">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-VOLUNTARY-CTXT-SWITCHES.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-VOLUNTARY-CTXT-SWITCHES">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-NON-VOLUNTARY-CTXT-SWITCHES.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-NON-VOLUNTARY-CTXT-SWITCHES">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-CPU.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-CPU">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/MAX-CPU.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/MAX-CPU">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-VMRSS-MB.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-VMRSS-MB">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-VMRSS-MB-BY-KEY.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-VMRSS-MB-BY-KEY">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-VMRSS-MB-BY-KEY-ERROR-POINTS.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-VMRSS-MB-BY-KEY-ERROR-POINTS">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-READS-COMPLETED-DELTA.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-READS-COMPLETED-DELTA">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-SECTORS-READ-DELTA.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-SECTORS-READ-DELTA">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-WRITES-COMPLETED-DELTA.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-WRITES-COMPLETED-DELTA">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-SECTORS-WRITTEN-DELTA.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-SECTORS-WRITTEN-DELTA">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-READ-BYTES-NUM-DELTA.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-READ-BYTES-NUM-DELTA">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-WRITE-BYTES-NUM-DELTA.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-WRITE-BYTES-NUM-DELTA">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-RECEIVE-BYTES-NUM-DELTA.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-RECEIVE-BYTES-NUM-DELTA">



<img src="https://storage.googleapis.com/dbtester-results/2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-TRANSMIT-BYTES-NUM-DELTA.svg" alt="2018Q1-02-etcd-zookeeper-consul/write-1M-keys-best-throughput/AVG-TRANSMIT-BYTES-NUM-DELTA">





================================================
FILE: agent/agent_cetcd.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"fmt"
	"os/exec"
	"strings"

	"github.com/etcd-io/dbtester/dbtesterpb"

	"go.uber.org/zap"
)

// startCetcd starts cetcd. This assumes that etcd is already started.
func startCetcd(fs *flags, t *transporterServer) error {
	if !exist(fs.cetcdExec) {
		return fmt.Errorf("cetcd binary %q does not exist", globalFlags.cetcdExec)
	}

	peerIPs := strings.Split(t.req.PeerIPsString, "___")
	clientURLs := make([]string, len(peerIPs))
	for i, u := range peerIPs {
		clientURLs[i] = fmt.Sprintf("http://%s:2379", u)
	}

	var flags []string
	switch t.req.DatabaseID {
	case dbtesterpb.DatabaseID_cetcd__beta:
		flags = []string{
			// "-consuladdr", "0.0.0.0:8500",
			"-consuladdr", fmt.Sprintf("%s:8500", peerIPs[t.req.IPIndex]),
			"-etcd", clientURLs[t.req.IPIndex], // etcd endpoint
		}

	default:
		return fmt.Errorf("database ID %q is not supported", t.req.DatabaseID)
	}

	flagString := strings.Join(flags, " ")

	cmd := exec.Command(fs.cetcdExec, flags...)
	cmd.Stdout = t.proxyDatabaseLogfile
	cmd.Stderr = t.proxyDatabaseLogfile
	cs := fmt.Sprintf("%s %s", cmd.Path, flagString)

	t.lg.Info("starting database", zap.String("command", cs))
	if err := cmd.Start(); err != nil {
		return err
	}
	t.proxyCmd = cmd
	t.proxyCmdWait = make(chan struct{})
	t.proxyPid = int64(cmd.Process.Pid)
	t.lg.Info("started database", zap.String("command", cs), zap.Int64("pid", t.pid))

	return nil
}


================================================
FILE: agent/agent_consul.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"fmt"
	"os"
	"os/exec"
	"strings"

	"github.com/etcd-io/dbtester/dbtesterpb"

	"go.uber.org/zap"
)

// startConsul starts Consul.
func startConsul(fs *flags, t *transporterServer) error {
	if !exist(fs.consulExec) {
		return fmt.Errorf("Consul binary %q does not exist", globalFlags.consulExec)
	}

	if err := os.RemoveAll(fs.consulDataDir); err != nil {
		return err
	}

	peerIPs := strings.Split(t.req.PeerIPsString, "___")

	var flags []string
	switch t.req.DatabaseID {
	case dbtesterpb.DatabaseID_consul__v1_0_2:
		switch t.req.IPIndex {
		case 0: // leader
			flags = []string{
				"agent",
				"-server",
				"-data-dir", fs.consulDataDir,
				"-bind", peerIPs[t.req.IPIndex],
				"-client", peerIPs[t.req.IPIndex],
				"-bootstrap-expect", fmt.Sprintf("%d", len(peerIPs)),
			}
		default:
			flags = []string{
				"agent",
				"-server",
				"-data-dir", fs.consulDataDir,
				"-bind", peerIPs[t.req.IPIndex],
				"-client", peerIPs[t.req.IPIndex],
				"-join", peerIPs[0],
			}
		}

	default:
		return fmt.Errorf("database ID %q is not supported", t.req.DatabaseID)
	}

	flagString := strings.Join(flags, " ")

	cmd := exec.Command(fs.consulExec, flags...)
	cmd.Stdout = t.databaseLogFile
	cmd.Stderr = t.databaseLogFile
	cs := fmt.Sprintf("%s %s", cmd.Path, flagString)

	t.lg.Info("starting database", zap.String("command", cs))
	if err := cmd.Start(); err != nil {
		return err
	}
	t.cmd = cmd
	t.cmdWait = make(chan struct{})
	t.pid = int64(cmd.Process.Pid)
	t.lg.Info("started database", zap.String("command", cs), zap.Int64("pid", t.pid))

	return nil
}


================================================
FILE: agent/agent_etcd.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"fmt"
	"os"
	"os/exec"
	"strings"

	"github.com/etcd-io/dbtester/dbtesterpb"

	"go.uber.org/zap"
)

// startEtcd starts etcd v3.
func startEtcd(fs *flags, t *transporterServer) error {
	if !exist(fs.etcdExec) {
		return fmt.Errorf("etcd binary %q does not exist", globalFlags.etcdExec)
	}

	if err := os.RemoveAll(fs.etcdDataDir); err != nil {
		return err
	}

	peerIPs := strings.Split(t.req.PeerIPsString, "___")

	names := make([]string, len(peerIPs))
	clientURLs := make([]string, len(peerIPs))
	peerURLs := make([]string, len(peerIPs))
	members := make([]string, len(peerIPs))
	for i, u := range peerIPs {
		names[i] = fmt.Sprintf("etcd-%d", i+1)
		clientURLs[i] = fmt.Sprintf("http://%s:2379", u)
		peerURLs[i] = fmt.Sprintf("http://%s:2380", u)
		members[i] = fmt.Sprintf("%s=%s", names[i], peerURLs[i])
	}

	var flags []string
	switch t.req.DatabaseID {
	case dbtesterpb.DatabaseID_etcd__other:
		flags = []string{
			"--name", names[t.req.IPIndex],
			"--data-dir", fs.etcdDataDir,
			"--quota-backend-bytes", fmt.Sprintf("%d", t.req.Flag_Etcd_Other.QuotaSizeBytes),

			"--snapshot-count", fmt.Sprintf("%d", t.req.Flag_Etcd_Other.SnapshotCount),

			"--listen-client-urls", clientURLs[t.req.IPIndex],
			"--advertise-client-urls", clientURLs[t.req.IPIndex],

			"--listen-peer-urls", peerURLs[t.req.IPIndex],
			"--initial-advertise-peer-urls", peerURLs[t.req.IPIndex],

			"--initial-cluster-token", "mytoken",
			"--initial-cluster", strings.Join(members, ","),
			"--initial-cluster-state", "new",
			"--logger", "zap",
			"--log-outputs", "stderr",
		}

	case dbtesterpb.DatabaseID_etcd__tip:
		flags = []string{
			"--name", names[t.req.IPIndex],
			"--data-dir", fs.etcdDataDir,
			"--quota-backend-bytes", fmt.Sprintf("%d", t.req.Flag_Etcd_Tip.QuotaSizeBytes),

			"--snapshot-count", fmt.Sprintf("%d", t.req.Flag_Etcd_Tip.SnapshotCount),

			"--listen-client-urls", clientURLs[t.req.IPIndex],
			"--advertise-client-urls", clientURLs[t.req.IPIndex],

			"--listen-peer-urls", peerURLs[t.req.IPIndex],
			"--initial-advertise-peer-urls", peerURLs[t.req.IPIndex],

			"--initial-cluster-token", "mytoken",
			"--initial-cluster", strings.Join(members, ","),
			"--initial-cluster-state", "new",
			"--logger", "zap",
			"--log-outputs", "stderr",
		}

	case dbtesterpb.DatabaseID_etcd__v3_2:
		flags = []string{
			"--name", names[t.req.IPIndex],
			"--data-dir", fs.etcdDataDir,
			"--quota-backend-bytes", fmt.Sprintf("%d", t.req.Flag_Etcd_V3_2.QuotaSizeBytes),

			"--snapshot-count", fmt.Sprintf("%d", t.req.Flag_Etcd_V3_2.SnapshotCount),

			"--listen-client-urls", clientURLs[t.req.IPIndex],
			"--advertise-client-urls", clientURLs[t.req.IPIndex],

			"--listen-peer-urls", peerURLs[t.req.IPIndex],
			"--initial-advertise-peer-urls", peerURLs[t.req.IPIndex],

			"--initial-cluster-token", "mytoken",
			"--initial-cluster", strings.Join(members, ","),
			"--initial-cluster-state", "new",
		}

	case dbtesterpb.DatabaseID_etcd__v3_3:
		flags = []string{
			"--name", names[t.req.IPIndex],
			"--data-dir", fs.etcdDataDir,
			"--quota-backend-bytes", fmt.Sprintf("%d", t.req.Flag_Etcd_V3_3.QuotaSizeBytes),

			"--snapshot-count", fmt.Sprintf("%d", t.req.Flag_Etcd_V3_3.SnapshotCount),

			"--listen-client-urls", clientURLs[t.req.IPIndex],
			"--advertise-client-urls", clientURLs[t.req.IPIndex],

			"--listen-peer-urls", peerURLs[t.req.IPIndex],
			"--initial-advertise-peer-urls", peerURLs[t.req.IPIndex],

			"--initial-cluster-token", "mytoken",
			"--initial-cluster", strings.Join(members, ","),
			"--initial-cluster-state", "new",
		}

	default:
		return fmt.Errorf("database ID %q is not supported", t.req.DatabaseID)
	}

	flagString := strings.Join(flags, " ")

	cmd := exec.Command(fs.etcdExec, flags...)
	cmd.Stdout = t.databaseLogFile
	cmd.Stderr = t.databaseLogFile
	cs := fmt.Sprintf("%s %s", cmd.Path, flagString)

	t.lg.Info("starting database", zap.String("command", cs))
	if err := cmd.Start(); err != nil {
		return err
	}
	t.cmd = cmd
	t.cmdWait = make(chan struct{})
	t.pid = int64(cmd.Process.Pid)
	t.lg.Info("started database", zap.String("command", cs), zap.Int64("pid", t.pid))

	return nil
}


================================================
FILE: agent/agent_zetcd.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"fmt"
	"os/exec"
	"strings"

	"github.com/etcd-io/dbtester/dbtesterpb"

	"go.uber.org/zap"
)

// startZetcd starts zetcd. This assumes that etcd is already started.
func startZetcd(fs *flags, t *transporterServer) error {
	if !exist(fs.zetcdExec) {
		return fmt.Errorf("zetcd binary %q does not exist", globalFlags.zetcdExec)
	}

	peerIPs := strings.Split(t.req.PeerIPsString, "___")
	clientURLs := make([]string, len(peerIPs))
	for i, u := range peerIPs {
		clientURLs[i] = fmt.Sprintf("http://%s:2379", u)
	}

	var flags []string
	switch t.req.DatabaseID {
	case dbtesterpb.DatabaseID_zetcd__beta:
		flags = []string{
			// "-zkaddr", "0.0.0.0:2181",
			"-zkaddr", fmt.Sprintf("%s:2181", peerIPs[t.req.IPIndex]),
			"-endpoint", clientURLs[t.req.IPIndex],
		}

	default:
		return fmt.Errorf("database ID %q is not supported", t.req.DatabaseID)
	}

	flagString := strings.Join(flags, " ")

	cmd := exec.Command(fs.zetcdExec, flags...)
	cmd.Stdout = t.proxyDatabaseLogfile
	cmd.Stderr = t.proxyDatabaseLogfile
	cs := fmt.Sprintf("%s %s", cmd.Path, flagString)

	t.lg.Info("starting database", zap.String("command", cs))
	if err := cmd.Start(); err != nil {
		return err
	}
	t.proxyCmd = cmd
	t.proxyCmdWait = make(chan struct{})
	t.proxyPid = int64(cmd.Process.Pid)
	t.lg.Info("started database", zap.String("command", cs), zap.Int64("pid", t.proxyPid))

	return nil
}


================================================
FILE: agent/agent_zookeeper.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"bytes"
	"fmt"
	"html/template"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/etcd-io/dbtester/dbtesterpb"

	"go.uber.org/zap"
)

var (
	zkTemplate = `tickTime={{.TickTime}}
dataDir={{.DataDir}}
clientPort={{.ClientPort}}
initLimit={{.InitLimit}}
syncLimit={{.SyncLimit}}
maxClientCnxns={{.MaxClientConnections}}
snapCount={{.SnapCount}}
{{range .Peers}}server.{{.MyID}}={{.IP}}:2888:3888
{{end}}
`
)

// ZookeeperConfig is zookeeper configuration.
// http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html
type ZookeeperConfig struct {
	TickTime             int64
	DataDir              string
	ClientPort           int64
	InitLimit            int64
	SyncLimit            int64
	MaxClientConnections int64
	SnapCount            int64
	Peers                []ZookeeperPeer
}

// ZookeeperPeer defines Zookeeper peer configuration.
type ZookeeperPeer struct {
	MyID int
	IP   string
}

var shell = os.Getenv("SHELL")

func init() {
	if len(shell) == 0 {
		shell = "sh"
	}
}

// Java class paths for Zookeeper.
// '-cp' is for 'class search path of directories and zip/jar files'.
// See https://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html for more.
// UPDATE FOR EACH ZOOKEEPER RELEASES!
// Search correct paths with 'find ./zookeeper/lib | sort'.
const (
	// JavaClassPathZookeeperr353beta is the Java class paths of Zookeeper r3.5.3-beta.
	// http://zookeeper.apache.org/doc/r3.5.3-beta/zookeeperAdmin.html#sc_zkMulitServerSetup
	JavaClassPathZookeeperr353beta = `-cp zookeeper-3.5.3-beta.jar:lib/slf4j-api-1.7.5.jar:lib/slf4j-log4j12-1.7.5.jar:lib/log4j-1.2.17.jar:conf org.apache.zookeeper.server.quorum.QuorumPeerMain`
)

// startZookeeper starts Zookeeper.
func startZookeeper(fs *flags, t *transporterServer) error {
	if !exist(fs.javaExec) {
		return fmt.Errorf("Java binary %q does not exist", globalFlags.javaExec)
	}
	if err := os.RemoveAll(fs.zkDataDir); err != nil {
		return err
	}
	if err := os.MkdirAll(fs.zkDataDir, 0777); err != nil {
		return err
	}

	// Zookeeper requires correct relative-path for runtime
	// needs manual 'cd' into the Zookeeper working directory!
	if err := os.Chdir(fs.zkWorkDir); err != nil {
		return err
	}

	ipath := filepath.Join(fs.zkDataDir, "myid")
	switch t.req.DatabaseID {
	case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
		if t.req.Flag_Zookeeper_R3_5_3Beta == nil {
			return fmt.Errorf("request 'Flag_Zookeeper_R3_5_3Beta' is nil")
		}
		t.lg.Info(
			"writing Zookeeper myid file",
			zap.Int("myid", int(t.req.Flag_Zookeeper_R3_5_3Beta.MyID)),
			zap.String("path", ipath),
		)
		if err := toFile(fmt.Sprintf("%d", t.req.Flag_Zookeeper_R3_5_3Beta.MyID), ipath); err != nil {
			return err
		}

	default:
		return fmt.Errorf("database ID %q is not supported", t.req.DatabaseID)
	}

	var cfg ZookeeperConfig
	peerIPs := strings.Split(t.req.PeerIPsString, "___")
	peers := []ZookeeperPeer{}
	for i := range peerIPs {
		peers = append(peers, ZookeeperPeer{MyID: i + 1, IP: peerIPs[i]})
	}
	switch t.req.DatabaseID {
	case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
		cfg = ZookeeperConfig{
			TickTime:             t.req.Flag_Zookeeper_R3_5_3Beta.TickTime,
			DataDir:              fs.zkDataDir,
			ClientPort:           t.req.Flag_Zookeeper_R3_5_3Beta.ClientPort,
			InitLimit:            t.req.Flag_Zookeeper_R3_5_3Beta.InitLimit,
			SyncLimit:            t.req.Flag_Zookeeper_R3_5_3Beta.SyncLimit,
			MaxClientConnections: t.req.Flag_Zookeeper_R3_5_3Beta.MaxClientConnections,
			Peers:                peers,
			SnapCount:            t.req.Flag_Zookeeper_R3_5_3Beta.SnapCount,
		}
	default:
		return fmt.Errorf("database ID %q is not supported", t.req.DatabaseID)
	}
	tpl := template.Must(template.New("zkTemplate").Parse(zkTemplate))
	buf := new(bytes.Buffer)
	if err := tpl.Execute(buf, cfg); err != nil {
		return err
	}
	zctxt := buf.String()
	t.lg.Info("writing Zookeeper config file", zap.String("path", fs.zkConfig))
	if err := toFile(zctxt, fs.zkConfig); err != nil {
		return err
	}

	var flagString string
	switch t.req.DatabaseID {
	case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
		if t.req.Flag_Zookeeper_R3_5_3Beta.JavaDJuteMaxBuffer != 0 {
			if len(flagString) > 0 {
				flagString += " "
			}
			flagString += fmt.Sprintf("-Djute.maxbuffer=%d", t.req.Flag_Zookeeper_R3_5_3Beta.JavaDJuteMaxBuffer)
		}
		if t.req.Flag_Zookeeper_R3_5_3Beta.JavaDJuteMaxBuffer != 0 {
			if len(flagString) > 0 {
				flagString += " "
			}
			flagString += fmt.Sprintf("-Xms%s", t.req.Flag_Zookeeper_R3_5_3Beta.JavaXms)
		}
		if t.req.Flag_Zookeeper_R3_5_3Beta.JavaDJuteMaxBuffer != 0 {
			if len(flagString) > 0 {
				flagString += " "
			}
			flagString += fmt.Sprintf("-Xmx%s", t.req.Flag_Zookeeper_R3_5_3Beta.JavaXmx)
		}
		// -Djute.maxbuffer=33554432 -Xms50G -Xmx50G
		if len(flagString) > 0 {
			flagString += " "
		}
		flagString += JavaClassPathZookeeperr353beta

	default:
		return fmt.Errorf("database ID %q is not supported", t.req.DatabaseID)
	}

	args := []string{shell, "-c", fs.javaExec + " " + flagString + " " + fs.zkConfig}
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Stdout = t.databaseLogFile
	cmd.Stderr = t.databaseLogFile
	cs := fmt.Sprintf("%s %s", cmd.Path, strings.Join(args[1:], " "))

	t.lg.Info("starting database", zap.String("command", cs))
	if err := cmd.Start(); err != nil {
		return err
	}
	t.cmd = cmd
	t.cmdWait = make(chan struct{})
	t.pid = int64(cmd.Process.Pid)
	t.lg.Info("started database", zap.String("command", cs), zap.Int64("pid", t.pid))

	return nil
}


================================================
FILE: agent/command.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"fmt"
	"net"
	"os"
	"path/filepath"

	"github.com/etcd-io/dbtester/dbtesterpb"
	"github.com/etcd-io/dbtester/pkg/ntp"
	"go.uber.org/zap"

	"github.com/coreos/etcd/pkg/netutil"
	"github.com/gyuho/linux-inspect/df"
	"github.com/spf13/cobra"
	"google.golang.org/grpc"
)

type flags struct {
	agentLog                     string
	databaseLog                  string
	systemMetricsCSV             string
	systemMetricsCSVInterpolated string

	javaExec   string
	etcdExec   string
	zetcdExec  string
	cetcdExec  string
	consulExec string

	zkWorkDir     string
	zkDataDir     string
	zkConfig      string
	etcdDataDir   string
	consulDataDir string

	grpcPort         string
	diskDevice       string
	networkInterface string
	clientNumPath    string
}

var globalFlags flags

func init() {
	dn, err := df.GetDevice("/")
	if err != nil {
		fmt.Printf("cannot get disk device mounted at '/' (%v)\n", err)
	}
	nm, err := netutil.GetDefaultInterfaces()
	if err != nil {
		fmt.Printf("cannot detect default network interface (%v)\n", err)
	}
	var nt string
	for k := range nm {
		nt = k
		break
	}

	Command.PersistentFlags().StringVar(&globalFlags.agentLog, "agent-log", filepath.Join(homeDir(), "agent.log"), "agent log path.")
	Command.PersistentFlags().StringVar(&globalFlags.databaseLog, "database-log", filepath.Join(homeDir(), "database.log"), "Database log path.")
	Command.PersistentFlags().StringVar(&globalFlags.systemMetricsCSV, "system-metrics-csv", filepath.Join(homeDir(), "server-system-metrics.csv"), "Raw system metrics data path.")
	Command.PersistentFlags().StringVar(&globalFlags.systemMetricsCSVInterpolated, "system-metrics-csv-interpolated", filepath.Join(homeDir(), "server-system-metrics-interpolated.csv"), "Interpolated system metrics data path.")

	Command.PersistentFlags().StringVar(&globalFlags.javaExec, "java-exec", "/usr/bin/java", "Java executable binary path (needed for Zookeeper).")
	Command.PersistentFlags().StringVar(&globalFlags.etcdExec, "etcd-exec", filepath.Join(os.Getenv("GOPATH"), "bin/etcd"), "etcd executable binary path.")
	Command.PersistentFlags().StringVar(&globalFlags.zetcdExec, "zetcd-exec", filepath.Join(os.Getenv("GOPATH"), "bin/zetcd"), "zetcd executable binary path .")
	Command.PersistentFlags().StringVar(&globalFlags.cetcdExec, "cetcd-exec", filepath.Join(os.Getenv("GOPATH"), "bin/cetcd"), "cetcd executable binary path .")
	Command.PersistentFlags().StringVar(&globalFlags.consulExec, "consul-exec", filepath.Join(os.Getenv("GOPATH"), "bin/consul"), "Consul executable binary path.")

	Command.PersistentFlags().StringVar(&globalFlags.zkWorkDir, "zookeeper-work-dir", filepath.Join(homeDir(), "zookeeper"), "Zookeeper working directory.")
	Command.PersistentFlags().StringVar(&globalFlags.zkDataDir, "zookeeper-data-dir", filepath.Join(homeDir(), "zookeeper/zookeeper.data"), "Zookeeper data directory.")
	Command.PersistentFlags().StringVar(&globalFlags.zkConfig, "zookeeper-config", filepath.Join(homeDir(), "zookeeper/zookeeper.config"), "Zookeeper configuration file path.")
	Command.PersistentFlags().StringVar(&globalFlags.etcdDataDir, "etcd-data-dir", filepath.Join(homeDir(), "etcd.data"), "etcd data directory.")
	Command.PersistentFlags().StringVar(&globalFlags.consulDataDir, "consul-data-dir", filepath.Join(homeDir(), "consul.data"), "Consul data directory.")

	Command.PersistentFlags().StringVar(&globalFlags.grpcPort, "agent-port", ":3500", "Port to server agent gRPC server.")
	Command.PersistentFlags().StringVar(&globalFlags.diskDevice, "disk-device", dn, "Disk device to collect disk statistics metrics from.")
	Command.PersistentFlags().StringVar(&globalFlags.networkInterface, "network-interface", nt, "Network interface to record in/outgoing packets.")
	Command.PersistentFlags().StringVar(&globalFlags.clientNumPath, "client-num-path", filepath.Join(homeDir(), "client-num"), "File path to store client number.")
}

// Command implements 'agent' command.
var Command = &cobra.Command{
	Use:   "agent",
	Short: "Database 'agent' in remote servers.",
	RunE:  commandFunc,
}

func commandFunc(cmd *cobra.Command, args []string) error {
	no, nerr := ntp.DefaultSync()
	fmt.Printf("npt update output: %q\n", no)
	if nerr != nil {
		fmt.Printf("npt update error: %v\n", nerr)
	}

	lcfg := zap.Config{
		Level:       zap.NewAtomicLevelAt(zap.InfoLevel),
		Development: false,
		Sampling: &zap.SamplingConfig{
			Initial:    100,
			Thereafter: 100,
		},
		Encoding:      "json",
		EncoderConfig: zap.NewProductionEncoderConfig(),

		OutputPaths:      []string{globalFlags.agentLog},
		ErrorOutputPaths: []string{globalFlags.agentLog},
	}
	lg, lerr := lcfg.Build()
	if lerr != nil {
		return lerr
	}

	var (
		grpcServer = grpc.NewServer()
		sender     = NewServer(lg)
	)
	ln, err := net.Listen("tcp", globalFlags.grpcPort)
	if err != nil {
		return err
	}
	dbtesterpb.RegisterTransporterServer(grpcServer, sender)

	lg.Info("agent started", zap.String("grpc-server-port", globalFlags.grpcPort), zap.String("agent-log", globalFlags.agentLog))
	return grpcServer.Serve(ln)
}


================================================
FILE: agent/doc.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package agent is a database agent in remote servers.
package agent


================================================
FILE: agent/server.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"fmt"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
	"time"

	"github.com/etcd-io/dbtester/dbtesterpb"
	"github.com/etcd-io/dbtester/pkg/fileinspect"

	"github.com/gyuho/linux-inspect/inspect"
	"go.uber.org/zap"
	"golang.org/x/net/context"
)

// implements dbtesterpb.TransporterServer
type transporterServer struct {
	lg  *zap.Logger
	req dbtesterpb.Request

	databaseLogFile      *os.File
	proxyDatabaseLogfile *os.File
	clientNumPath        string

	// cmd is the main process that's running the database
	cmd *exec.Cmd
	// cmdWait channel is closed
	// after database process is closed
	cmdWait chan struct{}

	pid int64

	proxyCmd     *exec.Cmd
	proxyCmdWait chan struct{}
	proxyPid     int64

	metricsCSV *inspect.CSV

	// trigger log uploads to cloud storage
	// this should be triggered before we shut down
	// the agent server
	uploadSig chan struct{}
	csvReady  chan struct{}

	// notified after all tests finish
	notifier chan os.Signal
}

// NewServer returns a new server that implements gRPC interface.
func NewServer(lg *zap.Logger) dbtesterpb.TransporterServer {
	notifier := make(chan os.Signal, 1)
	signal.Notify(notifier, syscall.SIGINT, syscall.SIGTERM)

	return &transporterServer{
		lg:            lg,
		clientNumPath: globalFlags.clientNumPath,
		uploadSig:     make(chan struct{}, 1),
		csvReady:      make(chan struct{}),
		notifier:      notifier,
	}
}

func (t *transporterServer) Transfer(ctx context.Context, req *dbtesterpb.Request) (*dbtesterpb.Response, error) {
	if req != nil {
		t.lg.Info(
			"received gRPC request",
			zap.String("operation", req.Operation.String()),
			zap.String("database-id", req.DatabaseID.String()),
			zap.Int64("client-number", req.CurrentClientNumber),
		)
	}

	if req.Operation == dbtesterpb.Operation_Start {
		f, err := openToAppend(globalFlags.databaseLog)
		if err != nil {
			return nil, err
		}
		t.databaseLogFile = f
		t.lg.Info("created database log file", zap.String("path", globalFlags.databaseLog))

		if req.DatabaseID == dbtesterpb.DatabaseID_zetcd__beta || req.DatabaseID == dbtesterpb.DatabaseID_cetcd__beta {
			proxyLog := globalFlags.databaseLog + "-" + t.req.DatabaseID.String()
			pf, err := openToAppend(proxyLog)
			if err != nil {
				return nil, err
			}
			t.proxyDatabaseLogfile = pf
			t.lg.Info("created database proxy log file", zap.String("path", proxyLog))
		}

		switch req.DatabaseID {
		case dbtesterpb.DatabaseID_etcd__other,
			dbtesterpb.DatabaseID_etcd__tip,
			dbtesterpb.DatabaseID_etcd__v3_2,
			dbtesterpb.DatabaseID_etcd__v3_3:
			t.lg.Info(
				"requested on etcd",
				zap.String("executable-binary-path", globalFlags.etcdExec),
				zap.String("data-directory", globalFlags.etcdDataDir),
			)

		case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
			t.lg.Info(
				"requested on Zookeeper",
				zap.String("working-directory", globalFlags.zkWorkDir),
				zap.String("data-directory", globalFlags.zkDataDir),
				zap.String("configuration-file", globalFlags.zkConfig),
			)

		case dbtesterpb.DatabaseID_consul__v1_0_2:
			t.lg.Info(
				"requested on Consul",
				zap.String("executable-binary-path", globalFlags.consulExec),
				zap.String("data-directory", globalFlags.consulDataDir),
			)

		case dbtesterpb.DatabaseID_zetcd__beta:
			t.lg.Info(
				"requested on zetcd",
				zap.String("executable-binary-path", globalFlags.zetcdExec),
				zap.String("data-directory", globalFlags.etcdDataDir),
			)

		case dbtesterpb.DatabaseID_cetcd__beta:
			t.lg.Info(
				"requested on cetcd",
				zap.String("executable-binary-path", globalFlags.cetcdExec),
				zap.String("data-directory", globalFlags.etcdDataDir),
			)
		}

		// re-use configurations for next requests
		t.req = *req
	}
	if req.Operation == dbtesterpb.Operation_Heartbeat {
		t.req.CurrentClientNumber = req.CurrentClientNumber
	}

	var diskSpaceUsageBytes int64
	switch req.Operation {
	case dbtesterpb.Operation_Start:
		switch t.req.DatabaseID {
		case dbtesterpb.DatabaseID_etcd__other,
			dbtesterpb.DatabaseID_etcd__tip,
			dbtesterpb.DatabaseID_etcd__v3_2,
			dbtesterpb.DatabaseID_etcd__v3_3,
			dbtesterpb.DatabaseID_zetcd__beta,
			dbtesterpb.DatabaseID_cetcd__beta:
			if err := startEtcd(&globalFlags, t); err != nil {
				return nil, err
			}
			switch t.req.DatabaseID {
			case dbtesterpb.DatabaseID_zetcd__beta:
				if err := startZetcd(&globalFlags, t); err != nil {
					return nil, err
				}
				go func() {
					defer close(t.proxyCmdWait)
					if err := t.proxyCmd.Wait(); err != nil {
						t.lg.Warn("zetcd t.proxyCmd.Wait() returned error", zap.Error(err))
						return
					}
					t.lg.Info("exiting zetcd", zap.String("executable-path", t.proxyCmd.Path))
				}()

			case dbtesterpb.DatabaseID_cetcd__beta:
				if err := startCetcd(&globalFlags, t); err != nil {
					return nil, err
				}
				go func() {
					defer close(t.proxyCmdWait)
					if err := t.proxyCmd.Wait(); err != nil {
						t.lg.Warn("cetcd t.proxyCmd.Wait() returned error", zap.Error(err))
						return
					}
					t.lg.Info("exiting cetcd", zap.String("executable-path", t.proxyCmd.Path))
				}()
			}

		case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
			if err := startZookeeper(&globalFlags, t); err != nil {
				return nil, err
			}

		case dbtesterpb.DatabaseID_consul__v1_0_2:
			if err := startConsul(&globalFlags, t); err != nil {
				return nil, err
			}

		default:
			return nil, fmt.Errorf("unknown database %q", t.req.DatabaseID)
		}

		go func() {
			defer close(t.cmdWait)
			if err := t.cmd.Wait(); err != nil {
				t.lg.Warn("t.cmd.Wait() returned error", zap.Error(err))
				return
			}
			t.lg.Info("exiting", zap.String("executable-path", t.cmd.Path))
		}()
		if err := startMetrics(&globalFlags, t); err != nil {
			return nil, err
		}

	case dbtesterpb.Operation_Stop:
		if t.cmd == nil {
			return nil, fmt.Errorf("nil command")
		}

		// to collect more monitoring data
		t.lg.Info("waiting a few more seconds before stopping", zap.String("executable-path", t.cmd.Path))
		time.Sleep(3 * time.Second)

		// TODO: https://github.com/etcd-io/dbtester/issues/330
		t.lg.Info("sending", zap.String("syscall", syscall.SIGINT.String()), zap.Int64("pid", t.pid), zap.String("executable-path", t.cmd.Path))
		if err := t.cmd.Process.Signal(syscall.SIGINT); err != nil {
			t.lg.Warn("syscall.SIGINT failed", zap.Error(err))

			time.Sleep(3 * time.Second)
			t.lg.Info("sending", zap.String("syscall", syscall.SIGTERM.String()), zap.Int64("pid", t.pid), zap.String("executable-path", t.cmd.Path))
			if err := syscall.Kill(int(t.pid), syscall.SIGTERM); err != nil {
				t.lg.Warn("syscall.Kill failed", zap.Error(err))
			}
		}

		time.Sleep(time.Second)
		<-t.cmdWait

		if t.databaseLogFile != nil {
			t.databaseLogFile.Sync()
			t.databaseLogFile.Close()
		}
		t.lg.Info("stopped", zap.String("database", t.req.DatabaseID.String()), zap.Int64("pid", t.pid))

		if t.proxyCmd != nil {
			t.lg.Info("sending", zap.String("syscall", syscall.SIGINT.String()), zap.Int64("pid", t.proxyPid), zap.String("executable-path", t.proxyCmd.Path))
			if err := t.proxyCmd.Process.Signal(syscall.SIGINT); err != nil {
				t.lg.Warn("syscall.SIGINT failed", zap.Error(err))

				time.Sleep(3 * time.Second)
				t.lg.Info("sending", zap.String("syscall", syscall.SIGTERM.String()), zap.Int64("pid", t.proxyPid), zap.String("executable-path", t.proxyCmd.Path))
				if err := syscall.Kill(int(t.proxyPid), syscall.SIGTERM); err != nil {
					t.lg.Warn("syscall.Kill failed", zap.Error(err))
				}
			}

			<-t.proxyCmdWait
			t.lg.Info("stopped", zap.String("database", t.req.DatabaseID.String()), zap.Int64("pid", t.proxyPid))

			if t.proxyDatabaseLogfile != nil {
				t.proxyDatabaseLogfile.Sync()
				t.proxyDatabaseLogfile.Close()
			}
		}

		t.uploadSig <- struct{}{}
		<-t.csvReady

		if t.req.TriggerLogUpload {
			if err := uploadLog(&globalFlags, t); err != nil {
				return nil, err
			}
		}

		dbs, err := measureDatabasSize(globalFlags, req.DatabaseID)
		if err != nil {
			return nil, err
		}
		diskSpaceUsageBytes = dbs

	case dbtesterpb.Operation_Heartbeat:
		t.lg.Info("overwriting clients number", zap.Int64("number", t.req.CurrentClientNumber), zap.String("number-path", t.clientNumPath))
		if err := toFile(fmt.Sprintf("%d", t.req.CurrentClientNumber), t.clientNumPath); err != nil {
			return nil, err
		}

	default:
		return nil, fmt.Errorf("Not implemented %v", req.Operation)
	}

	t.lg.Info("Transfer success!")
	return &dbtesterpb.Response{Success: true, DiskSpaceUsageBytes: diskSpaceUsageBytes}, nil
}

func measureDatabasSize(flg flags, rdb dbtesterpb.DatabaseID) (int64, error) {
	switch rdb {
	case dbtesterpb.DatabaseID_etcd__other,
		dbtesterpb.DatabaseID_etcd__tip,
		dbtesterpb.DatabaseID_etcd__v3_2,
		dbtesterpb.DatabaseID_etcd__v3_3,
		dbtesterpb.DatabaseID_cetcd__beta,
		dbtesterpb.DatabaseID_zetcd__beta:
		return fileinspect.Size(flg.etcdDataDir)

	case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
		return fileinspect.Size(flg.zkDataDir)

	case dbtesterpb.DatabaseID_consul__v1_0_2:
		return fileinspect.Size(flg.consulDataDir)

	default:
		return 0, fmt.Errorf("uknown %q", rdb)
	}
}


================================================
FILE: agent/server_system_metrics.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"fmt"
	"os"
	"time"

	"github.com/gyuho/linux-inspect/inspect"
	"github.com/gyuho/linux-inspect/top"
	"go.uber.org/zap"
)

// startMetrics starts collecting metrics.
func startMetrics(fs *flags, t *transporterServer) (err error) {
	if fs == nil || t == nil || t.cmd == nil {
		return fmt.Errorf("cannot find process to track (%+v, %+v)", fs, t)
	}

	t.lg.Info(
		"starting collecting system metrics",
		zap.String("database", t.req.DatabaseID.String()),
		zap.String("disk-device", fs.diskDevice),
		zap.String("network-device", fs.networkInterface),
		zap.Int64("pid", t.pid),
	)
	if err = os.RemoveAll(fs.systemMetricsCSV); err != nil {
		return err
	}
	if err = toFile(fmt.Sprintf("%d", t.req.CurrentClientNumber), t.clientNumPath); err != nil {
		return err
	}

	tcfg := &top.Config{
		Exec:           top.DefaultExecPath,
		IntervalSecond: 1,
		PID:            t.pid,
	}
	t.metricsCSV, err = inspect.NewCSV(
		fs.systemMetricsCSV,
		t.pid,
		fs.diskDevice,
		fs.networkInterface,
		t.clientNumPath,
		tcfg,
	)
	if err := t.metricsCSV.Add(); err != nil {
		return err
	}

	go func() {
		for {
			select {
			case <-time.After(time.Second):
				if err := t.metricsCSV.Add(); err != nil {
					t.lg.Warn("inspect.CSV.Add error", zap.Error(err))
					continue
				}

			case <-t.uploadSig:
				t.lg.Info("upload requested, saving CSV", zap.String("path", t.metricsCSV.FilePath))
				if err := t.metricsCSV.Save(); err != nil {
					t.lg.Warn("failed to save CSV", zap.Error(err))
				} else {
					t.lg.Info("saved CSV", zap.String("path", t.metricsCSV.FilePath))
				}

				interpolated, err := t.metricsCSV.Interpolate()
				if err != nil {
					t.lg.Fatal("failed to inspect.CSV.Interpolate", zap.Error(err))
				}
				interpolated.FilePath = fs.systemMetricsCSVInterpolated

				if err := interpolated.Save(); err != nil {
					t.lg.Warn("failed to save CSV", zap.Error(err))
				} else {
					t.lg.Info("saved CSV", zap.String("path", interpolated.FilePath))
				}

				close(t.csvReady)
				return

			case sig := <-t.notifier:
				t.lg.Info("received a signal", zap.String("signal", sig.String()))
				return
			}
		}
	}()
	return nil
}


================================================
FILE: agent/upload_log.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"fmt"
	"path/filepath"
	"strings"
	"time"

	"github.com/etcd-io/dbtester/dbtesterpb"
	"github.com/etcd-io/dbtester/pkg/remotestorage"

	"go.uber.org/zap"
)

// uploadLog starts cetcd. This assumes that etcd is already started.
func uploadLog(fs *flags, t *transporterServer) error {
	t.lg.Info(
		"stopped collecting metrics, now uploading logs to storage",
		zap.String("gcp-project-name", t.req.ConfigClientMachineInitial.GoogleCloudProjectName),
	)
	u, err := remotestorage.NewGoogleCloudStorage(t.lg, []byte(t.req.ConfigClientMachineInitial.GoogleCloudStorageKey), t.req.ConfigClientMachineInitial.GoogleCloudProjectName)
	if err != nil {
		return err
	}

	var uerr error

	{
		srcDatabaseLogPath := fs.databaseLog
		dstDatabaseLogPath := filepath.Base(fs.databaseLog)
		if !strings.HasPrefix(filepath.Base(fs.databaseLog), t.req.DatabaseTag) {
			dstDatabaseLogPath = fmt.Sprintf("%s-%d-%s", t.req.DatabaseTag, t.req.IPIndex+1, filepath.Base(fs.databaseLog))
		}
		dstDatabaseLogPath = filepath.Join(t.req.ConfigClientMachineInitial.GoogleCloudStorageSubDirectory, dstDatabaseLogPath)
		t.lg.Info("uploading database log", zap.String("source", srcDatabaseLogPath), zap.String("destination", dstDatabaseLogPath))
		for k := 0; k < 30; k++ {
			if uerr = u.UploadFile(t.req.ConfigClientMachineInitial.GoogleCloudStorageBucketName, srcDatabaseLogPath, dstDatabaseLogPath); uerr != nil {
				t.lg.Warn("upload error; retrying...", zap.Error(uerr))
				time.Sleep(2 * time.Second)
				continue
			}
			break
		}
		if uerr != nil {
			return uerr
		}
	}

	{
		if t.req.DatabaseID == dbtesterpb.DatabaseID_zetcd__beta ||
			t.req.DatabaseID == dbtesterpb.DatabaseID_cetcd__beta {
			dpath := fs.databaseLog + "-" + t.req.DatabaseID.String()
			srcDatabaseLogPath2 := dpath
			dstDatabaseLogPath2 := filepath.Base(dpath)
			if !strings.HasPrefix(filepath.Base(dpath), t.req.DatabaseTag) {
				dstDatabaseLogPath2 = fmt.Sprintf("%s-%d-%s", t.req.DatabaseTag, t.req.IPIndex+1, filepath.Base(dpath))
			}
			dstDatabaseLogPath2 = filepath.Join(t.req.ConfigClientMachineInitial.GoogleCloudStorageSubDirectory, dstDatabaseLogPath2)
			t.lg.Info("uploading proxy database log", zap.String("source", srcDatabaseLogPath2), zap.String("destination", dstDatabaseLogPath2))
			for k := 0; k < 30; k++ {
				if uerr = u.UploadFile(t.req.ConfigClientMachineInitial.GoogleCloudStorageBucketName, srcDatabaseLogPath2, dstDatabaseLogPath2); uerr != nil {
					t.lg.Warn("upload error; retrying...", zap.Error(uerr))
					time.Sleep(2 * time.Second)
					continue
				}
				break
			}
			if uerr != nil {
				return uerr
			}
		}
	}

	{
		srcSysMetricsDataPath := fs.systemMetricsCSV
		dstSysMetricsDataPath := filepath.Base(fs.systemMetricsCSV)
		if !strings.HasPrefix(filepath.Base(fs.systemMetricsCSV), t.req.DatabaseTag) {
			dstSysMetricsDataPath = fmt.Sprintf("%s-%d-%s", t.req.DatabaseTag, t.req.IPIndex+1, filepath.Base(fs.systemMetricsCSV))
		}
		dstSysMetricsDataPath = filepath.Join(t.req.ConfigClientMachineInitial.GoogleCloudStorageSubDirectory, dstSysMetricsDataPath)
		t.lg.Info("uploading system metrics", zap.String("source", srcSysMetricsDataPath), zap.String("destination", dstSysMetricsDataPath))
		for k := 0; k < 30; k++ {
			if uerr := u.UploadFile(t.req.ConfigClientMachineInitial.GoogleCloudStorageBucketName, srcSysMetricsDataPath, dstSysMetricsDataPath); uerr != nil {
				t.lg.Warn("upload error; retrying...", zap.Error(uerr))
				time.Sleep(2 * time.Second)
				continue
			}
			break
		}
		if uerr != nil {
			return uerr
		}
	}

	{
		srcSysMetricsInterpolatedDataPath := fs.systemMetricsCSVInterpolated
		dstSysMetricsInterpolatedDataPath := filepath.Base(fs.systemMetricsCSVInterpolated)
		if !strings.HasPrefix(filepath.Base(fs.systemMetricsCSVInterpolated), t.req.DatabaseTag) {
			dstSysMetricsInterpolatedDataPath = fmt.Sprintf("%s-%d-%s", t.req.DatabaseTag, t.req.IPIndex+1, filepath.Base(fs.systemMetricsCSVInterpolated))
		}
		dstSysMetricsInterpolatedDataPath = filepath.Join(t.req.ConfigClientMachineInitial.GoogleCloudStorageSubDirectory, dstSysMetricsInterpolatedDataPath)
		t.lg.Info("uploading interpolated system metrics", zap.String("source", srcSysMetricsInterpolatedDataPath), zap.String("destination", dstSysMetricsInterpolatedDataPath))
		for k := 0; k < 30; k++ {
			if uerr := u.UploadFile(t.req.ConfigClientMachineInitial.GoogleCloudStorageBucketName, srcSysMetricsInterpolatedDataPath, dstSysMetricsInterpolatedDataPath); uerr != nil {
				t.lg.Warn("upload error; retrying...", zap.Error(uerr))
				time.Sleep(2 * time.Second)
				continue
			}
			break
		}
		if uerr != nil {
			return uerr
		}
	}

	{
		srcAgentLogPath := fs.agentLog
		dstAgentLogPath := filepath.Base(fs.agentLog)
		if !strings.HasPrefix(filepath.Base(fs.agentLog), t.req.DatabaseTag) {
			dstAgentLogPath = fmt.Sprintf("%s-%d-%s", t.req.DatabaseTag, t.req.IPIndex+1, filepath.Base(fs.agentLog))
		}
		dstAgentLogPath = filepath.Join(t.req.ConfigClientMachineInitial.GoogleCloudStorageSubDirectory, dstAgentLogPath)
		t.lg.Info("uploading agent log", zap.String("source", srcAgentLogPath), zap.String("destination", dstAgentLogPath))
		for k := 0; k < 30; k++ {
			if uerr := u.UploadFile(t.req.ConfigClientMachineInitial.GoogleCloudStorageBucketName, srcAgentLogPath, dstAgentLogPath); uerr != nil {
				t.lg.Warn("upload error; retrying...", zap.Error(uerr))
				time.Sleep(2 * time.Second)
				continue
			}
			break
		}
	}

	return uerr
}


================================================
FILE: agent/util.go
================================================
// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package agent

import (
	"os"
	"runtime"
)

func openToAppend(fpath string) (*os.File, error) {
	f, err := os.OpenFile(fpath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0777)
	if err != nil {
		return nil, err
	}
	return f, nil
}

func openToOverwrite(fpath string) (*os.File, error) {
	f, err := os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0777)
	if err != nil {
		return nil, err
	}
	return f, nil
}

func toFile(txt, fpath string) error {
	f, err := openToOverwrite(fpath)
	if err != nil {
		f, err = os.Create(fpath)
		if err != nil {
			return err
		}
	}
	defer f.Close()
	_, err = f.WriteString(txt)
	return err
}

func homeDir() string {
	if runtime.GOOS == "windows" {
		home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
		if home == "" {
			home = os.Getenv("USERPROFILE")
		}
		return home
	}
	return os.Getenv("HOME")
}

// exist returns true if the file or directory exists.
func exist(fpath string) bool {
	st, err := os.Stat(fpath)
	if err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	if st.IsDir() {
		return true
	}
	if _, err := os.Stat(fpath); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}


================================================
FILE: analyze/01_read_raw_data_to_test_data.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package analyze

import (
	"fmt"
	"strconv"

	"github.com/gyuho/dataframe"
)

// sysMetricsColumnsToRead is already aggregated
// and interpolated by unix second.
var sysMetricsColumnsToRead = []string{
	"UNIX-SECOND",
	"VOLUNTARY-CTXT-SWITCHES",
	"NON-VOLUNTARY-CTXT-SWITCHES",
	"CPU-NUM",
	"LOAD-AVERAGE-1-MINUTE",
	"VMRSS-NUM",
	"READS-COMPLETED",
	"READS-COMPLETED-DELTA",
	"SECTORS-READ",
	"SECTORS-READ-DELTA",
	"WRITES-COMPLETED",
	"WRITES-COMPLETED-DELTA",
	"SECTORS-WRITTEN",
	"SECTORS-WRITTEN-DELTA",
	"READ-BYTES-DELTA",
	"WRITE-BYTES-DELTA",
	"RECEIVE-BYTES-NUM",
	"RECEIVE-BYTES-NUM-DELTA",
	"TRANSMIT-BYTES-NUM",
	"TRANSMIT-BYTES-NUM-DELTA",
	"EXTRA", // will be converted to 'CLIENT-NUM'
}

type testData struct {
	filePath        string
	frontUnixSecond int64
	lastUnixSecond  int64
	frame           dataframe.Frame
}

// readSystemMetrics extracts only the columns that we need for analyze.
func readSystemMetrics(fpath string) (data testData, err error) {
	originalFrame, err := dataframe.NewFromCSV(nil, fpath)
	if err != nil {
		return testData{}, err
	}

	data.filePath = fpath
	data.frame = dataframe.New()
	var unixSecondCol dataframe.Column
	for _, name := range sysMetricsColumnsToRead {
		var column dataframe.Column
		column, err = originalFrame.Column(name)
		if err != nil {
			return testData{}, err
		}
		if err = data.frame.AddColumn(column); err != nil {
			return testData{}, err
		}
		if name == "UNIX-SECOND" {
			unixSecondCol = column
		}
	}

	// get first(minimum) unix second
	fv, ok := unixSecondCol.FrontNonNil()
	if !ok {
		return testData{}, fmt.Errorf("FrontNonNil %s has empty Unix time %v", fpath, fv)
	}
	fs, ok := fv.String()
	if !ok {
		return testData{}, fmt.Errorf("cannot String %v", fv)
	}
	data.frontUnixSecond, err = strconv.ParseInt(fs, 10, 64)
	if err != nil {
		return testData{}, err
	}

	// get last(maximum) unix second
	bv, ok := unixSecondCol.BackNonNil()
	if !ok {
		return testData{}, fmt.Errorf("BackNonNil %s has empty Unix time %v", fpath, fv)
	}
	bs, ok := bv.String()
	if !ok {
		return testData{}, fmt.Errorf("cannot String %v", bv)
	}
	data.lastUnixSecond, err = strconv.ParseInt(bs, 10, 64)
	if err != nil {
		return testData{}, err
	}

	return
}


================================================
FILE: analyze/02_read_all_metrics_to_analyze_data.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package analyze

import (
	"fmt"

	"github.com/gyuho/dataframe"
)

type analyzeData struct {
	databaseTag string
	legend      string

	minUnixSecond int64
	maxUnixSecond int64
	sys           []testData

	// aggregated frame within [min,maxUnixSecond] from sys
	sysAgg               dataframe.Frame
	benchMetricsFilePath string
	benchMetrics         testData

	// aggregated from sysAgg and benchMetrics
	aggregated dataframe.Frame

	allAggregatedOutputPath string
}

// readSystemMetricsAll reads all system metric files
// (e.g. if cluster is 3-node, read all 3 files).
// It returns minimum and maximum common unix second and a list of frames.
func readSystemMetricsAll(fpaths ...string) (data *analyzeData, err error) {
	data = &analyzeData{}
	for i, fpath := range fpaths {
		sm, err := readSystemMetrics(fpath)
		if err != nil {
			return nil, err
		}
		if i == 0 {
			data.minUnixSecond = sm.frontUnixSecond
			data.maxUnixSecond = sm.lastUnixSecond
		}
		if data.minUnixSecond < sm.frontUnixSecond {
			data.minUnixSecond = sm.frontUnixSecond
		}
		if data.maxUnixSecond > sm.lastUnixSecond {
			data.maxUnixSecond = sm.lastUnixSecond
		}
		data.sys = append(data.sys, sm)
	}
	return
}

// aggSystemMetrics aggregates all system metrics from 3+ nodes.
func (data *analyzeData) aggSystemMetrics() error {
	// monitor CSVs from multiple servers, and want them to have equal number of rows
	// Truncate all rows before data.minUnixSecond and after data.maxUnixSecond
	minTS := fmt.Sprintf("%d", data.minUnixSecond)
	maxTS := fmt.Sprintf("%d", data.maxUnixSecond)
	data.sysAgg = dataframe.New()
	for i := range data.sys {
		uc, err := data.sys[i].frame.Column("UNIX-SECOND")
		if err != nil {
			return err
		}
		minTSIdx, ok := uc.FindFirst(dataframe.NewStringValue(minTS))
		if !ok {
			return fmt.Errorf("%v does not exist in %s", minTS, data.sys[i].filePath)
		}
		maxTSIdx, ok := uc.FindFirst(dataframe.NewStringValue(maxTS))
		if !ok {
			return fmt.Errorf("%v does not exist in %s", maxTS, data.sys[i].filePath)
		}

		for _, header := range data.sys[i].frame.Headers() {
			if i > 0 && header == "UNIX-SECOND" {
				// skip for other databases; we want to keep just one UNIX-SECOND column
				continue
			}

			var col dataframe.Column
			col, err = data.sys[i].frame.Column(header)
			if err != nil {
				return err
			}
			// just keep rows from [min,maxUnixSecond]
			if err = col.Keep(minTSIdx, maxTSIdx+1); err != nil {
				return err
			}

			if header == "UNIX-SECOND" {
				if err = data.sysAgg.AddColumn(col); err != nil {
					return err
				}
				continue
			}

			switch header {
			case "CPU-NUM":
				header = "CPU"

			case "VMRSS-NUM":
				header = "VMRSS-MB"

				// convert bytes to mb
				colN := col.Count()
				for rowIdx := 0; rowIdx < colN; rowIdx++ {
					var rowV dataframe.Value
					rowV, err = col.Value(rowIdx)
					if err != nil {
						return err
					}
					fv, _ := rowV.Float64()
					frv := float64(fv) * 0.000001
					if err = col.Set(rowIdx, dataframe.NewStringValue(fmt.Sprintf("%.2f", frv))); err != nil {
						return err
					}
				}

			case "EXTRA":
				// dbtester uses linux-inspect 'EXTRA' column as 'CLIENT-NUM'
				header = "CLIENT-NUM"
			}

			// since we are aggregating multiple system-metrics CSV files
			// suffix header with the index
			col.UpdateHeader(fmt.Sprintf("%s-%d", header, i+1))
			if err = data.sysAgg.AddColumn(col); err != nil {
				return err
			}
		}
	}

	return nil
}


================================================
FILE: analyze/03_read_benchmark_metrics_to_analyze_data.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package analyze

import (
	"fmt"

	"github.com/gyuho/dataframe"
)

// importBenchMetrics adds benchmark metrics from client-side
// and aggregates this to system metrics by unix timestamps.
func (data *analyzeData) importBenchMetrics(fpath string) (err error) {
	data.benchMetricsFilePath = fpath

	var tdf dataframe.Frame
	tdf, err = dataframe.NewFromCSV(nil, fpath)
	if err != nil {
		return
	}

	var oldTSCol dataframe.Column
	oldTSCol, err = tdf.Column("UNIX-SECOND")
	if err != nil {
		return err
	}

	// get first(minimum) unix second
	fv1, ok := oldTSCol.FrontNonNil()
	if !ok {
		return fmt.Errorf("FrontNonNil %s has empty Unix time %v", fpath, fv1)
	}
	ivv1, ok := fv1.Int64()
	if !ok {
		return fmt.Errorf("cannot Int64 %v", fv1)
	}
	data.benchMetrics.frontUnixSecond = int64(ivv1)

	// get last(maximum) unix second
	fv2, ok := oldTSCol.BackNonNil()
	if !ok {
		return fmt.Errorf("BackNonNil %s has empty Unix time %v", fpath, fv2)
	}
	ivv2, ok := fv2.Int64()
	if !ok {
		return fmt.Errorf("cannot Int64 %v", fv2)
	}
	data.benchMetrics.lastUnixSecond = int64(ivv2)

	// UNIX-SECOND, CONTROL-CLIENT-NUM, MIN-LATENCY-MS, AVG-LATENCY-MS, MAX-LATENCY-MS, AVG-THROUGHPUT
	var oldControlClientNumCol dataframe.Column
	oldControlClientNumCol, err = tdf.Column("CONTROL-CLIENT-NUM")
	if err != nil {
		return err
	}
	var oldMinLatencyMSCol dataframe.Column
	oldMinLatencyMSCol, err = tdf.Column("MIN-LATENCY-MS")
	if err != nil {
		return err
	}
	var oldAvgLatencyMSCol dataframe.Column
	oldAvgLatencyMSCol, err = tdf.Column("AVG-LATENCY-MS")
	if err != nil {
		return err
	}
	var oldMaxLatencyMSCol dataframe.Column
	oldMaxLatencyMSCol, err = tdf.Column("MAX-LATENCY-MS")
	if err != nil {
		return err
	}
	var oldAvgThroughputCol dataframe.Column
	oldAvgThroughputCol, err = tdf.Column("AVG-THROUGHPUT")
	if err != nil {
		return err
	}

	sec2Data := make(map[int64]rowData)
	for i := 0; i < oldTSCol.Count(); i++ {
		tv, err := oldTSCol.Value(i)
		if err != nil {
			return err
		}
		ts, ok := tv.Int64()
		if !ok {
			return fmt.Errorf("cannot Int64 %v", tv)
		}

		cv, err := oldControlClientNumCol.Value(i)
		if err != nil {
			return err
		}
		clientN, ok := cv.Int64()
		if !ok {
			return fmt.Errorf("cannot Int64 %v", cv)
		}
		cn := int64(clientN)

		lv1, err1 := oldMinLatencyMSCol.Value(i)
		if err1 != nil {
			return err1
		}
		minLat, ok1 := lv1.Float64()
		if !ok1 {
			return fmt.Errorf("cannot Float64 %v", lv1)
		}

		lv2, err2 := oldAvgLatencyMSCol.Value(i)
		if err2 != nil {
			return err2
		}
		avgLat, ok2 := lv2.Float64()
		if !ok2 {
			return fmt.Errorf("cannot Float64 %v", lv2)
		}

		lv3, err3 := oldMaxLatencyMSCol.Value(i)
		if err3 != nil {
			return err3
		}
		maxLat, ok3 := lv3.Float64()
		if !ok3 {
			return fmt.Errorf("cannot Float64 %v", lv3)
		}

		hv, err := oldAvgThroughputCol.Value(i)
		if err != nil {
			return err
		}
		dataThr, ok := hv.Float64()
		if !ok {
			return fmt.Errorf("cannot Float64 %v", hv)
		}

		// handle duplicate timestamps
		if v, ok := sec2Data[ts]; !ok {
			sec2Data[ts] = rowData{clientN: cn, minLat: minLat, avgLat: avgLat, maxLat: maxLat, throughput: dataThr}
		} else {
			// it is possible that there are duplicate timestamps with
			// different client numbers, when clients number bump up
			// these requests happen within this unix second, add up the
			// throughput, and select min,max and avg of latencies
			sec2Data[ts] = rowData{
				clientN:    cn,
				minLat:     minFloat64(v.minLat, minLat),
				avgLat:     (v.avgLat + avgLat) / 2.0,
				maxLat:     maxFloat64(v.maxLat, maxLat),
				throughput: v.throughput + dataThr,
			}
		}
	}

	// UNIX-SECOND, CONTROL-CLIENT-NUM, MIN-LATENCY-MS, AVG-LATENCY-MS, MAX-LATENCY-MS, AVG-THROUGHPUT
	// aggregate duplicate benchmark timestamps with average values
	// OR fill in missing timestamps with zero values
	//
	// expected row number
	expectedRowN := data.benchMetrics.lastUnixSecond - data.benchMetrics.frontUnixSecond + 1
	newSecondCol := dataframe.NewColumn("UNIX-SECOND")
	newControlClientNumCol := dataframe.NewColumn("CONTROL-CLIENT-NUM")
	newMinLatencyCol := dataframe.NewColumn("MIN-LATENCY-MS")
	newAvgLatencyCol := dataframe.NewColumn("AVG-LATENCY-MS")
	newMaxLatencyCol := dataframe.NewColumn("MAX-LATENCY-MS")
	newAvgThroughputCol := dataframe.NewColumn("AVG-THROUGHPUT")
	for i := int64(0); i < expectedRowN; i++ {
		second := data.benchMetrics.frontUnixSecond + i
		newSecondCol.PushBack(dataframe.NewStringValue(second))

		v, ok := sec2Data[second]
		if !ok {
			// fill-in missing rows with closest row
			closest := findClosest(second, sec2Data)
			newControlClientNumCol.PushBack(dataframe.NewStringValue(closest.clientN))
			newMinLatencyCol.PushBack(dataframe.NewStringValue(0.0))
			newAvgLatencyCol.PushBack(dataframe.NewStringValue(0.0))
			newMaxLatencyCol.PushBack(dataframe.NewStringValue(0.0))
			newAvgThroughputCol.PushBack(dataframe.NewStringValue(0))
			continue
		}

		newControlClientNumCol.PushBack(dataframe.NewStringValue(v.clientN))
		newMinLatencyCol.PushBack(dataframe.NewStringValue(v.minLat))
		newAvgLatencyCol.PushBack(dataframe.NewStringValue(v.avgLat))
		newMaxLatencyCol.PushBack(dataframe.NewStringValue(v.maxLat))
		newAvgThroughputCol.PushBack(dataframe.NewStringValue(v.throughput))
	}

	df := dataframe.New()
	if err = df.AddColumn(newSecondCol); err != nil {
		return err
	}
	if err = df.AddColumn(newControlClientNumCol); err != nil {
		return err
	}
	if err = df.AddColumn(newMinLatencyCol); err != nil {
		return err
	}
	if err = df.AddColumn(newAvgLatencyCol); err != nil {
		return err
	}
	if err = df.AddColumn(newMaxLatencyCol); err != nil {
		return err
	}
	if err = df.AddColumn(newAvgThroughputCol); err != nil {
		return err
	}

	data.benchMetrics.frame = df
	return
}

type rowData struct {
	clientN    int64
	minLat     float64
	avgLat     float64
	maxLat     float64
	throughput float64
}

func findClosest(second int64, sec2Data map[int64]rowData) rowData {
	v, ok := sec2Data[second]
	if ok {
		return v
	}
	var min int64
	var max int64
	for k := range sec2Data {
		if min == 0 || min > k {
			min = k
		}
		if max == 0 || max < k {
			max = k
		}
	}
	r, ok := _findClosestLower(second, sec2Data, min, max)
	if ok {
		return r
	}
	r, ok = _findClosestUpper(second, sec2Data, min, max)
	if !ok {
		panic(fmt.Errorf("something wrong with benchmark data... too many data points are missing"))
	}
	return r
}

func _findClosestUpper(second int64, sec2Data map[int64]rowData, min, max int64) (rowData, bool) {
	if second < min || second > max {
		return rowData{}, false
	}
	v, ok := sec2Data[second]
	if ok {
		return v, true
	}
	return _findClosestUpper(second+1, sec2Data, min, max)
}

func _findClosestLower(second int64, sec2Data map[int64]rowData, min, max int64) (rowData, bool) {
	if second < min || second > max {
		return rowData{}, false
	}
	v, ok := sec2Data[second]
	if ok {
		return v, true
	}
	return _findClosestLower(second-1, sec2Data, min, max)
}


================================================
FILE: analyze/04_aggregate_all_analyze_data.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package analyze

import (
	"fmt"
	"strings"

	"github.com/etcd-io/dbtester"

	humanize "github.com/dustin/go-humanize"
	"github.com/gyuho/dataframe"
)

// aggregateAll aggregates all system metrics from 3+ nodes.
func (data *analyzeData) aggregateAll(memoryByKeyPath string, readBytesDeltaByKeyPath string, writeBytesDeltaByKeyPath string, totalRequests int64) error {
	colSys, err := data.sysAgg.Column("UNIX-SECOND")
	if err != nil {
		return err
	}
	colBench, err := data.benchMetrics.frame.Column("UNIX-SECOND")
	if err != nil {
		return err
	}

	fv, ok := colBench.FrontNonNil()
	if !ok {
		return fmt.Errorf("FrontNonNil %s has empty Unix time %v", data.benchMetrics.filePath, fv)
	}
	sysStartIdx, ok := colSys.FindFirst(fv)
	if !ok {
		return fmt.Errorf("%v is not found in system metrics results", fv)
	}

	bv, ok := colBench.BackNonNil()
	if !ok {
		return fmt.Errorf("BackNonNil %s has empty Unix time %v", data.benchMetrics.filePath, fv)
	}
	sysEndIdx, ok := colSys.FindFirst(bv)
	if !ok {
		return fmt.Errorf("%v is not found in system metrics results", fv)
	}

	expectedSysRowN := sysEndIdx - sysStartIdx + 1

	var minBenchEndIdx int
	for _, col := range data.benchMetrics.frame.Columns() {
		if minBenchEndIdx == 0 {
			minBenchEndIdx = col.Count()
		}
		if minBenchEndIdx > col.Count() {
			minBenchEndIdx = col.Count()
		}
	}
	// this is index, so decrement by 1 to make it as valid index
	minBenchEndIdx--

	// sysStartIdx 3, sysEndIdx 9, expectedSysRowN 7, minBenchEndIdx 5 (5+1 < 7)
	// so benchmark has 6 rows, but system metrics has 7 rows; benchmark is short of rows
	// so we should keep system metrics [3, 9)
	// THEN sysEndIdx = 3 + 5 = 8 (keep [3, 8+1))
	//
	// sysStartIdx 3, sysEndIdx 7, expectedSysRowN 5, minBenchEndIdx 5 (5+1 > 5)
	// so benchmark has 6 rows, but system metrics has 5 rows; system metrics is short of rows
	// so we should keep benchmark [0, 5)
	// THEN minBenchEndIdx = 7 - 3 = 4 (keep [0, 4+1))
	if minBenchEndIdx+1 < expectedSysRowN {
		// benchmark is short of rows
		// adjust system metrics rows to benchmark-metrics
		// will truncate front of system metrics rows
		sysEndIdx = sysStartIdx + minBenchEndIdx
	} else {
		// system metrics is short of rows
		// adjust benchmark metrics to system-metrics
		// will truncate front of benchmark metrics rows
		minBenchEndIdx = sysEndIdx - sysStartIdx
	}

	// aggregate all system-metrics and benchmark-metrics
	data.aggregated = dataframe.New()

	// first, add bench metrics data
	// UNIX-SECOND, MIN-LATENCY-MS, AVG-LATENCY-MS, MAX-LATENCY-MS, AVG-THROUGHPUT
	for _, col := range data.benchMetrics.frame.Columns() {
		// ALWAYS KEEP FROM FIRST ROW OF BENCHMARKS
		// keeps from [a, b)
		if err = col.Keep(0, minBenchEndIdx+1); err != nil {
			return err
		}
		if err = data.aggregated.AddColumn(col); err != nil {
			return err
		}
	}
	for _, col := range data.sysAgg.Columns() {
		if col.Header() == "UNIX-SECOND" {
			continue
		}
		if err = col.Keep(sysStartIdx, sysEndIdx+1); err != nil {
			return err
		}
		if err = data.aggregated.AddColumn(col); err != nil {
			return err
		}
	}

	var (
		requestSum              int
		cumulativeThroughputCol = dataframe.NewColumn("CUMULATIVE-THROUGHPUT") // from AVG-THROUGHPUT

		sampleSize = float64(len(data.sys))

		avgClientNumCol             = dataframe.NewColumn("AVG-CLIENT-NUM")                  // from CLIENT-NUM
		avgVolCtxSwitchCol          = dataframe.NewColumn("AVG-VOLUNTARY-CTXT-SWITCHES")     // from VOLUNTARY-CTXT-SWITCHES
		avgNonVolCtxSwitchCol       = dataframe.NewColumn("AVG-NON-VOLUNTARY-CTXT-SWITCHES") // from NON-VOLUNTARY-CTXT-SWITCHES
		avgCPUCol                   = dataframe.NewColumn("AVG-CPU")                         // from CPU-NUM
		maxCPUCol                   = dataframe.NewColumn("MAX-CPU")                         // from CPU-NUM
		avgSystemLoadCol            = dataframe.NewColumn("AVG-SYSTEM-LOAD-1-MIN")           // from LOAD-AVERAGE-1-MINUTE
		avgVMRSSMBCol               = dataframe.NewColumn("AVG-VMRSS-MB")                    // from VMRSS-NUM
		avgReadsCompletedCol        = dataframe.NewColumn("AVG-READS-COMPLETED")             // from READS-COMPLETED
		avgReadsCompletedDeltaCol   = dataframe.NewColumn("AVG-READS-COMPLETED-DELTA")       // from READS-COMPLETED-DELTA
		avgSectorsReadCol           = dataframe.NewColumn("AVG-SECTORS-READ")                // from SECTORS-READ
		avgSectorsReadDeltaCol      = dataframe.NewColumn("AVG-SECTORS-READ-DELTA")          // from SECTORS-READ-DELTA
		avgWritesCompletedCol       = dataframe.NewColumn("AVG-WRITES-COMPLETED")            // from WRITES-COMPLETED
		avgWritesCompletedDeltaCol  = dataframe.NewColumn("AVG-WRITES-COMPLETED-DELTA")      // from WRITES-COMPLETED-DELTA
		avgSectorsWrittenCol        = dataframe.NewColumn("AVG-SECTORS-WRITTEN")             // from SECTORS-WRITTEN
		avgSectorsWrittenDeltaCol   = dataframe.NewColumn("AVG-SECTORS-WRITTEN-DELTA")       // from SECTORS-WRITTEN-DELTA
		avgReadBytesNumDeltaCol     = dataframe.NewColumn("AVG-READ-BYTES-NUM-DELTA")        // from READ-BYTES-DELTA
		avgWriteBytesNumDeltaCol    = dataframe.NewColumn("AVG-WRITE-BYTES-NUM-DELTA")       // from WRITE-BYTES-DELTA
		avgReceiveBytesNumCol       = dataframe.NewColumn("AVG-RECEIVE-BYTES-NUM")           // from RECEIVE-BYTES-NUM
		avgReceiveBytesNumDeltaCol  = dataframe.NewColumn("AVG-RECEIVE-BYTES-NUM-DELTA")     // from RECEIVE-BYTES-NUM-DELTA
		avgTransmitBytesNumCol      = dataframe.NewColumn("AVG-TRANSMIT-BYTES-NUM")          // from TRANSMIT-BYTES-NUM
		avgTransmitBytesNumDeltaCol = dataframe.NewColumn("AVG-TRANSMIT-BYTES-NUM-DELTA")    // from TRANSMIT-BYTES-NUM-DELTA
	)

	sec2minVMRSSMB := make(map[int64]float64)
	sec2maxVMRSSMB := make(map[int64]float64)

	// compute average value of 3+ nodes
	// by iterating each row (horizontally) for all the columns
	for rowIdx := 0; rowIdx < minBenchEndIdx+1; rowIdx++ {
		var (
			clientNumSum             float64
			volCtxSwitchSum          float64
			nonVolCtxSwitchSum       float64
			cpuSum                   float64
			cpuMax                   float64
			loadAvgSum               float64
			vmrssMBSum               float64
			readsCompletedSum        float64
			readsCompletedDeltaSum   float64
			sectorsReadSum           float64
			sectorsReadDeltaSum      float64
			writesCompletedSum       float64
			writesCompletedDeltaSum  float64
			sectorsWrittenSum        float64
			sectorsWrittenDeltaSum   float64
			readBytesDeltaSum        float64
			writeBytesDeltaSum       float64
			receiveBytesNumSum       float64
			receiveBytesNumDeltaSum  float64
			transmitBytesNumSum      float64
			transmitBytesNumDeltaSum float64
		)
		sc, err := data.aggregated.Column("UNIX-SECOND")
		if err != nil {
			return err
		}
		for _, col := range data.aggregated.Columns() {
			rv, err := col.Value(rowIdx)
			if err != nil {
				return err
			}
			vv, _ := rv.Float64()

			hd := col.Header()
			switch {
			// cumulative values
			case hd == "AVG-THROUGHPUT":
				requestSum += int(vv)
				cumulativeThroughputCol.PushBack(dataframe.NewStringValue(requestSum))

			// average values (need sume first!)
			case strings.HasPrefix(hd, "CLIENT-NUM-"):
				clientNumSum += vv
			case strings.HasPrefix(hd, "VOLUNTARY-CTXT-SWITCHES-"):
				volCtxSwitchSum += vv
			case strings.HasPrefix(hd, "NON-VOLUNTARY-CTXT-SWITCHES-"):
				nonVolCtxSwitchSum += vv
			case strings.HasPrefix(hd, "CPU-"): // CPU-NUM was converted to CPU-1, CPU-2, CPU-3
				cpuSum += vv
				if cpuMax == 0.0 || cpuMax < vv {
					cpuMax = vv
				}
			case strings.HasPrefix(hd, "LOAD-AVERAGE-1-"): // LOAD-AVERAGE-1-MINUTE
				loadAvgSum += vv
			case strings.HasPrefix(hd, "VMRSS-MB-"): // VMRSS-NUM-NUM was converted to VMRSS-MB-1, VMRSS-MB-2, VMRSS-MB-3
				vmrssMBSum += vv

				svv, err := sc.Value(rowIdx)
				if err != nil {
					return err
				}
				ts, _ := svv.Int64()

				if v, ok := sec2minVMRSSMB[ts]; !ok {
					sec2minVMRSSMB[ts] = vv
				} else if v > vv || (v == 0.0 && vv != 0.0) {
					sec2minVMRSSMB[ts] = vv
				}
				if v, ok := sec2maxVMRSSMB[ts]; !ok {
					sec2maxVMRSSMB[ts] = vv
				} else if v < vv {
					sec2maxVMRSSMB[ts] = vv
				}

			case strings.HasPrefix(hd, "READS-COMPLETED-DELTA-"): // match this first!
				readsCompletedDeltaSum += vv
			case strings.HasPrefix(hd, "READS-COMPLETED-"):
				readsCompletedSum += vv
			case strings.HasPrefix(hd, "SECTORS-READ-DELTA-"):
				sectorsReadDeltaSum += vv
			case strings.HasPrefix(hd, "SECTORS-READ-"):
				sectorsReadSum += vv
			case strings.HasPrefix(hd, "WRITES-COMPLETED-DELTA-"):
				writesCompletedDeltaSum += vv
			case strings.HasPrefix(hd, "WRITES-COMPLETED-"):
				writesCompletedSum += vv
			case strings.HasPrefix(hd, "SECTORS-WRITTEN-DELTA-"):
				sectorsWrittenDeltaSum += vv
			case strings.HasPrefix(hd, "SECTORS-WRITTEN-"):
				sectorsWrittenSum += vv
			case strings.HasPrefix(hd, "READ-BYTES-DELTA-"):
				readBytesDeltaSum += vv
			case strings.HasPrefix(hd, "WRITE-BYTES-DELTA-"):
				writeBytesDeltaSum += vv
			case strings.HasPrefix(hd, "RECEIVE-BYTES-NUM-DELTA-"):
				receiveBytesNumDeltaSum += vv
			case strings.HasPrefix(hd, "RECEIVE-BYTES-NUM-"):
				receiveBytesNumSum += vv
			case strings.HasPrefix(hd, "TRANSMIT-BYTES-NUM-DELTA-"):
				transmitBytesNumDeltaSum += vv
			case strings.HasPrefix(hd, "TRANSMIT-BYTES-NUM-"):
				transmitBytesNumSum += vv
			}
		}

		avgClientNumCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", clientNumSum/sampleSize)))
		avgVolCtxSwitchCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", volCtxSwitchSum/sampleSize)))
		avgNonVolCtxSwitchCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", nonVolCtxSwitchSum/sampleSize)))
		avgCPUCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", cpuSum/sampleSize)))
		maxCPUCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", cpuMax)))
		avgSystemLoadCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", loadAvgSum/sampleSize)))
		avgVMRSSMBCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", vmrssMBSum/sampleSize)))
		avgReadsCompletedCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", readsCompletedSum/sampleSize)))
		avgReadsCompletedDeltaCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", readsCompletedDeltaSum/sampleSize)))
		avgSectorsReadCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", sectorsReadSum/sampleSize)))
		avgSectorsReadDeltaCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", sectorsReadDeltaSum/sampleSize)))
		avgWritesCompletedCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", writesCompletedSum/sampleSize)))
		avgWritesCompletedDeltaCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", writesCompletedDeltaSum/sampleSize)))
		avgSectorsWrittenCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", sectorsWrittenSum/sampleSize)))
		avgSectorsWrittenDeltaCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", sectorsWrittenDeltaSum/sampleSize)))
		avgReadBytesNumDeltaCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", readBytesDeltaSum/sampleSize)))
		avgWriteBytesNumDeltaCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", writeBytesDeltaSum/sampleSize)))
		avgReceiveBytesNumCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", receiveBytesNumSum/sampleSize)))
		avgReceiveBytesNumDeltaCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", receiveBytesNumDeltaSum/sampleSize)))
		avgTransmitBytesNumCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", transmitBytesNumSum/sampleSize)))
		avgTransmitBytesNumDeltaCol.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", transmitBytesNumDeltaSum/sampleSize)))
	}

	// add all cumulative, average columns
	if err = data.aggregated.AddColumn(cumulativeThroughputCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgClientNumCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgVolCtxSwitchCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgNonVolCtxSwitchCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgCPUCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(maxCPUCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgSystemLoadCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgVMRSSMBCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgReadsCompletedCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgReadsCompletedDeltaCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgSectorsReadCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgSectorsReadDeltaCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgWritesCompletedCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgWritesCompletedDeltaCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgSectorsWrittenCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgSectorsWrittenDeltaCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgReadBytesNumDeltaCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgWriteBytesNumDeltaCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgReceiveBytesNumCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgReceiveBytesNumDeltaCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgTransmitBytesNumCol); err != nil {
		return err
	}
	if err = data.aggregated.AddColumn(avgTransmitBytesNumDeltaCol); err != nil {
		return err
	}

	// add SECOND column
	uc, err := data.aggregated.Column("UNIX-SECOND")
	if err != nil {
		return err
	}
	secondCol := dataframe.NewColumn("SECOND")
	for i := 0; i < uc.Count(); i++ {
		secondCol.PushBack(dataframe.NewStringValue(i))
	}
	if err = data.aggregated.AddColumn(secondCol); err != nil {
		return err
	}
	// move to 2th column
	if err = data.aggregated.MoveColumn("SECOND", 1); err != nil {
		return err
	}
	// move to 3th column
	if err = data.aggregated.MoveColumn("CONTROL-CLIENT-NUM", 2); err != nil {
		return err
	}
	// move to 3th column
	if err = data.aggregated.MoveColumn("AVG-CLIENT-NUM", 2); err != nil {
		return err
	}
	// move to 6th column
	if err = data.aggregated.MoveColumn("AVG-THROUGHPUT", 5); err != nil {
		return err
	}

	// currently first columns are ordered as:
	// UNIX-SECOND, SECOND, AVG-CLIENT-NUM, MIN-LATENCY-MS, AVG-LATENCY-MS, MAX-LATENCY-MS, AVG-THROUGHPUT
	//
	// re-order columns in the following order, to make it more readable
	reorder := []string{
		"CUMULATIVE-THROUGHPUT",
		"AVG-CPU",
		"MAX-CPU",
		"AVG-SYSTEM-LOAD-1-MIN",
		"AVG-VMRSS-MB",
		"AVG-WRITES-COMPLETED",
		"AVG-WRITES-COMPLETED-DELTA",
		"AVG-SECTORS-WRITTEN",
		"AVG-SECTORS-WRITTEN-DELTA",
		"AVG-READS-COMPLETED",
		"AVG-READS-COMPLETED-DELTA",
		"AVG-SECTORS-READ",
		"AVG-SECTORS-READ-DELTA",
		"AVG-READ-BYTES-NUM-DELTA",
		"AVG-WRITE-BYTES-NUM-DELTA",
		"AVG-RECEIVE-BYTES-NUM",
		"AVG-RECEIVE-BYTES-NUM-DELTA",
		"AVG-TRANSMIT-BYTES-NUM",
		"AVG-TRANSMIT-BYTES-NUM-DELTA",
		"AVG-VOLUNTARY-CTXT-SWITCHES",
		"AVG-NON-VOLUNTARY-CTXT-SWITCHES",
	}
	// move to 9th
	for i := len(reorder) - 1; i >= 0; i-- {
		if err = data.aggregated.MoveColumn(reorder[i], 8); err != nil {
			return err
		}
	}

	for _, col := range data.aggregated.Columns() {
		// since we will have same headers from different databases
		col.UpdateHeader(makeHeader(col.Header(), data.databaseTag))
	}

	// aggregate memory usage by number of keys
	colUnixSecond, err := data.aggregated.Column("UNIX-SECOND")
	if err != nil {
		return err
	}
	colMemoryMB, err := data.aggregated.Column("AVG-VMRSS-MB")
	if err != nil {
		return err
	}
	colAvgThroughput, err := data.aggregated.Column("AVG-THROUGHPUT")
	if err != nil {
		return err
	}
	colReadBytesNumDelta, err := data.aggregated.Column("AVG-READ-BYTES-NUM-DELTA")
	if err != nil {
		return err
	}
	colWriteBytesNumDelta, err := data.aggregated.Column("AVG-WRITE-BYTES-NUM-DELTA")
	if err != nil {
		return err
	}
	if colUnixSecond.Count() != colMemoryMB.Count() {
		return fmt.Errorf("SECOND column count %d, AVG-VMRSS-MB column count %d", colUnixSecond.Count(), colMemoryMB.Count())
	}
	if colAvgThroughput.Count() != colMemoryMB.Count() {
		return fmt.Errorf("AVG-THROUGHPUT column count %d, AVG-VMRSS-MB column count %d", colAvgThroughput.Count(), colMemoryMB.Count())
	}
	if colUnixSecond.Count() != colAvgThroughput.Count() {
		return fmt.Errorf("SECOND column count %d, AVG-THROUGHPUT column count %d", colUnixSecond.Count(), colAvgThroughput.Count())
	}
	if colReadBytesNumDelta.Count() != colAvgThroughput.Count() {
		return fmt.Errorf("AVG-READ-BYTES-NUM-DELTA column count %d, AVG-THROUGHPUT column count %d", colReadBytesNumDelta.Count(), colAvgThroughput.Count())
	}
	if colWriteBytesNumDelta.Count() != colAvgThroughput.Count() {
		return fmt.Errorf("AVG-WRITE-BYTES-NUM-DELTA column count %d, AVG-THROUGHPUT column count %d", colWriteBytesNumDelta.Count(), colAvgThroughput.Count())
	}

	var cdata []dbtester.CumulativeKeyNumAndOtherData
	for i := 0; i < colUnixSecond.Count(); i++ {
		vv0, err := colUnixSecond.Value(i)
		if err != nil {
			return err
		}
		v0, _ := vv0.Int64()

		vv1, err := colMemoryMB.Value(i)
		if err != nil {
			return err
		}
		vf1, _ := vv1.Float64()

		vv2, err := colAvgThroughput.Value(i)
		if err != nil {
			return err
		}
		vf2, _ := vv2.Float64()

		vv3, err := colReadBytesNumDelta.Value(i)
		if err != nil {
			return err
		}
		vf3, _ := vv3.Float64()

		vv4, err := colWriteBytesNumDelta.Value(i)
		if err != nil {
			return err
		}
		vf4, _ := vv4.Float64()

		point := dbtester.CumulativeKeyNumAndOtherData{
			UnixSecond: v0,
			Throughput: int64(vf2),

			MinMemoryMB: sec2minVMRSSMB[v0],
			AvgMemoryMB: vf1,
			MaxMemoryMB: sec2maxVMRSSMB[v0],

			AvgReadBytesDelta:  vf3,
			AvgWriteBytesDelta: vf4,
		}
		cdata = append(cdata, point)
	}

	// aggregate memory,write/read bytes by number of keys
	knms := dbtester.FindRangesData(cdata, 1000, totalRequests)

	ckk1 := dataframe.NewColumn("KEYS")
	ckk2 := dataframe.NewColumn("MIN-VMRSS-MB")
	ckk3 := dataframe.NewColumn("AVG-VMRSS-MB")
	ckk4 := dataframe.NewColumn("MAX-VMRSS-MB")
	ckk5 := dataframe.NewColumn("AVG-READ-BYTES-NUM-DELTA")
	ckk6 := dataframe.NewColumn("AVG-READ-BYTES")
	ckk7 := dataframe.NewColumn("AVG-WRITE-BYTES-NUM-DELTA")
	ckk8 := dataframe.NewColumn("AVG-WRITE-BYTES")
	for i := range knms {
		ckk1.PushBack(dataframe.NewStringValue(knms[i].CumulativeKeyNum))
		ckk2.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", knms[i].MinMemoryMB)))
		ckk3.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", knms[i].AvgMemoryMB)))
		ckk4.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", knms[i].MaxMemoryMB)))
		ckk5.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", knms[i].AvgReadBytesDelta)))
		ckk6.PushBack(dataframe.NewStringValue(humanize.Bytes(uint64(knms[i].AvgReadBytesDelta))))
		ckk7.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.2f", knms[i].AvgWriteBytesDelta)))
		ckk8.PushBack(dataframe.NewStringValue(humanize.Bytes(uint64(knms[i].AvgWriteBytesDelta))))
	}

	fr1 := dataframe.New()
	if err := fr1.AddColumn(ckk1); err != nil {
		panic(err)
	}
	if err := fr1.AddColumn(ckk2); err != nil {
		panic(err)
	}
	if err := fr1.AddColumn(ckk3); err != nil {
		panic(err)
	}
	if err := fr1.AddColumn(ckk4); err != nil {
		panic(err)
	}
	if err := fr1.CSV(memoryByKeyPath); err != nil {
		panic(err)
	}

	// aggregate read bytes by number of keys
	fr2 := dataframe.New()
	if err := fr2.AddColumn(ckk1); err != nil {
		panic(err)
	}
	if err := fr2.AddColumn(ckk5); err != nil {
		panic(err)
	}
	if err := fr2.AddColumn(ckk6); err != nil {
		panic(err)
	}
	if err := fr2.CSV(readBytesDeltaByKeyPath); err != nil {
		panic(err)
	}

	// aggregate write bytes by number of keys
	fr3 := dataframe.New()
	if err := fr3.AddColumn(ckk1); err != nil {
		panic(err)
	}
	if err := fr3.AddColumn(ckk7); err != nil {
		panic(err)
	}
	if err := fr3.AddColumn(ckk8); err != nil {
		panic(err)
	}
	if err := fr3.CSV(writeBytesDeltaByKeyPath); err != nil {
		panic(err)
	}

	return nil
}

func (data *analyzeData) save() error {
	return data.aggregated.CSV(data.allAggregatedOutputPath)
}


================================================
FILE: analyze/05_plot.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package analyze

import (
	"fmt"

	"github.com/etcd-io/dbtester/dbtesterpb"

	"github.com/gyuho/dataframe"
	"gonum.org/v1/plot"
	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/plotutil"
	"gonum.org/v1/plot/vg"
)

var (
	plotWidth  = 12 * vg.Inch
	plotHeight = 8 * vg.Inch
)

func init() {
	plot.DefaultFont = "Helvetica"
	plotter.DefaultLineStyle.Width = vg.Points(1.5)
	plotter.DefaultGlyphStyle.Radius = vg.Points(2.0)
}

type pair struct {
	x dataframe.Column
	y dataframe.Column
}

type triplet struct {
	x      dataframe.Column
	minCol dataframe.Column
	avgCol dataframe.Column
	maxCol dataframe.Column
}

func (all *allAggregatedData) draw(cfg dbtesterpb.ConfigAnalyzeMachinePlot, pairs ...pair) error {
	// frame now contains
	// AVG-LATENCY-MS-etcd-v3.1-go1.7.4, AVG-LATENCY-MS-zookeeper-r3.4.9-java8, AVG-LATENCY-MS-consul-v0.7.2-go1.7.4
	plt, err := plot.New()
	if err != nil {
		return err
	}
	plt.Title.Text = fmt.Sprintf("%s, %s", all.title, cfg.YAxis)
	plt.X.Label.Text = cfg.XAxis
	plt.Y.Label.Text = cfg.YAxis
	plt.Legend.Top = true

	var ps []plot.Plotter
	for i, p := range pairs {
		pt, err := points(p.y)
		if err != nil {
			return err
		}

		l, err := plotter.NewLine(pt)
		if err != nil {
			return err
		}
		l.Color = dbtesterpb.GetRGBI(all.headerToDatabaseID[p.y.Header()], i)
		l.Dashes = plotutil.Dashes(i)
		ps = append(ps, l)

		plt.Legend.Add(all.headerToDatabaseDescription[p.y.Header()], l)
	}
	plt.Add(ps...)

	for _, outputPath := range cfg.OutputPathList {
		if err = plt.Save(plotWidth, plotHeight, outputPath); err != nil {
			return err
		}
	}
	return nil
}

func (all *allAggregatedData) drawXY(cfg dbtesterpb.ConfigAnalyzeMachinePlot, pairs ...pair) error {
	// frame now contains
	// KEYS-DB-TAG-X, AVG-LATENCY-MS-DB-TAG-Y, ...
	plt, err := plot.New()
	if err != nil {
		return err
	}
	plt.Title.Text = fmt.Sprintf("%s, %s", all.title, cfg.YAxis)
	plt.X.Label.Text = cfg.XAxis
	plt.Y.Label.Text = cfg.YAxis
	plt.Legend.Top = true

	var ps []plot.Plotter
	for i, p := range pairs {
		pt, err := pointsXY(p.x, p.y)
		if err != nil {
			return err
		}

		l, err := plotter.NewLine(pt)
		if err != nil {
			return err
		}
		l.Color = dbtesterpb.GetRGBI(all.headerToDatabaseID[p.y.Header()], i)
		l.Dashes = plotutil.Dashes(i)
		ps = append(ps, l)

		plt.Legend.Add(all.headerToDatabaseDescription[p.y.Header()], l)
	}
	plt.Add(ps...)

	for _, outputPath := range cfg.OutputPathList {
		if err = plt.Save(plotWidth, plotHeight, outputPath); err != nil {
			return err
		}
	}
	return nil
}

func (all *allAggregatedData) drawXYWithErrorPoints(cfg dbtesterpb.ConfigAnalyzeMachinePlot, triplets ...triplet) error {
	// frame now contains
	// KEYS-DB-TAG-X, MIN-LATENCY-MS-DB-TAG-Y, AVG-LATENCY-MS-DB-TAG-Y, MAX-LATENCY-MS-DB-TAG-Y, ...
	plt, err := plot.New()
	if err != nil {
		return err
	}
	plt.Title.Text = fmt.Sprintf("%s, %s", all.title, cfg.YAxis)
	plt.X.Label.Text = cfg.XAxis
	plt.Y.Label.Text = cfg.YAxis
	plt.Legend.Top = true

	var ps []plot.Plotter
	for i, triplet := range triplets {
		{
			pt, err := pointsXY(triplet.x, triplet.minCol)
			if err != nil {
				return err
			}
			l, err := plotter.NewLine(pt)
			if err != nil {
				return err
			}
			l.Color = dbtesterpb.GetRGBII(all.headerToDatabaseID[triplet.avgCol.Header()], i)
			l.Dashes = plotutil.Dashes(i)
			ps = append(ps, l)
			plt.Legend.Add(all.headerToDatabaseDescription[triplet.avgCol.Header()]+" MIN", l)
		}
		{
			pt, err := pointsXY(triplet.x, triplet.avgCol)
			if err != nil {
				return err
			}
			l, err := plotter.NewLine(pt)
			if err != nil {
				return err
			}
			l.Color = dbtesterpb.GetRGBI(all.headerToDatabaseID[triplet.avgCol.Header()], i)
			l.Dashes = plotutil.Dashes(i)
			ps = append(ps, l)
			plt.Legend.Add(all.headerToDatabaseDescription[triplet.avgCol.Header()], l)
		}
		{
			pt, err := pointsXY(triplet.x, triplet.maxCol)
			if err != nil {
				return err
			}
			l, err := plotter.NewLine(pt)
			if err != nil {
				return err
			}
			l.Color = dbtesterpb.GetRGBIII(all.headerToDatabaseID[triplet.avgCol.Header()], i)
			l.Dashes = plotutil.Dashes(i)
			ps = append(ps, l)
			plt.Legend.Add(all.headerToDatabaseDescription[triplet.avgCol.Header()]+" MAX", l)
		}
	}
	plt.Add(ps...)

	for _, outputPath := range cfg.OutputPathList {
		if err = plt.Save(plotWidth, plotHeight, outputPath); err != nil {
			return err
		}
	}
	return nil
}

func points(col dataframe.Column) (plotter.XYs, error) {
	bv, ok := col.BackNonNil()
	if !ok {
		return nil, fmt.Errorf("BackNonNil not found")
	}
	rowN, ok := col.FindLast(bv)
	if !ok {
		return nil, fmt.Errorf("not found %v", bv)
	}
	pts := make(plotter.XYs, rowN)
	for i := range pts {
		v, err := col.Value(i)
		if err != nil {
			return nil, err
		}
		n, _ := v.Float64()
		pts[i].X = float64(i)
		pts[i].Y = n
	}
	return pts, nil
}

func pointsXY(colX, colY dataframe.Column) (plotter.XYs, error) {
	bv, ok := colX.BackNonNil()
	if !ok {
		return nil, fmt.Errorf("BackNonNil not found")
	}
	rowN, ok := colX.FindLast(bv)
	if !ok {
		return nil, fmt.Errorf("not found %v", bv)
	}
	pts := make(plotter.XYs, rowN)
	for i := range pts {
		vx, err := colX.Value(i)
		if err != nil {
			return nil, err
		}
		x, _ := vx.Float64()

		vy, err := colY.Value(i)
		if err != nil {
			return nil, err
		}
		y, _ := vy.Float64()

		pts[i].X = x
		pts[i].Y = y
	}
	return pts, nil
}


================================================
FILE: analyze/command.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package analyze

import (
	"bytes"
	"encoding/csv"
	"fmt"
	"path/filepath"
	"reflect"
	"sort"
	"strconv"
	"strings"

	"github.com/etcd-io/dbtester"
	"github.com/etcd-io/dbtester/dbtesterpb"

	humanize "github.com/dustin/go-humanize"
	"github.com/gyuho/dataframe"
	"github.com/olekukonko/tablewriter"
	"github.com/spf13/cobra"
)

// Command implements 'analyze' command.
var Command = &cobra.Command{
	Use:   "analyze",
	Short: "Analyzes test dbtester test results.",
	RunE:  commandFunc,
}

var configPath string

func init() {
	Command.PersistentFlags().StringVarP(&configPath, "config", "c", "", "YAML configuration file path.")
}

func commandFunc(cmd *cobra.Command, args []string) error {
	return do(configPath)
}

type allAggregatedData struct {
	title                       string
	data                        []*analyzeData
	headerToDatabaseID          map[string]string
	headerToDatabaseDescription map[string]string
	allDatabaseIDList           []string
}

func do(configPath string) error {
	cfg, err := dbtester.ReadConfig(configPath, true)
	if err != nil {
		return err
	}

	all := &allAggregatedData{
		title:                       cfg.TestTitle,
		data:                        make([]*analyzeData, 0, len(cfg.DatabaseIDToConfigAnalyzeMachineInitial)),
		headerToDatabaseID:          make(map[string]string),
		headerToDatabaseDescription: make(map[string]string),
		allDatabaseIDList:           cfg.AllDatabaseIDList,
	}
	for _, databaseID := range cfg.AllDatabaseIDList {
		testgroup := cfg.DatabaseIDToConfigClientMachineAgentControl[databaseID]
		testdata := cfg.DatabaseIDToConfigAnalyzeMachineInitial[databaseID]

		lg.Sugar().Info("reading system metrics data for %s", databaseID)
		ad, err := readSystemMetricsAll(testdata.ServerSystemMetricsInterpolatedPathList...)
		if err != nil {
			return err
		}
		ad.databaseTag = testgroup.DatabaseTag
		ad.legend = testgroup.DatabaseDescription
		ad.allAggregatedOutputPath = testdata.AllAggregatedOutputPath

		if err = ad.aggSystemMetrics(); err != nil {
			return err
		}
		if err = ad.importBenchMetrics(testdata.ClientLatencyThroughputTimeseriesPath); err != nil {
			return err
		}
		if err = ad.aggregateAll(testdata.ServerMemoryByKeyNumberPath, testdata.ServerReadBytesDeltaByKeyNumberPath, testdata.ServerWriteBytesDeltaByKeyNumberPath, testgroup.ConfigClientMachineBenchmarkOptions.RequestNumber); err != nil {
			return err
		}
		if err = ad.save(); err != nil {
			return err
		}

		all.data = append(all.data, ad)
		for _, hd := range ad.aggregated.Headers() {
			all.headerToDatabaseID[makeHeader(hd, testgroup.DatabaseTag)] = databaseID
			all.headerToDatabaseDescription[makeHeader(hd, testgroup.DatabaseTag)] = testgroup.DatabaseDescription
		}
	}

	// aggregated everything
	// 1. sum of all network usage per database
	// 2. throughput, latency percentiles distribution
	//
	// FIRST ROW FOR HEADER: etcd, Zookeeper, Consul, ...
	// FIRST COLUMN FOR LABELS: READS-COMPLETED-DELTA, ...
	// SECOND COLUMNS ~ FOR DATA
	row00Header := []string{""} // first is empty
	for _, ad := range all.data {
		// per database
		for _, col := range ad.aggregated.Columns() {
			databaseID := all.headerToDatabaseID[col.Header()]
			row00Header = append(row00Header, cfg.DatabaseIDToConfigClientMachineAgentControl[databaseID].DatabaseTag)
			break
		}
	}

	row17ServerReceiveBytesSum := []string{"SERVER-TOTAL-NETWORK-RX-DATA-SUM"}
	row17ServerReceiveBytesSumRaw := []string{"SERVER-TOTAL-NETWORK-RX-DATA-BYTES-SUM-RAW"}
	row18ServerTransmitBytesSum := []string{"SERVER-TOTAL-NETWORK-TX-DATA-SUM"}
	row18ServerTransmitBytesSumRaw := []string{"SERVER-TOTAL-NETWORK-TX-DATA-BYTES-SUM-RAW"}
	row21ServerMaxCPUUsage := []string{"SERVER-MAX-CPU-USAGE"}
	row22ServerMaxMemoryUsage := []string{"SERVER-MAX-MEMORY-USAGE"}
	row26ReadsCompletedDeltaSum := []string{"SERVER-AVG-READS-COMPLETED-DELTA-SUM"}
	row27SectorsReadDeltaSum := []string{"SERVER-AVG-SECTORS-READS-DELTA-SUM"}
	row28WritesCompletedDeltaSum := []string{"SERVER-AVG-WRITES-COMPLETED-DELTA-SUM"}
	row29SectorsWrittenDeltaSum := []string{"SERVER-AVG-SECTORS-WRITTEN-DELTA-SUM"}

	// iterate each database's all data
	for _, ad := range all.data {
		// per database
		var (
			readsCompletedDeltaSum   float64
			sectorsReadDeltaSum      float64
			writesCompletedDeltaSum  float64
			sectorsWrittenDeltaSum   float64
			receiveBytesNumDeltaSum  float64
			transmitBytesNumDeltaSum float64
			maxAvgCPU                float64
			maxAvgVMRSSMBs           []float64
		)
		for _, col := range ad.aggregated.Columns() {
			hdr := col.Header()
			switch {
			case strings.HasPrefix(hdr, "RECEIVE-BYTES-NUM-DELTA-"):
				cnt := col.Count()
				for j := 0; j < cnt; j++ {
					vv, err := col.Value(j)
					if err != nil {
						return err
					}
					fv, _ := vv.Float64()
					receiveBytesNumDeltaSum += fv
				}
			case strings.HasPrefix(hdr, "TRANSMIT-BYTES-NUM-DELTA-"):
				cnt := col.Count()
				for j := 0; j < cnt; j++ {
					vv, err := col.Value(j)
					if err != nil {
						return err
					}
					fv, _ := vv.Float64()
					transmitBytesNumDeltaSum += fv
				}
			case strings.HasPrefix(hdr, "READS-COMPLETED-DELTA-"):
				cnt := col.Count()
				for j := 0; j < cnt; j++ {
					vv, err := col.Value(j)
					if err != nil {
						return err
					}
					fv, _ := vv.Float64()
					readsCompletedDeltaSum += fv
				}
			case strings.HasPrefix(hdr, "SECTORS-READS-DELTA-"):
				cnt := col.Count()
				for j := 0; j < cnt; j++ {
					vv, err := col.Value(j)
					if err != nil {
						return err
					}
					fv, _ := vv.Float64()
					sectorsReadDeltaSum += fv
				}
			case strings.HasPrefix(hdr, "WRITES-COMPLETED-DELTA-"):
				cnt := col.Count()
				for j := 0; j < cnt; j++ {
					vv, err := col.Value(j)
					if err != nil {
						return err
					}
					fv, _ := vv.Float64()
					writesCompletedDeltaSum += fv
				}
			case strings.HasPrefix(hdr, "SECTORS-WRITTEN-DELTA-"):
				cnt := col.Count()
				for j := 0; j < cnt; j++ {
					vv, err := col.Value(j)
					if err != nil {
						return err
					}
					fv, _ := vv.Float64()
					sectorsWrittenDeltaSum += fv
				}
			case strings.HasPrefix(hdr, "AVG-CPU-"):
				cnt := col.Count()
				for j := 0; j < cnt; j++ {
					vv, err := col.Value(j)
					if err != nil {
						return err
					}
					fv, _ := vv.Float64()
					maxAvgCPU = maxFloat64(maxAvgCPU, fv)
				}
			case strings.HasPrefix(hdr, "AVG-VMRSS-MB-"):
				cnt := col.Count()
				for j := 0; j < cnt; j++ {
					vv, err := col.Value(j)
					if err != nil {
						return err
					}
					fv, _ := vv.Float64()
					maxAvgVMRSSMBs = append(maxAvgVMRSSMBs, fv)
				}
			}
		}

		row17ServerReceiveBytesSum = append(row17ServerReceiveBytesSum, humanize.Bytes(uint64(receiveBytesNumDeltaSum)))
		row17ServerReceiveBytesSumRaw = append(row17ServerReceiveBytesSumRaw, fmt.Sprintf("%.2f", receiveBytesNumDeltaSum))
		row18ServerTransmitBytesSum = append(row18ServerTransmitBytesSum, humanize.Bytes(uint64(transmitBytesNumDeltaSum)))
		row18ServerTransmitBytesSumRaw = append(row18ServerTransmitBytesSumRaw, fmt.Sprintf("%.2f", transmitBytesNumDeltaSum))
		row21ServerMaxCPUUsage = append(row21ServerMaxCPUUsage, fmt.Sprintf("%.2f %%", maxAvgCPU))
		row26ReadsCompletedDeltaSum = append(row26ReadsCompletedDeltaSum, humanize.Comma(int64(readsCompletedDeltaSum)))
		row27SectorsReadDeltaSum = append(row27SectorsReadDeltaSum, humanize.Comma(int64(sectorsReadDeltaSum)))
		row28WritesCompletedDeltaSum = append(row28WritesCompletedDeltaSum, humanize.Comma(int64(writesCompletedDeltaSum)))
		row29SectorsWrittenDeltaSum = append(row29SectorsWrittenDeltaSum, humanize.Comma(int64(sectorsWrittenDeltaSum)))

		sort.Float64s(maxAvgVMRSSMBs)
		mv := maxAvgVMRSSMBs[len(maxAvgVMRSSMBs)-1]
		mb := uint64(mv * 1000000)
		row22ServerMaxMemoryUsage = append(row22ServerMaxMemoryUsage, humanize.Bytes(mb))
	}

	row01TotalSeconds := []string{"TOTAL-SECONDS"} // TOTAL-SECONDS
	row02TotalRequestNumber := []string{"TOTAL-REQUEST-NUMBER"}
	row03MaxThroughput := []string{"MAX-THROUGHPUT"}                                    // MAX AVG-THROUGHPUT
	row04AverageThroughput := []string{"AVG-THROUGHPUT"}                                // REQUESTS-PER-SECOND
	row05MinThroughput := []string{"MIN-THROUGHPUT"}                                    // MIN AVG-THROUGHPUT
	row06FastestLatency := []string{"FASTEST-LATENCY"}                                  // FASTEST-LATENCY-MS
	row07AverageLatency := []string{"AVG-LATENCY"}                                      // AVERAGE-LATENCY-MS
	row08SlowestLatency := []string{"SLOWEST-LATENCY"}                                  // SLOWEST-LATENCY-MS
	row09p10 := []string{"Latency p10"}                                                 // p10
	row10p25 := []string{"Latency p25"}                                                 // p25
	row11p50 := []string{"Latency p50"}                                                 // p50
	row12p75 := []string{"Latency p75"}                                                 // p75
	row13p90 := []string{"Latency p90"}                                                 // p90
	row14p95 := []string{"Latency p95"}                                                 // p95
	row15p99 := []string{"Latency p99"}                                                 // p99
	row16p999 := []string{"Latency p99.9"}                                              // p99.9
	row19ClientReceiveBytesSum := []string{"CLIENT-TOTAL-NETWORK-RX-SUM"}               // RECEIVE-BYTES-NUM-DELTA
	row19ClientReceiveBytesSumRaw := []string{"CLIENT-TOTAL-NETWORK-RX-BYTES-SUM-RAW"}  // RECEIVE-BYTES-NUM-DELTA
	row20ClientTransmitBytesSum := []string{"CLIENT-TOTAL-NETWORK-TX-SUM"}              // TRANSMIT-BYTES-DELTA
	row20ClientTransmitBytesSumRaw := []string{"CLIENT-TOTAL-NETWORK-TX-BYTES-SUM-RAW"} // TRANSMIT-BYTES-DELTA
	row23ClientMaxCPU := []string{"CLIENT-MAX-CPU-USAGE"}                               // CPU-NUM
	row24ClientMaxMemory := []string{"CLIENT-MAX-MEMORY-USAGE"}                         // VMRSS-NUM
	row25ClientErrorCount := []string{"CLIENT-ERROR-COUNT"}                             // ERROR:
	row30AvgDiskSpaceUsage := []string{"SERVER-AVG-DISK-SPACE-USAGE"}                   // DISK-SPACE-USAGE

	databaseIDToErrs := make(map[string][]string)
	for i, databaseID := range cfg.AllDatabaseIDList {
		testgroup := cfg.DatabaseIDToConfigClientMachineAgentControl[databaseID]
		testdata := cfg.DatabaseIDToConfigAnalyzeMachineInitial[databaseID]

		tag := testdata.DatabaseTag
		if tag != row00Header[i+1] {
			return fmt.Errorf("analyze config has different order; expected %q, got %q", row00Header[i+1], tag)
		}
		row02TotalRequestNumber = append(row02TotalRequestNumber, humanize.Comma(testgroup.ConfigClientMachineBenchmarkOptions.RequestNumber))

		{
			fr, err := dataframe.NewFromCSV(nil, testdata.ClientSystemMetricsInterpolatedPath)
			if err != nil {
				return err
			}

			var receiveBytesNumDeltaSum float64
			col, err := fr.Column("RECEIVE-BYTES-NUM-DELTA")
			if err != nil {
				return err
			}
			for i := 0; i < col.Count(); i++ {
				v, err := col.Value(i)
				if err != nil {
					return err
				}
				fv, _ := v.Float64()
				receiveBytesNumDeltaSum += fv
			}

			var transmitBytesNumDeltaSum float64
			col, err = fr.Column("TRANSMIT-BYTES-NUM-DELTA")
			if err != nil {
				return err
			}
			for i := 0; i < col.Count(); i++ {
				v, err := col.Value(i)
				if err != nil {
					return err
				}
				fv, _ := v.Float64()
				transmitBytesNumDeltaSum += fv
			}

			var maxAvgCPU float64
			col, err = fr.Column("CPU-NUM")
			if err != nil {
				return err
			}
			for i := 0; i < col.Count(); i++ {
				v, err := col.Value(i)
				if err != nil {
					return err
				}
				fv, _ := v.Float64()
				if maxAvgCPU == 0 || fv > maxAvgCPU {
					maxAvgCPU = fv
				}
			}

			var maxVMRSSNum uint64
			col, err = fr.Column("VMRSS-NUM")
			if err != nil {
				return err
			}
			for i := 0; i < col.Count(); i++ {
				v, err := col.Value(i)
				if err != nil {
					return err
				}
				iv, _ := v.Uint64()
				if maxVMRSSNum == 0 || iv > maxVMRSSNum {
					maxVMRSSNum = iv
				}
			}

			row19ClientReceiveBytesSum = append(row19ClientReceiveBytesSum, humanize.Bytes(uint64(receiveBytesNumDeltaSum)))
			row19ClientReceiveBytesSumRaw = append(row19ClientReceiveBytesSumRaw, fmt.Sprintf("%.2f", receiveBytesNumDeltaSum))
			row20ClientTransmitBytesSum = append(row20ClientTransmitBytesSum, humanize.Bytes(uint64(transmitBytesNumDeltaSum)))
			row20ClientTransmitBytesSumRaw = append(row20ClientTransmitBytesSumRaw, fmt.Sprintf("%.2f", transmitBytesNumDeltaSum))
			row23ClientMaxCPU = append(row23ClientMaxCPU, fmt.Sprintf("%.2f %%", maxAvgCPU))
			row24ClientMaxMemory = append(row24ClientMaxMemory, humanize.Bytes(maxVMRSSNum))
		}
		{
			f, err := openToRead(testdata.ClientLatencyDistributionSummaryPath)
			if err != nil {
				return err
			}
			defer f.Close()

			rd := csv.NewReader(f)

			// FieldsPerRecord is the number of expected fields per record.
			// If FieldsPerRecord is positive, Read requires each record to
			// have the given number of fields. If FieldsPerRecord is 0, Read sets it to
			// the number of fields in the first record, so that future records must
			// have the same field count. If FieldsPerRecord is negative, no check is
			// made and records may have a variable number of fields.
			rd.FieldsPerRecord = -1

			rows, err := rd.ReadAll()
			if err != nil {
				return err
			}

			var totalErrCnt int64
			for _, row := range rows {
				switch row[0] {
				case "TOTAL-SECONDS":
					row01TotalSeconds = append(row01TotalSeconds, fmt.Sprintf("%s sec", row[1]))
				case "REQUESTS-PER-SECOND":
					fv, err := strconv.ParseFloat(row[1], 64)
					if err != nil {
						return err
					}
					avg := int64(fv)
					row04AverageThroughput = append(row04AverageThroughput, fmt.Sprintf("%s req/sec", humanize.Comma(avg)))
				case "SLOWEST-LATENCY-MS":
					row08SlowestLatency = append(row08SlowestLatency, fmt.Sprintf("%s ms", row[1]))
				case "FASTEST-LATENCY-MS":
					row06FastestLatency = append(row06FastestLatency, fmt.Sprintf("%s ms", row[1]))
				case "AVERAGE-LATENCY-MS":
					row07AverageLatency = append(row07AverageLatency, fmt.Sprintf("%s ms", row[1]))
				}

				if strings.HasPrefix(row[0], "ERROR:") {
					iv, err := strconv.ParseInt(row[1], 10, 64)
					if err != nil {
						return err
					}
					totalErrCnt += iv

					c1 := strings.TrimSpace(strings.Replace(row[0], "ERROR:", "", -1))
					c2 := humanize.Comma(iv)
					es := fmt.Sprintf("%s (count %s)", c1, c2)
					if _, ok := databaseIDToErrs[databaseID]; !ok {
						databaseIDToErrs[databaseID] = []string{es}
					} else {
						databaseIDToErrs[databaseID] = append(databaseIDToErrs[databaseID], es)
					}
				}
			}
			row25ClientErrorCount = append(row25ClientErrorCount, humanize.Comma(totalErrCnt))
		}
		{
			fr, err := dataframe.NewFromCSV(nil, testdata.ClientLatencyThroughputTimeseriesPath)
			if err != nil {
				return err
			}
			col, err := fr.Column("AVG-THROUGHPUT")
			if err != nil {
				return err
			}
			var min int64
			var max int64
			for i := 0; i < col.Count(); i++ {
				val, err := col.Value(i)
				if err != nil {
					return err
				}
				fv, _ := val.Float64()

				if i == 0 {
					min = int64(fv)
				}
				if max < int64(fv) {
					max = int64(fv)
				}
				if min > int64(fv) {
					min = int64(fv)
				}
			}
			row03MaxThroughput = append(row03MaxThroughput, fmt.Sprintf("%s req/sec", humanize.Comma(max)))
			row05MinThroughput = append(row05MinThroughput, fmt.Sprintf("%s req/sec", humanize.Comma(min)))
		}
		{
			fr, err := dataframe.NewFromCSV(nil, testdata.ServerDiskSpaceUsageSummaryPath)
			if err != nil {
				return err
			}
			col, err := fr.Column(dbtester.DiskSpaceUsageSummaryColumns[3]) // datasize in bytes
			if err != nil {
				return err
			}
			var sum float64
			for i := 0; i < col.Count(); i++ {
				val, err := col.Value(i)
				if err != nil {
					return err
				}
				fv, _ := val.Float64()
				sum += fv
			}
			avg := uint64(sum / float64(col.Count()))
			row30AvgDiskSpaceUsage = append(row30AvgDiskSpaceUsage, humanize.Bytes(avg))
		}
		{
			f, err := openToRead(testdata.ClientLatencyDistributionPercentilePath)
			if err != nil {
				return err
			}
			defer f.Close()

			rd := csv.NewReader(f)

			// FieldsPerRecord is the number of expected fields per record.
			// If FieldsPerRecord is positive, Read requires each record to
			// have the given number of fields. If FieldsPerRecord is 0, Read sets it to
			// the number of fields in the first record, so that future records must
			// have the same field count. If FieldsPerRecord is negative, no check is
			// made and records may have a variable number of fields.
			rd.FieldsPerRecord = -1

			rows, err := rd.ReadAll()
			if err != nil {
				return err
			}

			for ri, row := range rows {
				if ri == 0 {
					continue // skip header
				}
				switch row[0] {
				case "p10":
					row09p10 = append(row09p10, fmt.Sprintf("%s ms", row[1]))
				case "p25":
					row10p25 = append(row10p25, fmt.Sprintf("%s ms", row[1]))
				case "p50":
					row11p50 = append(row11p50, fmt.Sprintf("%s ms", row[1]))
				case "p75":
					row12p75 = append(row12p75, fmt.Sprintf("%s ms", row[1]))
				case "p90":
					row13p90 = append(row13p90, fmt.Sprintf("%s ms", row[1]))
				case "p95":
					row14p95 = append(row14p95, fmt.Sprintf("%s ms", row[1]))
				case "p99":
					row15p99 = append(row15p99, fmt.Sprintf("%s ms", row[1]))
				case "p99.9":
					row16p999 = append(row16p999, fmt.Sprintf("%s ms", row[1]))
				}
			}
		}
	}

	lg.Sugar().Info("saving summary data to %q", cfg.ConfigAnalyzeMachineAllAggregatedOutput.AllAggregatedOutputPathCSV)
	aggRowsForSummaryCSV := [][]string{
		row00Header,
		row01TotalSeconds,
		row02TotalRequestNumber,
		row03MaxThroughput,
		row04AverageThroughput,
		row05MinThroughput,

		row06FastestLatency,
		row07AverageLatency,
		row08SlowestLatency,

		row09p10,
		row10p25,
		row11p50,
		row12p75,
		row13p90,
		row14p95,
		row15p99,
		row16p999,

		row17ServerReceiveBytesSum,
		row17ServerReceiveBytesSumRaw,
		row18ServerTransmitBytesSum,
		row18ServerTransmitBytesSumRaw,
		row19ClientReceiveBytesSum,
		row19ClientReceiveBytesSumRaw,
		row20ClientTransmitBytesSum,
		row20ClientTransmitBytesSumRaw,

		row21ServerMaxCPUUsage,
		row22ServerMaxMemoryUsage,
		row23ClientMaxCPU,
		row24ClientMaxMemory,

		row25ClientErrorCount,

		row26ReadsCompletedDeltaSum,
		row27SectorsReadDeltaSum,
		row28WritesCompletedDeltaSum,
		row29SectorsWrittenDeltaSum,
		row30AvgDiskSpaceUsage,
	}
	file, err := openToOverwrite(cfg.ConfigAnalyzeMachineAllAggregatedOutput.AllAggregatedOutputPathCSV)
	if err != nil {
		return err
	}
	defer file.Close()
	wr := csv.NewWriter(file)
	if err := wr.WriteAll(aggRowsForSummaryCSV); err != nil {
		return err
	}
	wr.Flush()
	if err := wr.Error(); err != nil {
		return err
	}

	lg.Sugar().Info("saving summary data to %q", cfg.ConfigAnalyzeMachineAllAggregatedOutput.AllAggregatedOutputPathTXT)
	aggRowsForSummaryTXT := [][]string{
		row00Header,
		row01TotalSeconds,
		row02TotalRequestNumber,
		row03MaxThroughput,
		row04AverageThroughput,
		row05MinThroughput,

		row06FastestLatency,
		row07AverageLatency,
		row08SlowestLatency,

		row09p10,
		row10p25,
		row11p50,
		row12p75,
		row13p90,
		row14p95,
		row15p99,
		row16p999,

		row17ServerReceiveBytesSum,
		row18ServerTransmitBytesSum,
		row19ClientReceiveBytesSum,
		row20ClientTransmitBytesSum,

		row21ServerMaxCPUUsage,
		row22ServerMaxMemoryUsage,
		row23ClientMaxCPU,
		row24ClientMaxMemory,

		row25ClientErrorCount,

		row26ReadsCompletedDeltaSum,
		row27SectorsReadDeltaSum,
		row28WritesCompletedDeltaSum,
		row29SectorsWrittenDeltaSum,
		row30AvgDiskSpaceUsage,
	}
	buf := new(bytes.Buffer)
	tw := tablewriter.NewWriter(buf)
	tw.SetHeader(aggRowsForSummaryTXT[0])
	for _, row := range aggRowsForSummaryTXT[1:] {
		tw.Append(row)
	}
	tw.SetAutoFormatHeaders(false)
	tw.SetAlignment(tablewriter.ALIGN_RIGHT)
	tw.Render()
	errs := ""
	for _, databaseID := range cfg.AllDatabaseIDList {
		es, ok := databaseIDToErrs[databaseID]
		if !ok {
			continue
		}
		errs = databaseID + " " + "errors:\n" + strings.Join(es, "\n") + "\n"
	}
	stxt := buf.String()
	if errs != "" {
		stxt += "\n" + "\n" + errs
	}
	if err := toFile(stxt, changeExtToTxt(cfg.ConfigAnalyzeMachineAllAggregatedOutput.AllAggregatedOutputPathTXT)); err != nil {
		return err
	}

	// KEYS, MIN-LATENCY-MS, AVG-LATENCY-MS, MAX-LATENCY-MS
	lg.Sugar().Info("combining all latency data by keys")
	allLatencyFrame := dataframe.New()
	for _, databaseID := range cfg.AllDatabaseIDList {
		testdata := cfg.DatabaseIDToConfigAnalyzeMachineInitial[databaseID]

		fr, err := dataframe.NewFromCSV(nil, testdata.ClientLatencyByKeyNumberPath)
		if err != nil {
			return err
		}
		colKeys, err := fr.Column("KEYS")
		if err != nil {
			return err
		}
		colKeys.UpdateHeader(makeHeader("KEYS", testdata.DatabaseTag))
		if err = allLatencyFrame.AddColumn(colKeys); err != nil {
			return err
		}

		colMinLatency, err := fr.Column("MIN-LATENCY-MS")
		if err != nil {
			return err
		}
		colMinLatency.UpdateHeader(makeHeader("MIN-LATENCY-MS", testdata.DatabaseTag))
		if err = allLatencyFrame.AddColumn(colMinLatency); err != nil {
			return err
		}

		colAvgLatency, err := fr.Column("AVG-LATENCY-MS")
		if err != nil {
			return err
		}
		colAvgLatency.UpdateHeader(makeHeader("AVG-LATENCY-MS", testdata.DatabaseTag))
		if err = allLatencyFrame.AddColumn(colAvgLatency); err != nil {
			return err
		}

		colMaxLatency, err := fr.Column("MAX-LATENCY-MS")
		if err != nil {
			return err
		}
		colMaxLatency.UpdateHeader(makeHeader("MAX-LATENCY-MS", testdata.DatabaseTag))
		if err = allLatencyFrame.AddColumn(colMaxLatency); err != nil {
			return err
		}
	}
	// KEYS, MIN-VMRSS-MB, AVG-VMRSS-MB, MAX-VMRSS-MB
	lg.Sugar().Info("combining all server memory usage by keys")
	allMemoryFrame := dataframe.New()
	for _, databaseID := range cfg.AllDatabaseIDList {
		testdata := cfg.DatabaseIDToConfigAnalyzeMachineInitial[databaseID]

		fr, err := dataframe.NewFromCSV(nil, testdata.ServerMemoryByKeyNumberPath)
		if err != nil {
			return err
		}
		colKeys, err := fr.Column("KEYS")
		if err != nil {
			return err
		}
		colKeys.UpdateHeader(makeHeader("KEYS", testdata.DatabaseTag))
		if err = allMemoryFrame.AddColumn(colKeys); err != nil {
			return err
		}

		colMemMin, err := fr.Column("MIN-VMRSS-MB")
		if err != nil {
			return err
		}
		colMemMin.UpdateHeader(makeHeader("MIN-VMRSS-MB", testdata.DatabaseTag))
		if err = allMemoryFrame.AddColumn(colMemMin); err != nil {
			return err
		}

		colMem, err := fr.Column("AVG-VMRSS-MB")
		if err != nil {
			return err
		}
		colMem.UpdateHeader(makeHeader("AVG-VMRSS-MB", testdata.DatabaseTag))
		if err = allMemoryFrame.AddColumn(colMem); err != nil {
			return err
		}

		colMemMax, err := fr.Column("MAX-VMRSS-MB")
		if err != nil {
			return err
		}
		colMemMax.UpdateHeader(makeHeader("MAX-VMRSS-MB", testdata.DatabaseTag))
		if err = allMemoryFrame.AddColumn(colMemMax); err != nil {
			return err
		}
	}
	// KEYS, AVG-READ-BYTES-NUM-DELTA, AVG-READ-BYTES
	lg.Sugar().Info("combining all server read bytes delta by keys")
	allReadBytesDeltaFrame := dataframe.New()
	for _, databaseID := range cfg.AllDatabaseIDList {
		testdata := cfg.DatabaseIDToConfigAnalyzeMachineInitial[databaseID]

		fr, err := dataframe.NewFromCSV(nil, testdata.ServerReadBytesDeltaByKeyNumberPath)
		if err != nil {
			return err
		}
		colKeys, err := fr.Column("KEYS")
		if err != nil {
			return err
		}
		colKeys.UpdateHeader(makeHeader("KEYS", testdata.DatabaseTag))
		if err = allReadBytesDeltaFrame.AddColumn(colKeys); err != nil {
			return err
		}

		col1, err := fr.Column("AVG-READ-BYTES-NUM-DELTA")
		if err != nil {
			return err
		}
		col1.UpdateHeader(makeHeader("AVG-READ-BYTES-NUM-DELTA", testdata.DatabaseTag))
		if err = allReadBytesDeltaFrame.AddColumn(col1); err != nil {
			return err
		}

		col2, err := fr.Column("AVG-READ-BYTES")
		if err != nil {
			return err
		}
		col2.UpdateHeader(makeHeader("AVG-READ-BYTES", testdata.DatabaseTag))
		if err = allReadBytesDeltaFrame.AddColumn(col2); err != nil {
			return err
		}
	}
	// KEYS, AVG-WRITE-BYTES-NUM-DELTA, AVG-WRITE-BYTES
	lg.Sugar().Info("combining all server write bytes delta by keys")
	allWriteBytesDeltaFrame := dataframe.New()
	for _, databaseID := range cfg.AllDatabaseIDList {
		testdata := cfg.DatabaseIDToConfigAnalyzeMachineInitial[databaseID]

		fr, err := dataframe.NewFromCSV(nil, testdata.ServerWriteBytesDeltaByKeyNumberPath)
		if err != nil {
			return err
		}
		colKeys, err := fr.Column("KEYS")
		if err != nil {
			return err
		}
		colKeys.UpdateHeader(makeHeader("KEYS", testdata.DatabaseTag))
		if err = allWriteBytesDeltaFrame.AddColumn(colKeys); err != nil {
			return err
		}

		col1, err := fr.Column("AVG-WRITE-BYTES-NUM-DELTA")
		if err != nil {
			return err
		}
		col1.UpdateHeader(makeHeader("AVG-WRITE-BYTES-NUM-DELTA", testdata.DatabaseTag))
		if err = allWriteBytesDeltaFrame.AddColumn(col1); err != nil {
			return err
		}

		col2, err := fr.Column("AVG-WRITE-BYTES")
		if err != nil {
			return err
		}
		col2.UpdateHeader(makeHeader("AVG-WRITE-BYTES", testdata.DatabaseTag))
		if err = allWriteBytesDeltaFrame.AddColumn(col2); err != nil {
			return err
		}
	}

	{
		allLatencyFrameCfg := dbtesterpb.ConfigAnalyzeMachinePlot{
			Column:         "AVG-LATENCY-MS",
			XAxis:          "Cumulative Number of Keys",
			YAxis:          "Latency(millisecond) by Keys",
			OutputPathList: make([]string, len(cfg.AnalyzePlotList[0].OutputPathList)),
		}
		allLatencyFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY.svg")
		allLatencyFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY.png")
		lg.Sugar().Info("plotting %v", allLatencyFrameCfg.OutputPathList)
		var pairs []pair
		allCols := allLatencyFrame.Columns()
		for i := 0; i < len(allCols)-3; i += 4 {
			pairs = append(pairs, pair{
				x: allCols[i],   // x
				y: allCols[i+2], // avg
			})
		}
		if err = all.drawXY(allLatencyFrameCfg, pairs...); err != nil {
			return err
		}
		newCSV := dataframe.New()
		for _, p := range pairs {
			if err = newCSV.AddColumn(p.x); err != nil {
				return err
			}
			if err = newCSV.AddColumn(p.y); err != nil {
				return err
			}
		}
		csvPath := filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY.csv")
		if err := newCSV.CSV(csvPath); err != nil {
			return err
		}
	}
	{
		// with error points
		allLatencyFrameCfg := dbtesterpb.ConfigAnalyzeMachinePlot{
			Column:         "AVG-LATENCY-MS",
			XAxis:          "Cumulative Number of Keys",
			YAxis:          "Latency(millisecond) by Keys",
			OutputPathList: make([]string, len(cfg.AnalyzePlotList[0].OutputPathList)),
		}
		allLatencyFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY-ERROR-POINTS.svg")
		allLatencyFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY-ERROR-POINTS.png")
		lg.Sugar().Info("plotting %v", allLatencyFrameCfg.OutputPathList)
		var triplets []triplet
		allCols := allLatencyFrame.Columns()
		for i := 0; i < len(allCols)-3; i += 4 {
			triplets = append(triplets, triplet{
				x:      allCols[i],
				minCol: allCols[i+1],
				avgCol: allCols[i+2],
				maxCol: allCols[i+3],
			})
		}
		if err = all.drawXYWithErrorPoints(allLatencyFrameCfg, triplets...); err != nil {
			return err
		}
		newCSV := dataframe.New()
		for _, tri := range triplets {
			if err = newCSV.AddColumn(tri.x); err != nil {
				return err
			}
			if err = newCSV.AddColumn(tri.minCol); err != nil {
				return err
			}
			if err = newCSV.AddColumn(tri.avgCol); err != nil {
				return err
			}
			if err = newCSV.AddColumn(tri.maxCol); err != nil {
				return err
			}
		}
		csvPath := filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-LATENCY-MS-BY-KEY-ERROR-POINTS.csv")
		if err := newCSV.CSV(csvPath); err != nil {
			return err
		}
	}
	{
		allMemoryFrameCfg := dbtesterpb.ConfigAnalyzeMachinePlot{
			Column:         "AVG-VMRSS-MB",
			XAxis:          "Cumulative Number of Keys",
			YAxis:          "Memory(MB) by Keys",
			OutputPathList: make([]string, len(cfg.AnalyzePlotList[0].OutputPathList)),
		}
		allMemoryFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY.svg")
		allMemoryFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY.png")
		lg.Sugar().Info("plotting %v", allMemoryFrameCfg.OutputPathList)
		var pairs []pair
		allCols := allMemoryFrame.Columns()
		for i := 0; i < len(allCols)-3; i += 4 {
			pairs = append(pairs, pair{
				x: allCols[i],   // x
				y: allCols[i+2], // avg
			})
		}
		if err = all.drawXY(allMemoryFrameCfg, pairs...); err != nil {
			return err
		}
		newCSV := dataframe.New()
		for _, p := range pairs {
			if err = newCSV.AddColumn(p.x); err != nil {
				return err
			}
			if err = newCSV.AddColumn(p.y); err != nil {
				return err
			}
		}
		csvPath := filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY.csv")
		if err := newCSV.CSV(csvPath); err != nil {
			return err
		}
	}
	{
		// with error points
		allMemoryFrameCfg := dbtesterpb.ConfigAnalyzeMachinePlot{
			Column:         "AVG-VMRSS-MB",
			XAxis:          "Cumulative Number of Keys",
			YAxis:          "Memory(MB) by Keys",
			OutputPathList: make([]string, len(cfg.AnalyzePlotList[0].OutputPathList)),
		}
		allMemoryFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY-ERROR-POINTS.svg")
		allMemoryFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY-ERROR-POINTS.png")
		lg.Sugar().Info("plotting %v", allMemoryFrameCfg.OutputPathList)
		var triplets []triplet
		allCols := allMemoryFrame.Columns()
		for i := 0; i < len(allCols)-3; i += 4 {
			triplets = append(triplets, triplet{
				x:      allCols[i],
				minCol: allCols[i+1],
				avgCol: allCols[i+2],
				maxCol: allCols[i+3],
			})
		}
		if err = all.drawXYWithErrorPoints(allMemoryFrameCfg, triplets...); err != nil {
			return err
		}
		newCSV := dataframe.New()
		for _, tri := range triplets {
			if err = newCSV.AddColumn(tri.x); err != nil {
				return err
			}
			if err = newCSV.AddColumn(tri.minCol); err != nil {
				return err
			}
			if err = newCSV.AddColumn(tri.avgCol); err != nil {
				return err
			}
			if err = newCSV.AddColumn(tri.maxCol); err != nil {
				return err
			}
		}
		csvPath := filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-VMRSS-MB-BY-KEY-ERROR-POINTS.csv")
		if err := newCSV.CSV(csvPath); err != nil {
			return err
		}
	}
	{
		allReadBytesDeltaFrameCfg := dbtesterpb.ConfigAnalyzeMachinePlot{
			Column:         "AVG-READ-BYTES-NUM-DELTA",
			XAxis:          "Cumulative Number of Keys",
			YAxis:          "Average Read Bytes Delta by Keys",
			OutputPathList: make([]string, len(cfg.AnalyzePlotList[0].OutputPathList)),
		}
		allReadBytesDeltaFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-READ-BYTES-NUM-DELTA-BY-KEY.svg")
		allReadBytesDeltaFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-READ-BYTES-NUM-DELTA-BY-KEY.png")
		lg.Sugar().Info("plotting %v", allReadBytesDeltaFrameCfg.OutputPathList)
		var pairs []pair
		allCols := allReadBytesDeltaFrame.Columns()
		for i := 0; i < len(allCols)-2; i += 3 {
			pairs = append(pairs, pair{
				x: allCols[i],   // x
				y: allCols[i+1], // avg
			})
		}
		if err = all.drawXY(allReadBytesDeltaFrameCfg, pairs...); err != nil {
			return err
		}
		csvPath := filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-READ-BYTES-NUM-DELTA-BY-KEY.csv")
		if err := allReadBytesDeltaFrame.CSV(csvPath); err != nil {
			return err
		}
	}
	{
		allWriteBytesDeltaFrameCfg := dbtesterpb.ConfigAnalyzeMachinePlot{
			Column:         "AVG-WRITE-BYTES-NUM-DELTA",
			XAxis:          "Cumulative Number of Keys",
			YAxis:          "Average Write Bytes Delta by Keys",
			OutputPathList: make([]string, len(cfg.AnalyzePlotList[0].OutputPathList)),
		}
		allWriteBytesDeltaFrameCfg.OutputPathList[0] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-WRITE-BYTES-NUM-DELTA-BY-KEY.svg")
		allWriteBytesDeltaFrameCfg.OutputPathList[1] = filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-WRITE-BYTES-NUM-DELTA-BY-KEY.png")
		lg.Sugar().Info("plotting %v", allWriteBytesDeltaFrameCfg.OutputPathList)
		var pairs []pair
		allCols := allWriteBytesDeltaFrame.Columns()
		for i := 0; i < len(allCols)-2; i += 3 {
			pairs = append(pairs, pair{
				x: allCols[i],   // x
				y: allCols[i+1], // avg
			})
		}
		if err = all.drawXY(allWriteBytesDeltaFrameCfg, pairs...); err != nil {
			return err
		}
		csvPath := filepath.Join(filepath.Dir(cfg.AnalyzePlotList[0].OutputPathList[0]), "AVG-WRITE-BYTES-NUM-DELTA-BY-KEY.csv")
		if err := allWriteBytesDeltaFrame.CSV(csvPath); err != nil {
			return err
		}
	}

	lg.Info("combining data for plotting")
	for _, plotConfig := range cfg.AnalyzePlotList {
		lg.Sugar().Info("plotting %q", plotConfig.Column)
		var clientNumColumns []dataframe.Column
		var pairs []pair
		var dataColumns []dataframe.Column
		for i, ad := range all.data {
			databaseID := all.allDatabaseIDList[i]
			tag := cfg.DatabaseIDToConfigClientMachineAgentControl[databaseID].DatabaseTag

			avgCol, err := ad.aggregated.Column("CONTROL-CLIENT-NUM")
			if err != nil {
				return err
			}
			avgCol.UpdateHeader(makeHeader("CONTROL-CLIENT-NUM", tag))
			clientNumColumns = append(clientNumColumns, avgCol)

			col, err := ad.aggregated.Column(plotConfig.Column)
			if err != nil {
				return err
			}
			col.UpdateHeader(makeHeader(plotConfig.Column, tag))
			pairs = append(pairs, pair{y: col})
			dataColumns = append(dataColumns, col)
		}
		if err = all.draw(plotConfig, pairs...); err != nil {
			return err
		}

		lg.Sugar().Info("saving data for %q of all database", plotConfig.Column)
		nf1, err := dataframe.NewFromColumns(nil, dataColumns...)
		if err != nil {
			return err
		}
		if err = nf1.CSV(plotConfig.OutputPathCSV); err != nil {
			return err
		}

		lg.Sugar().Info("saving data for %q of all database (by client number)", plotConfig.Column)
		nf2 := dataframe.New()
		for i := range clientNumColumns {
			if clientNumColumns[i].Count() != dataColumns[i].Count() {
				return fmt.Errorf("%q row count %d != %q row count %d",
					clientNumColumns[i].Header(),
					clientNumColumns[i].Count(),
					dataColumns[i].Header(),
					dataColumns[i].Count(),
				)
			}
			if err := nf2.AddColumn(clientNumColumns[i]); err != nil {
				return err
			}
			if err := nf2.AddColumn(dataColumns[i]); err != nil {
				return err
			}
		}
		if err = nf2.CSV(filepath.Join(filepath.Dir(plotConfig.OutputPathCSV), plotConfig.Column+"-BY-CLIENT-NUM"+".csv")); err != nil {
			return err
		}

		if len(cfg.DatabaseIDToConfigClientMachineAgentControl[cfg.AllDatabaseIDList[0]].ConfigClientMachineBenchmarkOptions.ConnectionClientNumbers) > 0 {
			lg.Sugar().Info("aggregating data for %q of all database (by client number)", plotConfig.Column)
			nf3 := dataframe.New()
			var firstKeys []int
			for i := range clientNumColumns {
				n := clientNumColumns[i].Count()
				allData := make(map[int]float64)
				for j := 0; j < n; j++ {
					v1, err := clientNumColumns[i].Value(j)
					if err != nil {
						return err
					}
					num, _ := v1.Int64()

					v2, err := dataColumns[i].Value(j)
					if err != nil {
						return err
					}
					data, _ := v2.Float64()

					if v, ok := allData[int(num)]; ok {
						allData[int(num)] = (v + data) / 2
					} else {
						allData[int(num)] = data
					}
				}
				var allKeys []int
				for k := range allData {
					allKeys = append(allKeys, k)
				}
				sort.Ints(allKeys)

				if i == 0 {
					firstKeys = allKeys
				}
				if !reflect.DeepEqual(firstKeys, allKeys) {
					return fmt.Errorf("all keys must be %+v, got %+v", firstKeys, allKeys)
				}

				if i == 0 {
					col1 := dataframe.NewColumn("CONTROL-CLIENT-NUM")
					for j := range allKeys {
						col1.PushBack(dataframe.NewStringValue(allKeys[j]))
					}
					if err := nf3.AddColumn(col1); err != nil {
						return err
					}
				}
				col2 := dataframe.NewColumn(dataColumns[i].Header())
				for j := range allKeys {
					col2.PushBack(dataframe.NewStringValue(fmt.Sprintf("%.4f", allData[allKeys[j]])))
				}
				if err := nf3.AddColumn(col2); err != nil {
					return err
				}
			}
			if err = nf3.CSV(filepath.Join(filepath.Dir(plotConfig.OutputPathCSV), plotConfig.Column+"-BY-CLIENT-NUM-aggregated"+".csv")); err != nil {
				return err
			}
		}
	}

	return cfg.WriteREADME(stxt)
}

func changeExtToTxt(fpath string) string {
	ext := filepath.Ext(fpath)
	return strings.Replace(fpath, ext, ".txt", -1)
}


================================================
FILE: analyze/doc.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package analyze analyzes the bench test results, specific to dbtester tests.
package analyze


================================================
FILE: analyze/logger.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package analyze

import "go.uber.org/zap"

var lg *zap.Logger

func init() {
	var err error
	lg, err = zap.NewProduction()
	if err != nil {
		panic(err)
	}
}


================================================
FILE: analyze/util.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package analyze

import (
	"fmt"
	"os"
)

func minFloat64(a, b float64) float64 {
	if a < b {
		return a
	}
	return b
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	}
	return b
}

func makeHeader(column string, tag string) string {
	return fmt.Sprintf("%s-%s", column, tag)
}

func openToRead(fpath string) (*os.File, error) {
	f, err := os.OpenFile(fpath, os.O_RDONLY, 0444)
	if err != nil {
		return nil, err
	}
	return f, nil
}

func openToOverwrite(fpath string) (*os.File, error) {
	f, err := os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0777)
	if err != nil {
		return nil, err
	}
	return f, nil
}

func toFile(txt, fpath string) error {
	f, err := openToOverwrite(fpath)
	if err != nil {
		f, err = os.Create(fpath)
		if err != nil {
			return err
		}
	}
	defer f.Close()
	_, err = f.WriteString(txt)
	return err
}


================================================
FILE: broadcast_request.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dbtester

import (
	"context"
	"fmt"
	"time"

	"github.com/etcd-io/dbtester/dbtesterpb"

	"go.uber.org/zap"
	"google.golang.org/grpc"
)

// BroadcaseRequest sends request to all endpoints.
func (cfg *Config) BroadcaseRequest(databaseID string, op dbtesterpb.Operation) (map[int]dbtesterpb.Response, error) {
	gcfg, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[databaseID]
	if !ok {
		return nil, fmt.Errorf("database id %q does not exist", databaseID)
	}

	type result struct {
		idx int
		r   dbtesterpb.Response
	}
	donec, errc := make(chan result), make(chan error)
	for i := range gcfg.AgentEndpoints {
		req, err := cfg.ToRequest(databaseID, op, i)
		if err != nil {
			return nil, err
		}
		ep := gcfg.AgentEndpoints[i]

		go func(i int, ep string, req *dbtesterpb.Request) {
			cfg.lg.Info("sending message",
				zap.Int("index", i),
				zap.String("endpoint", ep),
				zap.String("operation", op.String()),
				zap.String("database", req.DatabaseID.String()),
			)
			conn, err := grpc.Dial(ep, grpc.WithInsecure())
			if err != nil {
				errc <- fmt.Errorf("%v (%q)", err, ep)
				return
			}
			defer conn.Close()

			// give enough timeout
			// e.g. uploading logs takes longer
			cli := dbtesterpb.NewTransporterClient(conn)
			ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
			resp, err := cli.Transfer(ctx, req)
			cancel()
			if err != nil {
				errc <- fmt.Errorf("%v (%q)", err, ep)
				return
			}
			cfg.lg.Info("received response",
				zap.Int("index", i),
				zap.String("endpoint", ep),
				zap.String("operation", op.String()),
				zap.String("database", req.DatabaseID.String()),
				zap.String("response", fmt.Sprintf("%+v", resp)),
			)

			donec <- result{idx: i, r: *resp}
		}(i, ep, req)

		time.Sleep(time.Second)
	}

	im := make(map[int]dbtesterpb.Response)
	var errs []error
	for cnt := 0; cnt != len(gcfg.AgentEndpoints); cnt++ {
		select {
		case rs := <-donec:
			im[rs.idx] = rs.r
		case err := <-errc:
			errs = append(errs, err)
		}
	}
	if len(errs) > 0 {
		return nil, errs[0]
	}
	return im, nil
}


================================================
FILE: cmd/dbtester/main.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// dbtester is distributed database tester.
//
//	Usage:
//	dbtester [command]
//
//	Available Commands:
//	agent       Database 'agent' in remote servers.
//	analyze     Analyzes test dbtester test results.
//	control     Controls tests.
//
package main

import (
	"fmt"
	"os"

	"github.com/etcd-io/dbtester/agent"
	"github.com/etcd-io/dbtester/analyze"
	"github.com/etcd-io/dbtester/control"
	"github.com/spf13/cobra"
)

var (
	rootCommand = &cobra.Command{
		Use:        "dbtester",
		Short:      "dbtester is distributed database tester.",
		SuggestFor: []string{"dbtstetr", "dbtes", "dbtesters"},
	}
)

func init() {
	cobra.EnablePrefixMatching = true
}

func init() {
	rootCommand.AddCommand(agent.Command)
	rootCommand.AddCommand(analyze.Command)
	rootCommand.AddCommand(control.Command)
}

func main() {
	if err := rootCommand.Execute(); err != nil {
		fmt.Fprintln(os.Stdout, err)
		os.Exit(1)
	}
}


================================================
FILE: code-of-conduct.md
================================================
## CoreOS Community Code of Conduct

### Contributor Code of Conduct

As contributors and maintainers of this project, and in the interest of
fostering an open and welcoming community, we pledge to respect all people who
contribute through reporting issues, posting feature requests, updating
documentation, submitting pull requests or patches, and other activities.

We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, religion, or nationality.

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing others' private information, such as physical or electronic addresses, without explicit permission
* Other unethical or unprofessional conduct.

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. By adopting this Code of Conduct,
project maintainers commit themselves to fairly and consistently applying these
principles to every aspect of managing this project. Project maintainers who do
not follow or enforce the Code of Conduct may be permanently removed from the
project team.

This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting a project maintainer, Brandon Philips
<brandon.philips@coreos.com>, and/or Rithu John <rithu.john@coreos.com>.

This Code of Conduct is adapted from the Contributor Covenant
(http://contributor-covenant.org), version 1.2.0, available at
http://contributor-covenant.org/version/1/2/0/

### CoreOS Events Code of Conduct

CoreOS events are working conferences intended for professional networking and
collaboration in the CoreOS community. Attendees are expected to behave
according to professional standards and in accordance with their employer’s
policies on appropriate workplace behavior.

While at CoreOS events or related social networking opportunities, attendees
should not engage in discriminatory or offensive speech or actions including
but not limited to gender, sexuality, race, age, disability, or religion.
Speakers should be especially aware of these concerns.

CoreOS does not condone any statements by speakers contrary to these standards.
CoreOS reserves the right to deny entrance and/or eject from an event (without
refund) any individual found to be engaging in discriminatory or offensive
speech or actions.

Please bring any concerns to the immediate attention of designated on-site
staff, Brandon Philips <brandon.philips@coreos.com>, and/or Rithu John <rithu.john@coreos.com>.


================================================
FILE: config-dbtester-gcloud-key.json
================================================
test-key

================================================
FILE: config_dbtester.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dbtester

import (
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strings"

	"github.com/etcd-io/dbtester/dbtesterpb"

	"go.uber.org/zap"
	"gopkg.in/yaml.v2"
)

// MakeTag converts database description to database tag.
func MakeTag(desc string) string {
	s := strings.ToLower(desc)
	s = strings.Replace(s, "go ", "go", -1)
	s = strings.Replace(s, "java ", "java", -1)
	s = strings.Replace(s, "(", "", -1)
	s = strings.Replace(s, ")", "", -1)
	return strings.Replace(s, " ", "-", -1)
}

// Config configures dbtester control clients.
type Config struct {
	lg *zap.Logger

	TestTitle       string `yaml:"test_title"`
	TestDescription string `yaml:"test_description"`

	dbtesterpb.ConfigClientMachineInitial `yaml:"config_client_machine_initial"`

	AllDatabaseIDList                           []string                                              `yaml:"all_database_id_list"`
	DatabaseIDToConfigClientMachineAgentControl map[string]dbtesterpb.ConfigClientMachineAgentControl `yaml:"datatbase_id_to_config_client_machine_agent_control"`
	DatabaseIDToConfigAnalyzeMachineInitial     map[string]dbtesterpb.ConfigAnalyzeMachineInitial     `yaml:"datatbase_id_to_config_analyze_machine_initial"`

	dbtesterpb.ConfigAnalyzeMachineAllAggregatedOutput `yaml:"analyze_all_aggregated_output"`
	AnalyzePlotPathPrefix                              string                                `yaml:"analyze_plot_path_prefix"`
	AnalyzePlotList                                    []dbtesterpb.ConfigAnalyzeMachinePlot `yaml:"analyze_plot_list"`
	dbtesterpb.ConfigAnalyzeMachineREADME              `yaml:"analyze_readme"`
}

// ReadConfig reads control configuration file.
func ReadConfig(fpath string, analyze bool) (*Config, error) {
	bts, err := ioutil.ReadFile(fpath)
	if err != nil {
		return nil, err
	}
	cfg := Config{}
	if err = yaml.Unmarshal(bts, &cfg); err != nil {
		return nil, err
	}

	lg, lerr := zap.NewProduction()
	if lerr != nil {
		return nil, lerr
	}
	cfg.lg = lg

	for _, id := range cfg.AllDatabaseIDList {
		if !dbtesterpb.IsValidDatabaseID(id) {
			return nil, fmt.Errorf("databaseID %q is unknown", id)
		}
	}

	if cfg.ConfigClientMachineInitial.PathPrefix != "" {
		cfg.ConfigClientMachineInitial.LogPath = filepath.Join(cfg.ConfigClientMachineInitial.PathPrefix, cfg.ConfigClientMachineInitial.LogPath)
		cfg.ConfigClientMachineInitial.ClientSystemMetricsPath = filepath.Join(cfg.ConfigClientMachineInitial.PathPrefix, cfg.ConfigClientMachineInitial.ClientSystemMetricsPath)
		cfg.ConfigClientMachineInitial.ClientSystemMetricsInterpolatedPath = filepath.Join(cfg.ConfigClientMachineInitial.PathPrefix, cfg.ConfigClientMachineInitial.ClientSystemMetricsInterpolatedPath)
		cfg.ConfigClientMachineInitial.ClientLatencyThroughputTimeseriesPath = filepath.Join(cfg.ConfigClientMachineInitial.PathPrefix, cfg.ConfigClientMachineInitial.ClientLatencyThroughputTimeseriesPath)
		cfg.ConfigClientMachineInitial.ClientLatencyDistributionAllPath = filepath.Join(cfg.ConfigClientMachineInitial.PathPrefix, cfg.ConfigClientMachineInitial.ClientLatencyDistributionAllPath)
		cfg.ConfigClientMachineInitial.ClientLatencyDistributionPercentilePath = filepath.Join(cfg.ConfigClientMachineInitial.PathPrefix, cfg.ConfigClientMachineInitial.ClientLatencyDistributionPercentilePath)
		cfg.ConfigClientMachineInitial.ClientLatencyDistributionSummaryPath = filepath.Join(cfg.ConfigClientMachineInitial.PathPrefix, cfg.ConfigClientMachineInitial.ClientLatencyDistributionSummaryPath)
		cfg.ConfigClientMachineInitial.ClientLatencyByKeyNumberPath = filepath.Join(cfg.ConfigClientMachineInitial.PathPrefix, cfg.ConfigClientMachineInitial.ClientLatencyByKeyNumberPath)
		cfg.ConfigClientMachineInitial.ServerDiskSpaceUsageSummaryPath = filepath.Join(cfg.ConfigClientMachineInitial.PathPrefix, cfg.ConfigClientMachineInitial.ServerDiskSpaceUsageSummaryPath)
	}

	for databaseID, group := range cfg.DatabaseIDToConfigClientMachineAgentControl {
		if !dbtesterpb.IsValidDatabaseID(databaseID) {
			return nil, fmt.Errorf("databaseID %q is unknown", databaseID)
		}

		group.DatabaseID = databaseID
		group.DatabaseTag = MakeTag(group.DatabaseDescription)
		group.PeerIPsString = strings.Join(group.PeerIPs, "___")
		group.DatabaseEndpoints = make([]string, len(group.PeerIPs))
		group.AgentEndpoints = make([]string, len(group.PeerIPs))
		for j := range group.PeerIPs {
			group.DatabaseEndpoints[j] = fmt.Sprintf("%s:%d", group.PeerIPs[j], group.DatabasePortToConnect)
			group.AgentEndpoints[j] = fmt.Sprintf("%s:%d", group.PeerIPs[j], group.AgentPortToConnect)
		}
		cfg.DatabaseIDToConfigClientMachineAgentControl[databaseID] = group
	}

	for databaseID, amc := range cfg.DatabaseIDToConfigAnalyzeMachineInitial {
		amc.PathPrefix = strings.TrimSpace(amc.PathPrefix)
		amc.DatabaseID = databaseID
		amc.DatabaseTag = cfg.DatabaseIDToConfigClientMachineAgentControl[databaseID].DatabaseTag
		amc.DatabaseDescription = cfg.DatabaseIDToConfigClientMachineAgentControl[databaseID].DatabaseDescription

		if amc.PathPrefix != "" {
			amc.ClientSystemMetricsInterpolatedPath = amc.PathPrefix + "-" + amc.ClientSystemMetricsInterpolatedPath
			amc.ClientLatencyThroughputTimeseriesPath = amc.PathPrefix + "-" + amc.ClientLatencyThroughputTimeseriesPath
			amc.ClientLatencyDistributionAllPath = amc.PathPrefix + "-" + amc.ClientLatencyDistributionAllPath
			amc.ClientLatencyDistributionPercentilePath = amc.PathPrefix + "-" + amc.ClientLatencyDistributionPercentilePath
			amc.ClientLatencyDistributionSummaryPath = amc.PathPrefix + "-" + amc.ClientLatencyDistributionSummaryPath
			amc.ClientLatencyByKeyNumberPath = amc.PathPrefix + "-" + amc.ClientLatencyByKeyNumberPath
			amc.ServerDiskSpaceUsageSummaryPath = amc.PathPrefix + "-" + amc.ServerDiskSpaceUsageSummaryPath
			amc.ServerMemoryByKeyNumberPath = amc.PathPrefix + "-" + amc.ServerMemoryByKeyNumberPath
			amc.ServerReadBytesDeltaByKeyNumberPath = amc.PathPrefix + "-" + amc.ServerReadBytesDeltaByKeyNumberPath
			amc.ServerWriteBytesDeltaByKeyNumberPath = amc.PathPrefix + "-" + amc.ServerWriteBytesDeltaByKeyNumberPath
			for i := range amc.ServerSystemMetricsInterpolatedPathList {
				amc.ServerSystemMetricsInterpolatedPathList[i] = amc.PathPrefix + "-" + amc.ServerSystemMetricsInterpolatedPathList[i]
			}
			amc.AllAggregatedOutputPath = amc.PathPrefix + "-" + amc.AllAggregatedOutputPath
		}

		cfg.DatabaseIDToConfigAnalyzeMachineInitial[databaseID] = amc
	}

	for databaseID, ctrl := range cfg.DatabaseIDToConfigClientMachineAgentControl {
		if databaseID != dbtesterpb.DatabaseID_etcd__other.String() &&
			databaseID != dbtesterpb.DatabaseID_etcd__tip.String() &&
			databaseID != dbtesterpb.DatabaseID_etcd__v3_2.String() &&
			databaseID != dbtesterpb.DatabaseID_etcd__v3_3.String() &&
			ctrl.ConfigClientMachineBenchmarkOptions.ConnectionNumber != ctrl.ConfigClientMachineBenchmarkOptions.ClientNumber {
			return nil, fmt.Errorf("%q got connected %d != clients %d", databaseID, ctrl.ConfigClientMachineBenchmarkOptions.ConnectionNumber, ctrl.ConfigClientMachineBenchmarkOptions.ClientNumber)
		}
	}

	const (
		defaultAgentPort           int64 = 3500
		defaultEtcdClientPort      int64 = 2379
		defaultZookeeperClientPort int64 = 2181
		defaultConsulClientPort    int64 = 8500

		defaultEtcdSnapshotCount             int64 = 100000
		defaultEtcdQuotaSizeBytes            int64 = 8000000000
		defaultZookeeperSnapCount            int64 = 100000
		defaultZookeeperTickTime             int64 = 2000
		defaultZookeeperInitLimit            int64 = 5
		defaultZookeeperSyncLimit            int64 = 5
		defaultZookeeperMaxClientConnections int64 = 5000
	)

	if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__other.String()]; ok {
		if v.AgentPortToConnect == 0 {
			v.AgentPortToConnect = defaultAgentPort
		}
		if v.DatabasePortToConnect == 0 {
			v.DatabasePortToConnect = defaultEtcdClientPort
		}
		if v.Flag_Etcd_Other.SnapshotCount == 0 {
			v.Flag_Etcd_Other.SnapshotCount = defaultEtcdSnapshotCount
		}
		if v.Flag_Etcd_Other.QuotaSizeBytes == 0 {
			v.Flag_Etcd_Other.QuotaSizeBytes = defaultEtcdQuotaSizeBytes
		}
		cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__other.String()] = v
	}
	if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()]; ok {
		if v.AgentPortToConnect == 0 {
			v.AgentPortToConnect = defaultAgentPort
		}
		if v.DatabasePortToConnect == 0 {
			v.DatabasePortToConnect = defaultEtcdClientPort
		}
		if v.Flag_Etcd_Tip.SnapshotCount == 0 {
			v.Flag_Etcd_Tip.SnapshotCount = defaultEtcdSnapshotCount
		}
		if v.Flag_Etcd_Tip.QuotaSizeBytes == 0 {
			v.Flag_Etcd_Tip.QuotaSizeBytes = defaultEtcdQuotaSizeBytes
		}
		cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()] = v
	}
	if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()]; ok {
		if v.AgentPortToConnect == 0 {
			v.AgentPortToConnect = defaultAgentPort
		}
		if v.DatabasePortToConnect == 0 {
			v.DatabasePortToConnect = defaultEtcdClientPort
		}
		if v.Flag_Etcd_V3_2.SnapshotCount == 0 {
			v.Flag_Etcd_V3_2.SnapshotCount = defaultEtcdSnapshotCount
		}
		if v.Flag_Etcd_V3_2.QuotaSizeBytes == 0 {
			v.Flag_Etcd_V3_2.QuotaSizeBytes = defaultEtcdQuotaSizeBytes
		}
		cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()] = v
	}
	if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_3.String()]; ok {
		if v.AgentPortToConnect == 0 {
			v.AgentPortToConnect = defaultAgentPort
		}
		if v.DatabasePortToConnect == 0 {
			v.DatabasePortToConnect = defaultEtcdClientPort
		}
		if v.Flag_Etcd_V3_3.SnapshotCount == 0 {
			v.Flag_Etcd_V3_3.SnapshotCount = defaultEtcdSnapshotCount
		}
		if v.Flag_Etcd_V3_3.QuotaSizeBytes == 0 {
			v.Flag_Etcd_V3_3.QuotaSizeBytes = defaultEtcdQuotaSizeBytes
		}
		cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_3.String()] = v
	}

	if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta.String()]; ok {
		if v.AgentPortToConnect == 0 {
			v.AgentPortToConnect = defaultAgentPort
		}
		if v.DatabasePortToConnect == 0 {
			v.DatabasePortToConnect = defaultZookeeperClientPort
		}
		v.Flag_Zookeeper_R3_5_3Beta.ClientPort = v.DatabasePortToConnect
		if v.Flag_Zookeeper_R3_5_3Beta.TickTime == 0 {
			v.Flag_Zookeeper_R3_5_3Beta.TickTime = defaultZookeeperTickTime
		}
		if v.Flag_Zookeeper_R3_5_3Beta.TickTime == 0 {
			v.Flag_Zookeeper_R3_5_3Beta.TickTime = defaultZookeeperTickTime
		}
		if v.Flag_Zookeeper_R3_5_3Beta.InitLimit == 0 {
			v.Flag_Zookeeper_R3_5_3Beta.InitLimit = defaultZookeeperInitLimit
		}
		if v.Flag_Zookeeper_R3_5_3Beta.SyncLimit == 0 {
			v.Flag_Zookeeper_R3_5_3Beta.SyncLimit = defaultZookeeperSyncLimit
		}
		if v.Flag_Zookeeper_R3_5_3Beta.SnapCount == 0 {
			v.Flag_Zookeeper_R3_5_3Beta.SnapCount = defaultZookeeperSnapCount
		}
		if v.Flag_Zookeeper_R3_5_3Beta.MaxClientConnections == 0 {
			v.Flag_Zookeeper_R3_5_3Beta.MaxClientConnections = defaultZookeeperMaxClientConnections
		}
		cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta.String()] = v
	}

	if v, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v1_0_2.String()]; ok {
		if v.AgentPortToConnect == 0 {
			v.AgentPortToConnect = defaultAgentPort
		}
		if v.DatabasePortToConnect == 0 {
			v.DatabasePortToConnect = defaultConsulClientPort
		}
		cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_consul__v1_0_2.String()] = v
	}

	// need etcd configs since it's backed by etcd
	if _, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_zetcd__beta.String()]; ok {
		_, okOther := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__other.String()]
		_, okTip := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()]
		_, ok32 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()]
		_, ok33 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_3.String()]
		if !okOther && !okTip && !ok32 && !ok33 {
			return nil, fmt.Errorf("got %q config, but no etcd config is given", dbtesterpb.DatabaseID_zetcd__beta.String())
		}
	}
	if _, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_cetcd__beta.String()]; ok {
		_, okOther := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__other.String()]
		_, okTip := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__tip.String()]
		_, ok32 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_2.String()]
		_, ok33 := cfg.DatabaseIDToConfigClientMachineAgentControl[dbtesterpb.DatabaseID_etcd__v3_3.String()]
		if !okOther && !okTip && !ok32 && !ok33 {
			return nil, fmt.Errorf("got %q config, but no etcd config is given", dbtesterpb.DatabaseID_cetcd__beta.String())
		}
	}

	if cfg.ConfigClientMachineInitial.GoogleCloudStorageKeyPath != "" && !analyze {
		bts, err = ioutil.ReadFile(cfg.ConfigClientMachineInitial.GoogleCloudStorageKeyPath)
		if err != nil {
			return nil, err
		}
		cfg.ConfigClientMachineInitial.GoogleCloudStorageKey = string(bts)
	}

	for i := range cfg.AnalyzePlotList {
		cfg.AnalyzePlotList[i].OutputPathCSV = filepath.Join(cfg.AnalyzePlotPathPrefix, cfg.AnalyzePlotList[i].Column+".csv")
		cfg.AnalyzePlotList[i].OutputPathList = make([]string, 2)
		cfg.AnalyzePlotList[i].OutputPathList[0] = filepath.Join(cfg.AnalyzePlotPathPrefix, cfg.AnalyzePlotList[i].Column+".svg")
		cfg.AnalyzePlotList[i].OutputPathList[1] = filepath.Join(cfg.AnalyzePlotPathPrefix, cfg.AnalyzePlotList[i].Column+".png")
	}

	return &cfg, nil
}

const maxEtcdQuotaSize = 8000000000

// ToRequest converts configuration to 'dbtesterpb.Request'.
func (cfg *Config) ToRequest(databaseID string, op dbtesterpb.Operation, idx int) (req *dbtesterpb.Request, err error) {
	gcfg, ok := cfg.DatabaseIDToConfigClientMachineAgentControl[databaseID]
	if !ok {
		err = fmt.Errorf("database ID %q is not defined", databaseID)
		return
	}
	did := dbtesterpb.DatabaseID(dbtesterpb.DatabaseID_value[databaseID])

	req = &dbtesterpb.Request{
		Operation:           op,
		TriggerLogUpload:    gcfg.ConfigClientMachineBenchmarkSteps.Step4UploadLogs,
		DatabaseID:          did,
		DatabaseTag:         gcfg.DatabaseTag,
		PeerIPsString:       gcfg.PeerIPsString,
		IPIndex:             uint32(idx),
		CurrentClientNumber: gcfg.ConfigClientMachineBenchmarkOptions.ClientNumber,
		ConfigClientMachineInitial: &dbtesterpb.ConfigClientMachineInitial{
			GoogleCloudProjectName:         cfg.ConfigClientMachineInitial.GoogleCloudProjectName,
			GoogleCloudStorageKey:          cfg.ConfigClientMachineInitial.GoogleCloudStorageKey,
			GoogleCloudStorageBucketName:   cfg.ConfigClientMachineInitial.GoogleCloudStorageBucketName,
			GoogleCloudStorageSubDirectory: cfg.ConfigClientMachineInitial.GoogleCloudStorageSubDirectory,
		},
	}

	switch req.DatabaseID {
	case dbtesterpb.DatabaseID_etcd__other:
		if gcfg.Flag_Etcd_Other.QuotaSizeBytes > maxEtcdQuotaSize {
			err = fmt.Errorf("maximum etcd quota is 8 GB (%d), got %d", maxEtcdQuotaSize, gcfg.Flag_Etcd_Other.QuotaSizeBytes)
			return
		}
		req.Flag_Etcd_Other = &dbtesterpb.Flag_Etcd_Other{
			SnapshotCount:  gcfg.Flag_Etcd_Other.SnapshotCount,
			QuotaSizeBytes: gcfg.Flag_Etcd_Other.QuotaSizeBytes,
		}
	case dbtesterpb.DatabaseID_etcd__tip:
		if gcfg.Flag_Etcd_Tip.QuotaSizeBytes > maxEtcdQuotaSize {
			err = fmt.Errorf("maximum etcd quota is 8 GB (%d), got %d", maxEtcdQuotaSize, gcfg.Flag_Etcd_Tip.QuotaSizeBytes)
			return
		}
		req.Flag_Etcd_Tip = &dbtesterpb.Flag_Etcd_Tip{
			SnapshotCount:  gcfg.Flag_Etcd_Tip.SnapshotCount,
			QuotaSizeBytes: gcfg.Flag_Etcd_Tip.QuotaSizeBytes,
		}
	case dbtesterpb.DatabaseID_etcd__v3_2:
		if gcfg.Flag_Etcd_V3_2.QuotaSizeBytes > maxEtcdQuotaSize {
			err = fmt.Errorf("maximum etcd quota is 8 GB (%d), got %d", maxEtcdQuotaSize, gcfg.Flag_Etcd_V3_2.QuotaSizeBytes)
			return
		}
		req.Flag_Etcd_V3_2 = &dbtesterpb.Flag_Etcd_V3_2{
			SnapshotCount:  gcfg.Flag_Etcd_V3_2.SnapshotCount,
			QuotaSizeBytes: gcfg.Flag_Etcd_V3_2.QuotaSizeBytes,
		}
	case dbtesterpb.DatabaseID_etcd__v3_3:
		if gcfg.Flag_Etcd_V3_3.QuotaSizeBytes > maxEtcdQuotaSize {
			err = fmt.Errorf("maximum etcd quota is 8 GB (%d), got %d", maxEtcdQuotaSize, gcfg.Flag_Etcd_V3_3.QuotaSizeBytes)
			return
		}
		req.Flag_Etcd_V3_3 = &dbtesterpb.Flag_Etcd_V3_3{
			SnapshotCount:  gcfg.Flag_Etcd_V3_3.SnapshotCount,
			QuotaSizeBytes: gcfg.Flag_Etcd_V3_3.QuotaSizeBytes,
		}

	case dbtesterpb.DatabaseID_zookeeper__r3_5_3_beta:
		req.Flag_Zookeeper_R3_5_3Beta = &dbtesterpb.Flag_Zookeeper_R3_5_3Beta{
			JavaDJuteMaxBuffer:   gcfg.Flag_Zookeeper_R3_5_3Beta.JavaDJuteMaxBuffer,
			JavaXms:              gcfg.Flag_Zookeeper_R3_5_3Beta.JavaXms,
			JavaXmx:              gcfg.Flag_Zookeeper_R3_5_3Beta.JavaXmx,
			MyID:                 uint32(idx + 1),
			ClientPort:           gcfg.Flag_Zookeeper_R3_5_3Beta.ClientPort,
			TickTime:             gcfg.Flag_Zookeeper_R3_5_3Beta.TickTime,
			InitLimit:            gcfg.Flag_Zookeeper_R3_5_3Beta.InitLimit,
			SyncLimit:            gcfg.Flag_Zookeeper_R3_5_3Beta.SyncLimit,
			SnapCount:            gcfg.Flag_Zookeeper_R3_5_3Beta.SnapCount,
			MaxClientConnections: gcfg.Flag_Zookeeper_R3_5_3Beta.MaxClientConnections,
		}

	case dbtesterpb.DatabaseID_consul__v1_0_2:

	case dbtesterpb.DatabaseID_zetcd__beta:
	case dbtesterpb.DatabaseID_cetcd__beta:

	default:
		err = fmt.Errorf("unknown %v", req.DatabaseID)
	}

	return
}


================================================
FILE: config_dbtester_test.go
================================================
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dbtester

import (
	"reflect"
	"testing"

	"github.com/etcd-io/dbtester/dbtesterpb"
)

func TestConfig(t *testing.T) {
	cfg, err := ReadConfig("config_dbtester_test.yaml", false)
	if err != nil {
		t.Fatal(err)
	}
	expected := &Config{
		TestTitle: "Write 1M keys, 256-byte key, 1KB value value, clients 1 to 1,000",
		TestDescription: `- Google Cloud Compute Engine
- 4 machines of 16 vCPUs + 60 GB Memory + 300 GB SSD (1 for client)
- Ubuntu 16.10
- etcd tip (Go 1.8.0)
- Zookeeper r3.5.3-beta
  - Java 8
  - javac 1.8.0_121
  - Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
  - Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
  - ` + "`/usr/bin/java -Djute.maxbuffer=33554432 -Xms50G -Xmx50G`" + `
- Consul v1.0.2 (Go 1.8.0)
`,
		ConfigClientMachineInitial: dbtesterpb.ConfigClientMachineInitial{
			PathPrefix:                              "/home/gyuho",
			LogPath:                                 "/home/gyuho/client-control.log",
			ClientSystemMetricsPath:                 "/home/gyuho/client-system-metrics.csv",
			ClientSystemMetricsInterpolatedPath:     "/home/gyuho/client-system-metrics-interpolated.csv",
			ClientLatencyThroughputTimeseriesPath:   "/home/gyuho/client-latency-throughput-timeseries.csv",
			ClientLatencyDistributionAllPath:        "/home/gyuho/client-latency-distribution-all.csv",
			ClientLatencyDistributionPercentilePath: "/home/gyuho/client-latency-distribution-percentile.csv",
			ClientLatencyDistributionSummaryPath:    "/home/gyuho/client-latency-distribution-summary.csv",
			ClientLatencyByKeyNumberPath:            "/home/gyuho/client-latency-by-key-number.csv",
			ServerDiskSpaceUsageSummaryPath:         "/home/gyuho/server-disk-space-usage-summary.csv",
			GoogleCloudProjectName:                  "etcd-development",
			GoogleCloudStorageKeyPath:               "config-dbtester-gcloud-key.json",
			GoogleCloudStorageKey:                   "test-key",
			GoogleCloudStorageBucketName:            "dbtester-results",
			GoogleCloudStorageSubDirectory:          "2017Q1-01-etcd-zookeeper-consul/01-write-1M-keys-client-variable",
		},
		AllDatabaseIDList: []string{"etcd__tip", "zookeeper__r3_5_3_beta", "consul__v1_0_2"},
		DatabaseIDToConfigClientMachineAgentControl: map[string]dbtesterpb.ConfigClientMachineAgentControl{
			"etcd__tip": {
				DatabaseID:            "etcd__tip",
				DatabaseTag:           "etcd-tip-go1.8.0",
				DatabaseDescription:   "etcd tip (Go 1.8.0)",
				PeerIPs:               []string{"10.240.0.7", "10.240.0.8", "10.240.0.12"},
				PeerIPsString:         "10.240.0.7___10.240.0.8___10.240.0.12",
				DatabasePortToConnect: 2379,
				DatabaseEndpoints:     []string{"10.240.0.7:2379", "10.240.0.8:2379", "10.240.0.12:2379"},
				AgentPortToConnect:    3500,
				AgentEndpoints:        []string{"10.240.0.7:3500", "10.240.0.8:3500", "10.240.0.12:3500"},
				Flag_Etcd_Tip: &dbtesterpb.Flag_Etcd_Tip{
					SnapshotCount:  100000,
					QuotaSizeBytes: 8000000000,
				},
				ConfigClientMachineBenchmarkOptions: &dbtesterpb.ConfigClientMachineBenchmarkOptions{
					Type:                       "write",
					RequestNumber:              1000000,
					ConnectionNumber:           0,
					ClientNumber:               0,
					ConnectionClientNumbers:    []int64{1, 10, 50, 100, 300, 500, 700, 1000},
					RateLimitRequestsPerSecond: 0,
					SameKey:                    false,
					KeySizeBytes:               256,
					ValueSizeBytes:             1024,
					StaleRead:                  false,
				},
				ConfigClientMachineBenchmarkSteps: &dbtesterpb.ConfigClientMachineBenchmarkSteps{
					Step1StartDatabase:  true,
					Step2StressDatabase: true,
					Step3StopDatabase:   true,
					Step4UploadLogs:     true,
				},
			},
			"zookeeper__r3_5_3_beta": {
				DatabaseID:            "zookeeper__r3_5_3_beta",
				DatabaseTag:           "zookeeper-r3.5.3-beta-java8",
				DatabaseDescription:   "Zookeeper r3.5.3-beta (Java 8)",
				PeerIPs:               []string{"10.240.0.21", "10.240.0.22", "10.240.0.23"},
				PeerIPsString:         "10.240.0.21___10.240.0.22___10.240.0.23",
				DatabasePortToConnect: 2181,
				DatabaseEndpoints:     []string{"10.240.0.21:2181", "10.240.0.22:2181", "10.240.0.23:2181"},
				AgentPortToConnect:    3500,
				AgentEndpoints:        []string{"10.240.0.21:3500", "10.240.0.22:3500", "10.240.0.23:3500"},
				Flag_Zookeeper_R3_5_3Beta: &dbtesterpb.Flag_Zookeeper_R3_5_3Beta{
					JavaDJuteMaxBuffer:   33554432,
					JavaXms:              "50G",
					JavaXmx:              "50G",
					ClientPort:           2181,
					TickTime:             2000,
					InitLimit:            5,
					SyncLimit:            5,
					SnapCount:            100000,
					MaxClientConnections: 5000,
				},
				ConfigClientMachineBenchmarkOptions: &dbtesterpb.ConfigClientMachineBenchmarkOptions{
					Type:                       "write",
					RequestNumber:              1000000,
					ConnectionNumber:           0,
					ClientNumber:               0,
					ConnectionClientNumbers:    []int64{1, 10, 50, 100, 300, 500, 700, 1000},
					RateLimitRequestsPerSecond: 0,
					SameKey:                    false,
					KeySizeBytes:               256,
					ValueSizeBytes:             1024,
					StaleRead:                  false,
				},
				ConfigClientMachineBenchmarkSteps: &dbtesterpb.ConfigClientMachineBenchmarkSteps{
					Step1StartDatabase:  true,
					Step2StressDatabase: true,
					Step3StopDatabase:   true,
					Step4UploadLogs:     true,
				},
			},
			"consul__v1_0_2": {
				DatabaseID:            "consul__v1_0_2",
				DatabaseTag:           "consul-v1.0.2-go1.8.0",
				DatabaseDescription:   "Consul v1.0.2 (Go 1.8.0)",
				PeerIPs:               []string{"10.240.0.27", "10.240.0.28", "10.240.0.29"},
				PeerIPsString:         "10.240.0.27___10.240.0.28___10.240.0.29",
				DatabasePortToConnect: 8500,
				DatabaseEndpoints:     []string{"10.240.0.27:8500", "10.240.0.28:8500", "10.240.0.29:8500"},
				AgentPortToConnect:    3500,
				AgentEndpoints:        []string{"10.240.0.27:3500", "10.240.0.28:3500", "10.240.0.29:3500"},
				ConfigClientMachineBenchmarkOptions: &dbtesterpb.ConfigClientMachineBenchmarkOptions{
					Type:                       "write",
					RequestNumber:              1000000,
					ConnectionNumber:           0,
					ClientNumber:               0,
					ConnectionClientNumbers:    []int64{1, 10, 50, 100, 300, 500, 700, 1000},
					RateLimitRequestsPerSecond: 0,
					SameKey:                    false,
					KeySizeBytes:               256,
					ValueSizeBytes:             1024,
					StaleRead:                  false,
				},
				ConfigClientMachineBenchmarkSteps: &dbtesterpb.ConfigClientMachineBenchmarkSteps{
					Step1StartDatabase:  true,
					Step2StressDatabase: true,
					Step3Stop
Download .txt
gitextract_jgj486as/

├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── DCO
├── Gopkg.toml
├── LICENSE
├── NOTICE
├── README.md
├── agent/
│   ├── agent_cetcd.go
│   ├── agent_consul.go
│   ├── agent_etcd.go
│   ├── agent_zetcd.go
│   ├── agent_zookeeper.go
│   ├── command.go
│   ├── doc.go
│   ├── server.go
│   ├── server_system_metrics.go
│   ├── upload_log.go
│   └── util.go
├── analyze/
│   ├── 01_read_raw_data_to_test_data.go
│   ├── 02_read_all_metrics_to_analyze_data.go
│   ├── 03_read_benchmark_metrics_to_analyze_data.go
│   ├── 04_aggregate_all_analyze_data.go
│   ├── 05_plot.go
│   ├── command.go
│   ├── doc.go
│   ├── logger.go
│   └── util.go
├── broadcast_request.go
├── cmd/
│   └── dbtester/
│       └── main.go
├── code-of-conduct.md
├── config-dbtester-gcloud-key.json
├── config_dbtester.go
├── config_dbtester_test.go
├── config_dbtester_test.yaml
├── control/
│   ├── command.go
│   └── logger.go
├── dbtesterpb/
│   ├── config_analyze_machine.pb.go
│   ├── config_analyze_machine.proto
│   ├── config_client_machine.pb.go
│   ├── config_client_machine.proto
│   ├── database_id.pb.go
│   ├── database_id.proto
│   ├── flag_cetcd.pb.go
│   ├── flag_cetcd.proto
│   ├── flag_consul.pb.go
│   ├── flag_consul.proto
│   ├── flag_etcd.pb.go
│   ├── flag_etcd.proto
│   ├── flag_zetcd.pb.go
│   ├── flag_zetcd.proto
│   ├── flag_zookeeper.pb.go
│   ├── flag_zookeeper.proto
│   ├── message.pb.go
│   ├── message.proto
│   └── util.go
├── find_ranges.go
├── find_ranges_test.go
├── pkg/
│   ├── fileinspect/
│   │   ├── fileinspect.go
│   │   └── fileinspect_test.go
│   ├── ntp/
│   │   ├── ntp.go
│   │   └── ntp_test.go
│   └── remotestorage/
│       ├── doc.go
│       ├── example/
│       │   ├── agent.log
│       │   ├── key.json
│       │   └── main.go
│       ├── op.go
│       ├── uploader.go
│       └── util.go
├── readme.go
├── report.go
├── report_save_upload.go
├── scripts/
│   ├── dbtester-google-cloud.sh
│   ├── genproto.sh
│   ├── install-cetcd.sh
│   ├── install-consul.sh
│   ├── install-etcd.sh
│   ├── install-go.sh
│   ├── install-zetcd.sh
│   ├── install-zookeeper-ubuntu.sh
│   ├── tests.sh
│   └── updatedep.sh
├── stress.go
├── stress_client.go
├── stress_client_consul.go
├── stress_client_etcdv3.go
├── stress_client_zookeeper.go
├── test-configs/
│   ├── read-3M-same-keys-1K-client.yaml
│   ├── read-3M-same-keys-best-throughput-etcd.yaml
│   ├── read-3M-same-keys-best-throughput.yaml
│   ├── write-100K-keys-1-client.yaml
│   ├── write-1M-keys-1000QPS.yaml
│   ├── write-1M-keys-best-throughput.yaml
│   ├── write-1M-keys-client-variable.yaml
│   └── write-too-many-keys.yaml
├── test-results/
│   ├── 2017Q1-00-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2017Q1-01-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2017Q2-01-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2017Q2-02-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2018Q1-01-etcd/
│   │   └── README.md
│   ├── 2018Q1-02-etcd-zookeeper-consul/
│   │   └── README.md
│   ├── 2018Q1-03-etcd-kubemark/
│   │   └── README.md
│   ├── 2018Q1-04-etcd-zookeeper/
│   │   └── README.md
│   ├── 2018Q2-01-etcd-client-balancer/
│   │   ├── README.md
│   │   ├── read-3M-same-keys-best-throughput.yaml
│   │   └── write-1M-keys-best-throughput.yaml
│   └── 2018Q2-02-etcd-client-balancer/
│       ├── README.md
│       ├── read-3M-same-keys-best-throughput.yaml
│       └── write-1M-keys-best-throughput.yaml
├── util.go
├── util_test.go
└── vendor/
    ├── bitbucket.org/
    │   └── zombiezen/
    │       └── gopdf/
    │           ├── LICENSE
    │           └── pdf/
    │               ├── canvas.go
    │               ├── doc.go
    │               ├── encode.go
    │               ├── image.go
    │               ├── marshal.go
    │               ├── metrics.go
    │               ├── objects.go
    │               ├── pdf.go
    │               ├── stream.go
    │               └── text.go
    ├── cloud.google.com/
    │   └── go/
    │       ├── LICENSE
    │       ├── cloud.go
    │       ├── compute/
    │       │   └── metadata/
    │       │       └── metadata.go
    │       ├── iam/
    │       │   └── iam.go
    │       ├── internal/
    │       │   ├── annotate.go
    │       │   ├── optional/
    │       │   │   └── optional.go
    │       │   ├── retry.go
    │       │   └── version/
    │       │       └── version.go
    │       └── storage/
    │           ├── acl.go
    │           ├── bucket.go
    │           ├── copy.go
    │           ├── doc.go
    │           ├── go110.go
    │           ├── go17.go
    │           ├── iam.go
    │           ├── invoke.go
    │           ├── not_go110.go
    │           ├── not_go17.go
    │           ├── notifications.go
    │           ├── reader.go
    │           ├── storage.go
    │           └── writer.go
    ├── github.com/
    │   ├── ajstarks/
    │   │   └── svgo/
    │   │       ├── LICENSE
    │   │       ├── doc.go
    │   │       └── svg.go
    │   ├── cheggaaa/
    │   │   └── pb/
    │   │       ├── LICENSE
    │   │       ├── format.go
    │   │       ├── pb.go
    │   │       ├── pb_appengine.go
    │   │       ├── pb_win.go
    │   │       ├── pb_x.go
    │   │       ├── pool.go
    │   │       ├── pool_win.go
    │   │       ├── pool_x.go
    │   │       ├── reader.go
    │   │       ├── runecount.go
    │   │       ├── termios_bsd.go
    │   │       └── termios_sysv.go
    │   ├── coreos/
    │   │   ├── etcd/
    │   │   │   ├── LICENSE
    │   │   │   ├── NOTICE
    │   │   │   ├── auth/
    │   │   │   │   ├── authpb/
    │   │   │   │   │   └── auth.pb.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── jwt.go
    │   │   │   │   ├── nop.go
    │   │   │   │   ├── range_perm_cache.go
    │   │   │   │   ├── simple_token.go
    │   │   │   │   └── store.go
    │   │   │   ├── client/
    │   │   │   │   ├── auth_role.go
    │   │   │   │   ├── auth_user.go
    │   │   │   │   ├── cancelreq.go
    │   │   │   │   ├── client.go
    │   │   │   │   ├── cluster_error.go
    │   │   │   │   ├── curl.go
    │   │   │   │   ├── discover.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── keys.generated.go
    │   │   │   │   ├── keys.go
    │   │   │   │   ├── members.go
    │   │   │   │   └── util.go
    │   │   │   ├── clientv3/
    │   │   │   │   ├── auth.go
    │   │   │   │   ├── balancer/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   └── grpc1.7-health.go
    │   │   │   │   ├── client.go
    │   │   │   │   ├── cluster.go
    │   │   │   │   ├── compact_op.go
    │   │   │   │   ├── compare.go
    │   │   │   │   ├── config.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── kv.go
    │   │   │   │   ├── lease.go
    │   │   │   │   ├── logger.go
    │   │   │   │   ├── maintenance.go
    │   │   │   │   ├── op.go
    │   │   │   │   ├── options.go
    │   │   │   │   ├── ready_wait.go
    │   │   │   │   ├── retry.go
    │   │   │   │   ├── sort.go
    │   │   │   │   ├── txn.go
    │   │   │   │   └── watch.go
    │   │   │   ├── etcdserver/
    │   │   │   │   ├── api/
    │   │   │   │   │   ├── capability.go
    │   │   │   │   │   ├── cluster.go
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   └── v3rpc/
    │   │   │   │   │       ├── auth.go
    │   │   │   │   │       ├── codec.go
    │   │   │   │   │       ├── grpc.go
    │   │   │   │   │       ├── header.go
    │   │   │   │   │       ├── interceptor.go
    │   │   │   │   │       ├── key.go
    │   │   │   │   │       ├── lease.go
    │   │   │   │   │       ├── maintenance.go
    │   │   │   │   │       ├── member.go
    │   │   │   │   │       ├── metrics.go
    │   │   │   │   │       ├── quota.go
    │   │   │   │   │       ├── rpctypes/
    │   │   │   │   │       │   ├── doc.go
    │   │   │   │   │       │   ├── error.go
    │   │   │   │   │       │   ├── md.go
    │   │   │   │   │       │   └── metadatafields.go
    │   │   │   │   │       ├── util.go
    │   │   │   │   │       └── watch.go
    │   │   │   │   ├── apply.go
    │   │   │   │   ├── apply_auth.go
    │   │   │   │   ├── apply_v2.go
    │   │   │   │   ├── backend.go
    │   │   │   │   ├── cluster_util.go
    │   │   │   │   ├── config.go
    │   │   │   │   ├── consistent_index.go
    │   │   │   │   ├── corrupt.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── errors.go
    │   │   │   │   ├── etcdserverpb/
    │   │   │   │   │   ├── etcdserver.pb.go
    │   │   │   │   │   ├── raft_internal.pb.go
    │   │   │   │   │   ├── raft_internal_stringer.go
    │   │   │   │   │   └── rpc.pb.go
    │   │   │   │   ├── metrics.go
    │   │   │   │   ├── quota.go
    │   │   │   │   ├── raft.go
    │   │   │   │   ├── server.go
    │   │   │   │   ├── server_access_control.go
    │   │   │   │   ├── snapshot_merge.go
    │   │   │   │   ├── storage.go
    │   │   │   │   ├── util.go
    │   │   │   │   ├── v2_server.go
    │   │   │   │   └── v3_server.go
    │   │   │   ├── main.go
    │   │   │   ├── mvcc/
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── index.go
    │   │   │   │   ├── key_index.go
    │   │   │   │   ├── kv.go
    │   │   │   │   ├── kv_view.go
    │   │   │   │   ├── kvstore.go
    │   │   │   │   ├── kvstore_compaction.go
    │   │   │   │   ├── kvstore_txn.go
    │   │   │   │   ├── metrics.go
    │   │   │   │   ├── metrics_txn.go
    │   │   │   │   ├── mvccpb/
    │   │   │   │   │   └── kv.pb.go
    │   │   │   │   ├── revision.go
    │   │   │   │   ├── util.go
    │   │   │   │   ├── watchable_store.go
    │   │   │   │   ├── watchable_store_txn.go
    │   │   │   │   ├── watcher.go
    │   │   │   │   └── watcher_group.go
    │   │   │   ├── pkg/
    │   │   │   │   ├── cpuutil/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   └── endian.go
    │   │   │   │   ├── logutil/
    │   │   │   │   │   ├── discard_logger.go
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   ├── logger.go
    │   │   │   │   │   ├── merge_logger.go
    │   │   │   │   │   ├── package_logger.go
    │   │   │   │   │   ├── zap_grpc.go
    │   │   │   │   │   ├── zap_journal.go
    │   │   │   │   │   └── zap_raft.go
    │   │   │   │   ├── netutil/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   ├── isolate_linux.go
    │   │   │   │   │   ├── isolate_stub.go
    │   │   │   │   │   ├── netutil.go
    │   │   │   │   │   ├── routes.go
    │   │   │   │   │   └── routes_linux.go
    │   │   │   │   ├── report/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   ├── report.go
    │   │   │   │   │   ├── timeseries.go
    │   │   │   │   │   └── weighted.go
    │   │   │   │   ├── systemd/
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   └── journal.go
    │   │   │   │   └── types/
    │   │   │   │       ├── doc.go
    │   │   │   │       ├── id.go
    │   │   │   │       ├── set.go
    │   │   │   │       ├── slice.go
    │   │   │   │       ├── urls.go
    │   │   │   │       └── urlsmap.go
    │   │   │   └── raft/
    │   │   │       ├── doc.go
    │   │   │       ├── log.go
    │   │   │       ├── log_unstable.go
    │   │   │       ├── logger.go
    │   │   │       ├── node.go
    │   │   │       ├── progress.go
    │   │   │       ├── raft.go
    │   │   │       ├── raftpb/
    │   │   │       │   └── raft.pb.go
    │   │   │       ├── rawnode.go
    │   │   │       ├── read_only.go
    │   │   │       ├── status.go
    │   │   │       ├── storage.go
    │   │   │       └── util.go
    │   │   ├── go-systemd/
    │   │   │   ├── LICENSE
    │   │   │   └── journal/
    │   │   │       └── journal.go
    │   │   └── pkg/
    │   │       ├── LICENSE
    │   │       ├── NOTICE
    │   │       └── capnslog/
    │   │           ├── formatters.go
    │   │           ├── glog_formatter.go
    │   │           ├── init.go
    │   │           ├── init_windows.go
    │   │           ├── journald_formatter.go
    │   │           ├── log_hijack.go
    │   │           ├── logmap.go
    │   │           ├── pkg_logger.go
    │   │           └── syslog_formatter.go
    │   ├── dustin/
    │   │   └── go-humanize/
    │   │       ├── LICENSE
    │   │       ├── big.go
    │   │       ├── bigbytes.go
    │   │       ├── bytes.go
    │   │       ├── comma.go
    │   │       ├── commaf.go
    │   │       ├── ftoa.go
    │   │       ├── humanize.go
    │   │       ├── number.go
    │   │       ├── ordinals.go
    │   │       ├── si.go
    │   │       └── times.go
    │   ├── gogo/
    │   │   └── protobuf/
    │   │       ├── LICENSE
    │   │       ├── gogoproto/
    │   │       │   ├── doc.go
    │   │       │   ├── gogo.pb.go
    │   │       │   └── helper.go
    │   │       ├── proto/
    │   │       │   ├── clone.go
    │   │       │   ├── decode.go
    │   │       │   ├── decode_gogo.go
    │   │       │   ├── duration.go
    │   │       │   ├── duration_gogo.go
    │   │       │   ├── encode.go
    │   │       │   ├── encode_gogo.go
    │   │       │   ├── equal.go
    │   │       │   ├── extensions.go
    │   │       │   ├── extensions_gogo.go
    │   │       │   ├── lib.go
    │   │       │   ├── lib_gogo.go
    │   │       │   ├── message_set.go
    │   │       │   ├── pointer_reflect.go
    │   │       │   ├── pointer_reflect_gogo.go
    │   │       │   ├── pointer_unsafe.go
    │   │       │   ├── pointer_unsafe_gogo.go
    │   │       │   ├── properties.go
    │   │       │   ├── properties_gogo.go
    │   │       │   ├── skip_gogo.go
    │   │       │   ├── text.go
    │   │       │   ├── text_gogo.go
    │   │       │   ├── text_parser.go
    │   │       │   ├── timestamp.go
    │   │       │   └── timestamp_gogo.go
    │   │       └── protoc-gen-gogo/
    │   │           ├── descriptor/
    │   │           │   ├── descriptor.go
    │   │           │   ├── descriptor.pb.go
    │   │           │   ├── descriptor_gostring.gen.go
    │   │           │   └── helper.go
    │   │           ├── doc.go
    │   │           └── main.go
    │   ├── golang/
    │   │   ├── freetype/
    │   │   │   ├── LICENSE
    │   │   │   ├── freetype.go
    │   │   │   ├── licenses/
    │   │   │   │   ├── ftl.txt
    │   │   │   │   └── gpl.txt
    │   │   │   ├── raster/
    │   │   │   │   ├── geom.go
    │   │   │   │   ├── paint.go
    │   │   │   │   ├── raster.go
    │   │   │   │   └── stroke.go
    │   │   │   └── truetype/
    │   │   │       ├── face.go
    │   │   │       ├── glyph.go
    │   │   │       ├── hint.go
    │   │   │       ├── opcodes.go
    │   │   │       └── truetype.go
    │   │   └── protobuf/
    │   │       ├── LICENSE
    │   │       ├── proto/
    │   │       │   ├── clone.go
    │   │       │   ├── decode.go
    │   │       │   ├── encode.go
    │   │       │   ├── equal.go
    │   │       │   ├── extensions.go
    │   │       │   ├── lib.go
    │   │       │   ├── message_set.go
    │   │       │   ├── pointer_reflect.go
    │   │       │   ├── pointer_unsafe.go
    │   │       │   ├── properties.go
    │   │       │   ├── text.go
    │   │       │   └── text_parser.go
    │   │       ├── protoc-gen-go/
    │   │       │   ├── descriptor/
    │   │       │   │   └── descriptor.pb.go
    │   │       │   ├── doc.go
    │   │       │   ├── link_grpc.go
    │   │       │   └── main.go
    │   │       └── ptypes/
    │   │           ├── any/
    │   │           │   └── any.pb.go
    │   │           ├── any.go
    │   │           ├── doc.go
    │   │           ├── duration/
    │   │           │   └── duration.pb.go
    │   │           ├── duration.go
    │   │           ├── timestamp/
    │   │           │   └── timestamp.pb.go
    │   │           └── timestamp.go
    │   ├── googleapis/
    │   │   └── gax-go/
    │   │       ├── LICENSE
    │   │       ├── call_option.go
    │   │       ├── gax.go
    │   │       ├── header.go
    │   │       └── invoke.go
    │   ├── gyuho/
    │   │   ├── dataframe/
    │   │   │   ├── LICENSE
    │   │   │   ├── column.go
    │   │   │   ├── dataframe.go
    │   │   │   ├── doc.go
    │   │   │   ├── sorter.go
    │   │   │   ├── util.go
    │   │   │   ├── value.go
    │   │   │   ├── value_data_type.go
    │   │   │   ├── value_sort.go
    │   │   │   ├── value_string.go
    │   │   │   └── value_time.go
    │   │   └── linux-inspect/
    │   │       ├── LICENSE
    │   │       ├── df/
    │   │       │   ├── df.go
    │   │       │   ├── doc.go
    │   │       │   ├── generated.go
    │   │       │   └── schema.go
    │   │       ├── inspect/
    │   │       │   ├── binary_search.go
    │   │       │   ├── doc.go
    │   │       │   ├── ds.go
    │   │       │   ├── ns.go
    │   │       │   ├── op.go
    │   │       │   ├── proc.go
    │   │       │   ├── proc_csv.go
    │   │       │   ├── proc_csv_interpolate.go
    │   │       │   ├── ps.go
    │   │       │   └── ss.go
    │   │       ├── pkg/
    │   │       │   ├── fileutil/
    │   │       │   │   └── fileutil.go
    │   │       │   └── timeutil/
    │   │       │       └── timeutil.go
    │   │       ├── proc/
    │   │       │   ├── diskstats.go
    │   │       │   ├── doc.go
    │   │       │   ├── generated.go
    │   │       │   ├── io.go
    │   │       │   ├── list.go
    │   │       │   ├── load_avg.go
    │   │       │   ├── net_dev.go
    │   │       │   ├── net_tcp.go
    │   │       │   ├── parse_ip.go
    │   │       │   ├── schema.go
    │   │       │   ├── stat.go
    │   │       │   ├── status.go
    │   │       │   ├── uptime.go
    │   │       │   └── utils.go
    │   │       ├── schema/
    │   │       │   └── schema.go
    │   │       └── top/
    │   │           ├── doc.go
    │   │           ├── generated.go
    │   │           ├── parse.go
    │   │           ├── schema.go
    │   │           ├── stream.go
    │   │           └── top.go
    │   ├── hashicorp/
    │   │   ├── consul/
    │   │   │   ├── LICENSE
    │   │   │   ├── api/
    │   │   │   │   ├── acl.go
    │   │   │   │   ├── agent.go
    │   │   │   │   ├── api.go
    │   │   │   │   ├── catalog.go
    │   │   │   │   ├── coordinate.go
    │   │   │   │   ├── event.go
    │   │   │   │   ├── health.go
    │   │   │   │   ├── kv.go
    │   │   │   │   ├── lock.go
    │   │   │   │   ├── operator.go
    │   │   │   │   ├── operator_area.go
    │   │   │   │   ├── operator_autopilot.go
    │   │   │   │   ├── operator_keyring.go
    │   │   │   │   ├── operator_raft.go
    │   │   │   │   ├── operator_segment.go
    │   │   │   │   ├── prepared_query.go
    │   │   │   │   ├── raw.go
    │   │   │   │   ├── semaphore.go
    │   │   │   │   ├── session.go
    │   │   │   │   ├── snapshot.go
    │   │   │   │   └── status.go
    │   │   │   └── main.go
    │   │   ├── go-cleanhttp/
    │   │   │   ├── LICENSE
    │   │   │   ├── cleanhttp.go
    │   │   │   ├── doc.go
    │   │   │   └── handlers.go
    │   │   ├── go-rootcerts/
    │   │   │   ├── LICENSE
    │   │   │   ├── doc.go
    │   │   │   ├── rootcerts.go
    │   │   │   ├── rootcerts_base.go
    │   │   │   └── rootcerts_darwin.go
    │   │   └── serf/
    │   │       ├── LICENSE
    │   │       └── coordinate/
    │   │           ├── client.go
    │   │           ├── config.go
    │   │           ├── coordinate.go
    │   │           └── phantom.go
    │   ├── inconshreveable/
    │   │   └── mousetrap/
    │   │       ├── LICENSE
    │   │       ├── trap_others.go
    │   │       ├── trap_windows.go
    │   │       └── trap_windows_1.4.go
    │   ├── kr/
    │   │   └── pty/
    │   │       ├── License
    │   │       ├── doc.go
    │   │       ├── ioctl.go
    │   │       ├── ioctl_bsd.go
    │   │       ├── pty_darwin.go
    │   │       ├── pty_dragonfly.go
    │   │       ├── pty_freebsd.go
    │   │       ├── pty_linux.go
    │   │       ├── pty_unsupported.go
    │   │       ├── run.go
    │   │       ├── types.go
    │   │       ├── types_dragonfly.go
    │   │       ├── types_freebsd.go
    │   │       ├── util.go
    │   │       ├── ztypes_386.go
    │   │       ├── ztypes_amd64.go
    │   │       ├── ztypes_arm.go
    │   │       ├── ztypes_arm64.go
    │   │       ├── ztypes_dragonfly_amd64.go
    │   │       ├── ztypes_freebsd_386.go
    │   │       ├── ztypes_freebsd_amd64.go
    │   │       ├── ztypes_freebsd_arm.go
    │   │       ├── ztypes_mipsx.go
    │   │       ├── ztypes_ppc64.go
    │   │       ├── ztypes_ppc64le.go
    │   │       └── ztypes_s390x.go
    │   ├── llgcode/
    │   │   └── draw2d/
    │   │       ├── LICENSE
    │   │       ├── draw2d.go
    │   │       ├── draw2dbase/
    │   │       │   ├── curve.go
    │   │       │   ├── dasher.go
    │   │       │   ├── demux_flattener.go
    │   │       │   ├── flattener.go
    │   │       │   ├── line.go
    │   │       │   ├── stack_gc.go
    │   │       │   ├── stroker.go
    │   │       │   └── text.go
    │   │       ├── draw2dimg/
    │   │       │   ├── fileutil.go
    │   │       │   ├── ftgc.go
    │   │       │   ├── ftpath.go
    │   │       │   └── text.go
    │   │       ├── font.go
    │   │       ├── gc.go
    │   │       ├── matrix.go
    │   │       └── path.go
    │   ├── mattn/
    │   │   └── go-runewidth/
    │   │       ├── LICENSE
    │   │       ├── runewidth.go
    │   │       ├── runewidth_js.go
    │   │       ├── runewidth_posix.go
    │   │       └── runewidth_windows.go
    │   ├── mitchellh/
    │   │   └── go-homedir/
    │   │       ├── LICENSE
    │   │       └── homedir.go
    │   ├── olekukonko/
    │   │   └── tablewriter/
    │   │       ├── LICENCE.md
    │   │       ├── csv.go
    │   │       ├── table.go
    │   │       ├── table_with_color.go
    │   │       ├── util.go
    │   │       └── wrap.go
    │   ├── samuel/
    │   │   └── go-zookeeper/
    │   │       ├── LICENSE
    │   │       └── zk/
    │   │           ├── conn.go
    │   │           ├── constants.go
    │   │           ├── dnshostprovider.go
    │   │           ├── flw.go
    │   │           ├── lock.go
    │   │           ├── server_help.go
    │   │           ├── server_java.go
    │   │           ├── structs.go
    │   │           └── util.go
    │   └── spf13/
    │       ├── cobra/
    │       │   ├── LICENSE.txt
    │       │   ├── args.go
    │       │   ├── bash_completions.go
    │       │   ├── cobra.go
    │       │   ├── command.go
    │       │   ├── command_notwin.go
    │       │   ├── command_win.go
    │       │   └── zsh_completions.go
    │       └── pflag/
    │           ├── LICENSE
    │           ├── bool.go
    │           ├── bool_slice.go
    │           ├── count.go
    │           ├── duration.go
    │           ├── flag.go
    │           ├── float32.go
    │           ├── float64.go
    │           ├── golangflag.go
    │           ├── int.go
    │           ├── int32.go
    │           ├── int64.go
    │           ├── int8.go
    │           ├── int_slice.go
    │           ├── ip.go
    │           ├── ip_slice.go
    │           ├── ipmask.go
    │           ├── ipnet.go
    │           ├── string.go
    │           ├── string_array.go
    │           ├── string_slice.go
    │           ├── uint.go
    │           ├── uint16.go
    │           ├── uint32.go
    │           ├── uint64.go
    │           ├── uint8.go
    │           └── uint_slice.go
    ├── go.uber.org/
    │   ├── atomic/
    │   │   ├── LICENSE.txt
    │   │   ├── atomic.go
    │   │   └── string.go
    │   ├── multierr/
    │   │   ├── LICENSE.txt
    │   │   └── error.go
    │   └── zap/
    │       ├── LICENSE.txt
    │       ├── array.go
    │       ├── buffer/
    │       │   ├── buffer.go
    │       │   └── pool.go
    │       ├── config.go
    │       ├── doc.go
    │       ├── encoder.go
    │       ├── error.go
    │       ├── field.go
    │       ├── flag.go
    │       ├── global.go
    │       ├── http_handler.go
    │       ├── internal/
    │       │   ├── bufferpool/
    │       │   │   └── bufferpool.go
    │       │   ├── color/
    │       │   │   └── color.go
    │       │   └── exit/
    │       │       └── exit.go
    │       ├── level.go
    │       ├── logger.go
    │       ├── options.go
    │       ├── stacktrace.go
    │       ├── sugar.go
    │       ├── time.go
    │       ├── writer.go
    │       └── zapcore/
    │           ├── console_encoder.go
    │           ├── core.go
    │           ├── doc.go
    │           ├── encoder.go
    │           ├── entry.go
    │           ├── error.go
    │           ├── field.go
    │           ├── hook.go
    │           ├── json_encoder.go
    │           ├── level.go
    │           ├── level_strings.go
    │           ├── marshaler.go
    │           ├── memory_encoder.go
    │           ├── sampler.go
    │           ├── tee.go
    │           └── write_syncer.go
    ├── golang.org/
    │   └── x/
    │       ├── image/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── draw/
    │       │   │   ├── draw.go
    │       │   │   ├── gen.go
    │       │   │   ├── go1_8.go
    │       │   │   ├── go1_9.go
    │       │   │   ├── impl.go
    │       │   │   └── scale.go
    │       │   ├── font/
    │       │   │   └── font.go
    │       │   ├── math/
    │       │   │   ├── f64/
    │       │   │   │   └── f64.go
    │       │   │   └── fixed/
    │       │   │       └── fixed.go
    │       │   └── tiff/
    │       │       ├── buffer.go
    │       │       ├── compress.go
    │       │       ├── consts.go
    │       │       ├── lzw/
    │       │       │   └── reader.go
    │       │       ├── reader.go
    │       │       └── writer.go
    │       ├── net/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── context/
    │       │   │   ├── context.go
    │       │   │   ├── ctxhttp/
    │       │   │   │   ├── ctxhttp.go
    │       │   │   │   └── ctxhttp_pre17.go
    │       │   │   ├── go17.go
    │       │   │   ├── go19.go
    │       │   │   ├── pre_go17.go
    │       │   │   └── pre_go19.go
    │       │   ├── http2/
    │       │   │   ├── ciphers.go
    │       │   │   ├── client_conn_pool.go
    │       │   │   ├── configure_transport.go
    │       │   │   ├── databuffer.go
    │       │   │   ├── errors.go
    │       │   │   ├── flow.go
    │       │   │   ├── frame.go
    │       │   │   ├── go16.go
    │       │   │   ├── go17.go
    │       │   │   ├── go17_not18.go
    │       │   │   ├── go18.go
    │       │   │   ├── go19.go
    │       │   │   ├── gotrack.go
    │       │   │   ├── headermap.go
    │       │   │   ├── hpack/
    │       │   │   │   ├── encode.go
    │       │   │   │   ├── hpack.go
    │       │   │   │   ├── huffman.go
    │       │   │   │   └── tables.go
    │       │   │   ├── http2.go
    │       │   │   ├── not_go16.go
    │       │   │   ├── not_go17.go
    │       │   │   ├── not_go18.go
    │       │   │   ├── not_go19.go
    │       │   │   ├── pipe.go
    │       │   │   ├── server.go
    │       │   │   ├── transport.go
    │       │   │   ├── write.go
    │       │   │   ├── writesched.go
    │       │   │   ├── writesched_priority.go
    │       │   │   └── writesched_random.go
    │       │   ├── idna/
    │       │   │   ├── idna.go
    │       │   │   ├── punycode.go
    │       │   │   ├── tables.go
    │       │   │   ├── trie.go
    │       │   │   └── trieval.go
    │       │   ├── internal/
    │       │   │   └── timeseries/
    │       │   │       └── timeseries.go
    │       │   ├── lex/
    │       │   │   └── httplex/
    │       │   │       └── httplex.go
    │       │   └── trace/
    │       │       ├── events.go
    │       │       ├── histogram.go
    │       │       ├── trace.go
    │       │       ├── trace_go16.go
    │       │       └── trace_go17.go
    │       ├── oauth2/
    │       │   ├── LICENSE
    │       │   ├── google/
    │       │   │   ├── appengine.go
    │       │   │   ├── appengine_hook.go
    │       │   │   ├── appengineflex_hook.go
    │       │   │   ├── default.go
    │       │   │   ├── google.go
    │       │   │   ├── jwt.go
    │       │   │   └── sdk.go
    │       │   ├── internal/
    │       │   │   ├── client_appengine.go
    │       │   │   ├── doc.go
    │       │   │   ├── oauth2.go
    │       │   │   ├── token.go
    │       │   │   └── transport.go
    │       │   ├── jws/
    │       │   │   └── jws.go
    │       │   ├── jwt/
    │       │   │   └── jwt.go
    │       │   ├── oauth2.go
    │       │   ├── token.go
    │       │   └── transport.go
    │       ├── sys/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   └── unix/
    │       │       ├── affinity_linux.go
    │       │       ├── asm_darwin_386.s
    │       │       ├── asm_darwin_amd64.s
    │       │       ├── asm_darwin_arm.s
    │       │       ├── asm_darwin_arm64.s
    │       │       ├── asm_dragonfly_amd64.s
    │       │       ├── asm_freebsd_386.s
    │       │       ├── asm_freebsd_amd64.s
    │       │       ├── asm_freebsd_arm.s
    │       │       ├── asm_linux_386.s
    │       │       ├── asm_linux_amd64.s
    │       │       ├── asm_linux_arm.s
    │       │       ├── asm_linux_arm64.s
    │       │       ├── asm_linux_mips64x.s
    │       │       ├── asm_linux_mipsx.s
    │       │       ├── asm_linux_ppc64x.s
    │       │       ├── asm_linux_s390x.s
    │       │       ├── asm_netbsd_386.s
    │       │       ├── asm_netbsd_amd64.s
    │       │       ├── asm_netbsd_arm.s
    │       │       ├── asm_openbsd_386.s
    │       │       ├── asm_openbsd_amd64.s
    │       │       ├── asm_openbsd_arm.s
    │       │       ├── asm_solaris_amd64.s
    │       │       ├── bluetooth_linux.go
    │       │       ├── cap_freebsd.go
    │       │       ├── constants.go
    │       │       ├── dev_darwin.go
    │       │       ├── dev_dragonfly.go
    │       │       ├── dev_freebsd.go
    │       │       ├── dev_linux.go
    │       │       ├── dev_netbsd.go
    │       │       ├── dev_openbsd.go
    │       │       ├── dirent.go
    │       │       ├── endian_big.go
    │       │       ├── endian_little.go
    │       │       ├── env_unix.go
    │       │       ├── errors_freebsd_386.go
    │       │       ├── errors_freebsd_amd64.go
    │       │       ├── errors_freebsd_arm.go
    │       │       ├── flock.go
    │       │       ├── flock_linux_32bit.go
    │       │       ├── gccgo.go
    │       │       ├── gccgo_c.c
    │       │       ├── gccgo_linux_amd64.go
    │       │       ├── mkpost.go
    │       │       ├── openbsd_pledge.go
    │       │       ├── pagesize_unix.go
    │       │       ├── race.go
    │       │       ├── race0.go
    │       │       ├── sockcmsg_linux.go
    │       │       ├── sockcmsg_unix.go
    │       │       ├── str.go
    │       │       ├── syscall.go
    │       │       ├── syscall_bsd.go
    │       │       ├── syscall_darwin.go
    │       │       ├── syscall_darwin_386.go
    │       │       ├── syscall_darwin_amd64.go
    │       │       ├── syscall_darwin_arm.go
    │       │       ├── syscall_darwin_arm64.go
    │       │       ├── syscall_dragonfly.go
    │       │       ├── syscall_dragonfly_amd64.go
    │       │       ├── syscall_freebsd.go
    │       │       ├── syscall_freebsd_386.go
    │       │       ├── syscall_freebsd_amd64.go
    │       │       ├── syscall_freebsd_arm.go
    │       │       ├── syscall_linux.go
    │       │       ├── syscall_linux_386.go
    │       │       ├── syscall_linux_amd64.go
    │       │       ├── syscall_linux_amd64_gc.go
    │       │       ├── syscall_linux_arm.go
    │       │       ├── syscall_linux_arm64.go
    │       │       ├── syscall_linux_mips64x.go
    │       │       ├── syscall_linux_mipsx.go
    │       │       ├── syscall_linux_ppc64x.go
    │       │       ├── syscall_linux_s390x.go
    │       │       ├── syscall_linux_sparc64.go
    │       │       ├── syscall_netbsd.go
    │       │       ├── syscall_netbsd_386.go
    │       │       ├── syscall_netbsd_amd64.go
    │       │       ├── syscall_netbsd_arm.go
    │       │       ├── syscall_openbsd.go
    │       │       ├── syscall_openbsd_386.go
    │       │       ├── syscall_openbsd_amd64.go
    │       │       ├── syscall_openbsd_arm.go
    │       │       ├── syscall_solaris.go
    │       │       ├── syscall_solaris_amd64.go
    │       │       ├── syscall_unix.go
    │       │       ├── syscall_unix_gc.go
    │       │       ├── timestruct.go
    │       │       ├── types_darwin.go
    │       │       ├── types_dragonfly.go
    │       │       ├── types_freebsd.go
    │       │       ├── types_netbsd.go
    │       │       ├── types_openbsd.go
    │       │       ├── types_solaris.go
    │       │       ├── zerrors_darwin_386.go
    │       │       ├── zerrors_darwin_amd64.go
    │       │       ├── zerrors_darwin_arm.go
    │       │       ├── zerrors_darwin_arm64.go
    │       │       ├── zerrors_dragonfly_amd64.go
    │       │       ├── zerrors_freebsd_386.go
    │       │       ├── zerrors_freebsd_amd64.go
    │       │       ├── zerrors_freebsd_arm.go
    │       │       ├── zerrors_linux_386.go
    │       │       ├── zerrors_linux_amd64.go
    │       │       ├── zerrors_linux_arm.go
    │       │       ├── zerrors_linux_arm64.go
    │       │       ├── zerrors_linux_mips.go
    │       │       ├── zerrors_linux_mips64.go
    │       │       ├── zerrors_linux_mips64le.go
    │       │       ├── zerrors_linux_mipsle.go
    │       │       ├── zerrors_linux_ppc64.go
    │       │       ├── zerrors_linux_ppc64le.go
    │       │       ├── zerrors_linux_s390x.go
    │       │       ├── zerrors_linux_sparc64.go
    │       │       ├── zerrors_netbsd_386.go
    │       │       ├── zerrors_netbsd_amd64.go
    │       │       ├── zerrors_netbsd_arm.go
    │       │       ├── zerrors_openbsd_386.go
    │       │       ├── zerrors_openbsd_amd64.go
    │       │       ├── zerrors_openbsd_arm.go
    │       │       ├── zerrors_solaris_amd64.go
    │       │       ├── zptrace386_linux.go
    │       │       ├── zptracearm_linux.go
    │       │       ├── zptracemips_linux.go
    │       │       ├── zptracemipsle_linux.go
    │       │       ├── zsyscall_darwin_386.go
    │       │       ├── zsyscall_darwin_amd64.go
    │       │       ├── zsyscall_darwin_arm.go
    │       │       ├── zsyscall_darwin_arm64.go
    │       │       ├── zsyscall_dragonfly_amd64.go
    │       │       ├── zsyscall_freebsd_386.go
    │       │       ├── zsyscall_freebsd_amd64.go
    │       │       ├── zsyscall_freebsd_arm.go
    │       │       ├── zsyscall_linux_386.go
    │       │       ├── zsyscall_linux_amd64.go
    │       │       ├── zsyscall_linux_arm.go
    │       │       ├── zsyscall_linux_arm64.go
    │       │       ├── zsyscall_linux_mips.go
    │       │       ├── zsyscall_linux_mips64.go
    │       │       ├── zsyscall_linux_mips64le.go
    │       │       ├── zsyscall_linux_mipsle.go
    │       │       ├── zsyscall_linux_ppc64.go
    │       │       ├── zsyscall_linux_ppc64le.go
    │       │       ├── zsyscall_linux_s390x.go
    │       │       ├── zsyscall_linux_sparc64.go
    │       │       ├── zsyscall_netbsd_386.go
    │       │       ├── zsyscall_netbsd_amd64.go
    │       │       ├── zsyscall_netbsd_arm.go
    │       │       ├── zsyscall_openbsd_386.go
    │       │       ├── zsyscall_openbsd_amd64.go
    │       │       ├── zsyscall_openbsd_arm.go
    │       │       ├── zsyscall_solaris_amd64.go
    │       │       ├── zsysctl_openbsd_386.go
    │       │       ├── zsysctl_openbsd_amd64.go
    │       │       ├── zsysctl_openbsd_arm.go
    │       │       ├── zsysnum_darwin_386.go
    │       │       ├── zsysnum_darwin_amd64.go
    │       │       ├── zsysnum_darwin_arm.go
    │       │       ├── zsysnum_darwin_arm64.go
    │       │       ├── zsysnum_dragonfly_amd64.go
    │       │       ├── zsysnum_freebsd_386.go
    │       │       ├── zsysnum_freebsd_amd64.go
    │       │       ├── zsysnum_freebsd_arm.go
    │       │       ├── zsysnum_linux_386.go
    │       │       ├── zsysnum_linux_amd64.go
    │       │       ├── zsysnum_linux_arm.go
    │       │       ├── zsysnum_linux_arm64.go
    │       │       ├── zsysnum_linux_mips.go
    │       │       ├── zsysnum_linux_mips64.go
    │       │       ├── zsysnum_linux_mips64le.go
    │       │       ├── zsysnum_linux_mipsle.go
    │       │       ├── zsysnum_linux_ppc64.go
    │       │       ├── zsysnum_linux_ppc64le.go
    │       │       ├── zsysnum_linux_s390x.go
    │       │       ├── zsysnum_linux_sparc64.go
    │       │       ├── zsysnum_netbsd_386.go
    │       │       ├── zsysnum_netbsd_amd64.go
    │       │       ├── zsysnum_netbsd_arm.go
    │       │       ├── zsysnum_openbsd_386.go
    │       │       ├── zsysnum_openbsd_amd64.go
    │       │       ├── zsysnum_openbsd_arm.go
    │       │       ├── ztypes_darwin_386.go
    │       │       ├── ztypes_darwin_amd64.go
    │       │       ├── ztypes_darwin_arm.go
    │       │       ├── ztypes_darwin_arm64.go
    │       │       ├── ztypes_dragonfly_amd64.go
    │       │       ├── ztypes_freebsd_386.go
    │       │       ├── ztypes_freebsd_amd64.go
    │       │       ├── ztypes_freebsd_arm.go
    │       │       ├── ztypes_linux_386.go
    │       │       ├── ztypes_linux_amd64.go
    │       │       ├── ztypes_linux_arm.go
    │       │       ├── ztypes_linux_arm64.go
    │       │       ├── ztypes_linux_mips.go
    │       │       ├── ztypes_linux_mips64.go
    │       │       ├── ztypes_linux_mips64le.go
    │       │       ├── ztypes_linux_mipsle.go
    │       │       ├── ztypes_linux_ppc64.go
    │       │       ├── ztypes_linux_ppc64le.go
    │       │       ├── ztypes_linux_s390x.go
    │       │       ├── ztypes_linux_sparc64.go
    │       │       ├── ztypes_netbsd_386.go
    │       │       ├── ztypes_netbsd_amd64.go
    │       │       ├── ztypes_netbsd_arm.go
    │       │       ├── ztypes_openbsd_386.go
    │       │       ├── ztypes_openbsd_amd64.go
    │       │       ├── ztypes_openbsd_arm.go
    │       │       └── ztypes_solaris_amd64.go
    │       ├── text/
    │       │   ├── LICENSE
    │       │   ├── PATENTS
    │       │   ├── collate/
    │       │   │   ├── build/
    │       │   │   │   ├── builder.go
    │       │   │   │   ├── colelem.go
    │       │   │   │   ├── contract.go
    │       │   │   │   ├── order.go
    │       │   │   │   ├── table.go
    │       │   │   │   └── trie.go
    │       │   │   ├── collate.go
    │       │   │   ├── index.go
    │       │   │   ├── maketables.go
    │       │   │   ├── option.go
    │       │   │   ├── sort.go
    │       │   │   └── tables.go
    │       │   ├── doc.go
    │       │   ├── gen.go
    │       │   ├── internal/
    │       │   │   ├── colltab/
    │       │   │   │   ├── collelem.go
    │       │   │   │   ├── colltab.go
    │       │   │   │   ├── contract.go
    │       │   │   │   ├── iter.go
    │       │   │   │   ├── numeric.go
    │       │   │   │   ├── table.go
    │       │   │   │   ├── trie.go
    │       │   │   │   └── weighter.go
    │       │   │   ├── gen/
    │       │   │   │   ├── code.go
    │       │   │   │   └── gen.go
    │       │   │   ├── gen.go
    │       │   │   ├── internal.go
    │       │   │   ├── match.go
    │       │   │   ├── tables.go
    │       │   │   ├── tag/
    │       │   │   │   └── tag.go
    │       │   │   ├── triegen/
    │       │   │   │   ├── compact.go
    │       │   │   │   ├── print.go
    │       │   │   │   └── triegen.go
    │       │   │   └── ucd/
    │       │   │       └── ucd.go
    │       │   ├── language/
    │       │   │   ├── common.go
    │       │   │   ├── coverage.go
    │       │   │   ├── doc.go
    │       │   │   ├── gen.go
    │       │   │   ├── gen_common.go
    │       │   │   ├── gen_index.go
    │       │   │   ├── go1_1.go
    │       │   │   ├── go1_2.go
    │       │   │   ├── index.go
    │       │   │   ├── language.go
    │       │   │   ├── lookup.go
    │       │   │   ├── match.go
    │       │   │   ├── parse.go
    │       │   │   ├── tables.go
    │       │   │   └── tags.go
    │       │   ├── secure/
    │       │   │   ├── bidirule/
    │       │   │   │   ├── bidirule.go
    │       │   │   │   ├── bidirule10.0.0.go
    │       │   │   │   └── bidirule9.0.0.go
    │       │   │   └── doc.go
    │       │   ├── transform/
    │       │   │   └── transform.go
    │       │   └── unicode/
    │       │       ├── bidi/
    │       │       │   ├── bidi.go
    │       │       │   ├── bracket.go
    │       │       │   ├── core.go
    │       │       │   ├── gen.go
    │       │       │   ├── gen_ranges.go
    │       │       │   ├── gen_trieval.go
    │       │       │   ├── prop.go
    │       │       │   ├── tables10.0.0.go
    │       │       │   ├── tables9.0.0.go
    │       │       │   └── trieval.go
    │       │       ├── cldr/
    │       │       │   ├── base.go
    │       │       │   ├── cldr.go
    │       │       │   ├── collate.go
    │       │       │   ├── decode.go
    │       │       │   ├── makexml.go
    │       │       │   ├── resolve.go
    │       │       │   ├── slice.go
    │       │       │   └── xml.go
    │       │       ├── doc.go
    │       │       ├── norm/
    │       │       │   ├── composition.go
    │       │       │   ├── forminfo.go
    │       │       │   ├── input.go
    │       │       │   ├── iter.go
    │       │       │   ├── maketables.go
    │       │       │   ├── normalize.go
    │       │       │   ├── readwriter.go
    │       │       │   ├── tables10.0.0.go
    │       │       │   ├── tables9.0.0.go
    │       │       │   ├── transform.go
    │       │       │   ├── trie.go
    │       │       │   └── triegen.go
    │       │       └── rangetable/
    │       │           ├── gen.go
    │       │           ├── merge.go
    │       │           ├── rangetable.go
    │       │           ├── tables10.0.0.go
    │       │           └── tables9.0.0.go
    │       └── time/
    │           ├── LICENSE
    │           ├── PATENTS
    │           └── rate/
    │               ├── rate.go
    │               ├── rate_go16.go
    │               └── rate_go17.go
    ├── gonum.org/
    │   └── v1/
    │       ├── gonum/
    │       │   ├── LICENSE
    │       │   ├── blas/
    │       │   │   ├── blas.go
    │       │   │   ├── blas64/
    │       │   │   │   ├── blas64.go
    │       │   │   │   ├── conv.go
    │       │   │   │   ├── conv_symmetric.go
    │       │   │   │   └── doc.go
    │       │   │   ├── doc.go
    │       │   │   └── gonum/
    │       │   │       ├── cmplx.go
    │       │   │       ├── dgemm.go
    │       │   │       ├── doc.go
    │       │   │       ├── general_double.go
    │       │   │       ├── general_single.go
    │       │   │       ├── gonum.go
    │       │   │       ├── level1cmplx128.go
    │       │   │       ├── level1double.go
    │       │   │       ├── level1double_ddot.go
    │       │   │       ├── level1single.go
    │       │   │       ├── level1single_dsdot.go
    │       │   │       ├── level1single_sdot.go
    │       │   │       ├── level1single_sdsdot.go
    │       │   │       ├── level2cmplx128.go
    │       │   │       ├── level2double.go
    │       │   │       ├── level2single.go
    │       │   │       ├── level3double.go
    │       │   │       ├── level3single.go
    │       │   │       └── sgemm.go
    │       │   ├── floats/
    │       │   │   ├── doc.go
    │       │   │   └── floats.go
    │       │   ├── internal/
    │       │   │   ├── asm/
    │       │   │   │   ├── c128/
    │       │   │   │   │   ├── axpyinc_amd64.s
    │       │   │   │   │   ├── axpyincto_amd64.s
    │       │   │   │   │   ├── axpyunitary_amd64.s
    │       │   │   │   │   ├── axpyunitaryto_amd64.s
    │       │   │   │   │   ├── doc.go
    │       │   │   │   │   ├── dotcinc_amd64.s
    │       │   │   │   │   ├── dotcunitary_amd64.s
    │       │   │   │   │   ├── dotuinc_amd64.s
    │       │   │   │   │   ├── dotuunitary_amd64.s
    │       │   │   │   │   ├── dscalinc_amd64.s
    │       │   │   │   │   ├── dscalunitary_amd64.s
    │       │   │   │   │   ├── scal.go
    │       │   │   │   │   ├── scalUnitary_amd64.s
    │       │   │   │   │   ├── scalinc_amd64.s
    │       │   │   │   │   ├── stubs_amd64.go
    │       │   │   │   │   └── stubs_noasm.go
    │       │   │   │   ├── f32/
    │       │   │   │   │   ├── axpyinc_amd64.s
    │       │   │   │   │   ├── axpyincto_amd64.s
    │       │   │   │   │   ├── axpyunitary_amd64.s
    │       │   │   │   │   ├── axpyunitaryto_amd64.s
    │       │   │   │   │   ├── ddotinc_amd64.s
    │       │   │   │   │   ├── ddotunitary_amd64.s
    │       │   │   │   │   ├── doc.go
    │       │   │   │   │   ├── dotinc_amd64.s
    │       │   │   │   │   ├── dotunitary_amd64.s
    │       │   │   │   │   ├── scal.go
    │       │   │   │   │   ├── stubs_amd64.go
    │       │   │   │   │   └── stubs_noasm.go
    │       │   │   │   └── f64/
    │       │   │   │       ├── abssum_amd64.s
    │       │   │   │       ├── abssuminc_amd64.s
    │       │   │   │       ├── add_amd64.s
    │       │   │   │       ├── addconst_amd64.s
    │       │   │   │       ├── axpy.go
    │       │   │   │       ├── axpyinc_amd64.s
    │       │   │   │       ├── axpyincto_amd64.s
    │       │   │   │       ├── axpyunitary_amd64.s
    │       │   │   │       ├── axpyunitaryto_amd64.s
    │       │   │   │       ├── cumprod_amd64.s
    │       │   │   │       ├── cumsum_amd64.s
    │       │   │   │       ├── div_amd64.s
    │       │   │   │       ├── divto_amd64.s
    │       │   │   │       ├── doc.go
    │       │   │   │       ├── dot.go
    │       │   │   │       ├── dot_amd64.s
    │       │   │   │       ├── l1norm_amd64.s
    │       │   │   │       ├── linfnorm_amd64.s
    │       │   │   │       ├── scal.go
    │       │   │   │       ├── scalinc_amd64.s
    │       │   │   │       ├── scalincto_amd64.s
    │       │   │   │       ├── scalunitary_amd64.s
    │       │   │   │       ├── scalunitaryto_amd64.s
    │       │   │   │       ├── stubs_amd64.go
    │       │   │   │       └── stubs_noasm.go
    │       │   │   └── math32/
    │       │   │       ├── doc.go
    │       │   │       ├── math.go
    │       │   │       ├── signbit.go
    │       │   │       ├── sqrt.go
    │       │   │       ├── sqrt_amd64.go
    │       │   │       └── sqrt_amd64.s
    │       │   ├── lapack/
    │       │   │   ├── gonum/
    │       │   │   │   ├── dbdsqr.go
    │       │   │   │   ├── dgebak.go
    │       │   │   │   ├── dgebal.go
    │       │   │   │   ├── dgebd2.go
    │       │   │   │   ├── dgebrd.go
    │       │   │   │   ├── dgecon.go
    │       │   │   │   ├── dgeev.go
    │       │   │   │   ├── dgehd2.go
    │       │   │   │   ├── dgehrd.go
    │       │   │   │   ├── dgelq2.go
    │       │   │   │   ├── dgelqf.go
    │       │   │   │   ├── dgels.go
    │       │   │   │   ├── dgeql2.go
    │       │   │   │   ├── dgeqp3.go
    │       │   │   │   ├── dgeqr2.go
    │       │   │   │   ├── dgeqrf.go
    │       │   │   │   ├── dgerq2.go
    │       │   │   │   ├── dgerqf.go
    │       │   │   │   ├── dgesvd.go
    │       │   │   │   ├── dgetf2.go
    │       │   │   │   ├── dgetrf.go
    │       │   │   │   ├── dgetri.go
    │       │   │   │   ├── dgetrs.go
    │       │   │   │   ├── dggsvd3.go
    │       │   │   │   ├── dggsvp3.go
    │       │   │   │   ├── dhseqr.go
    │       │   │   │   ├── dlabrd.go
    │       │   │   │   ├── dlacn2.go
    │       │   │   │   ├── dlacpy.go
    │       │   │   │   ├── dlae2.go
    │       │   │   │   ├── dlaev2.go
    │       │   │   │   ├── dlaexc.go
    │       │   │   │   ├── dlags2.go
    │       │   │   │   ├── dlahqr.go
    │       │   │   │   ├── dlahr2.go
    │       │   │   │   ├── dlaln2.go
    │       │   │   │   ├── dlange.go
    │       │   │   │   ├── dlanst.go
    │       │   │   │   ├── dlansy.go
    │       │   │   │   ├── dlantr.go
    │       │   │   │   ├── dlanv2.go
    │       │   │   │   ├── dlapll.go
    │       │   │   │   ├── dlapmt.go
    │       │   │   │   ├── dlapy2.go
    │       │   │   │   ├── dlaqp2.go
    │       │   │   │   ├── dlaqps.go
    │       │   │   │   ├── dlaqr04.go
    │       │   │   │   ├── dlaqr1.go
    │       │   │   │   ├── dlaqr23.go
    │       │   │   │   ├── dlaqr5.go
    │       │   │   │   ├── dlarf.go
    │       │   │   │   ├── dlarfb.go
    │       │   │   │   ├── dlarfg.go
    │       │   │   │   ├── dlarft.go
    │       │   │   │   ├── dlarfx.go
    │       │   │   │   ├── dlartg.go
    │       │   │   │   ├── dlas2.go
    │       │   │   │   ├── dlascl.go
    │       │   │   │   ├── dlaset.go
    │       │   │   │   ├── dlasq1.go
    │       │   │   │   ├── dlasq2.go
    │       │   │   │   ├── dlasq3.go
    │       │   │   │   ├── dlasq4.go
    │       │   │   │   ├── dlasq5.go
    │       │   │   │   ├── dlasq6.go
    │       │   │   │   ├── dlasr.go
    │       │   │   │   ├── dlasrt.go
    │       │   │   │   ├── dlassq.go
    │       │   │   │   ├── dlasv2.go
    │       │   │   │   ├── dlaswp.go
    │       │   │   │   ├── dlasy2.go
    │       │   │   │   ├── dlatrd.go
    │       │   │   │   ├── dlatrs.go
    │       │   │   │   ├── doc.go
    │       │   │   │   ├── dorg2l.go
    │       │   │   │   ├── dorg2r.go
    │       │   │   │   ├── dorgbr.go
    │       │   │   │   ├── dorghr.go
    │       │   │   │   ├── dorgl2.go
    │       │   │   │   ├── dorglq.go
    │       │   │   │   ├── dorgql.go
    │       │   │   │   ├── dorgqr.go
    │       │   │   │   ├── dorgtr.go
    │       │   │   │   ├── dorm2r.go
    │       │   │   │   ├── dormbr.go
    │       │   │   │   ├── dormhr.go
    │       │   │   │   ├── dorml2.go
    │       │   │   │   ├── dormlq.go
    │       │   │   │   ├── dormqr.go
    │       │   │   │   ├── dormr2.go
    │       │   │   │   ├── dpbtf2.go
    │       │   │   │   ├── dpocon.go
    │       │   │   │   ├── dpotf2.go
    │       │   │   │   ├── dpotrf.go
    │       │   │   │   ├── drscl.go
    │       │   │   │   ├── dsteqr.go
    │       │   │   │   ├── dsterf.go
    │       │   │   │   ├── dsyev.go
    │       │   │   │   ├── dsytd2.go
    │       │   │   │   ├── dsytrd.go
    │       │   │   │   ├── dtgsja.go
    │       │   │   │   ├── dtrcon.go
    │       │   │   │   ├── dtrevc3.go
    │       │   │   │   ├── dtrexc.go
    │       │   │   │   ├── dtrti2.go
    │       │   │   │   ├── dtrtri.go
    │       │   │   │   ├── dtrtrs.go
    │       │   │   │   ├── general.go
    │       │   │   │   ├── iladlc.go
    │       │   │   │   ├── iladlr.go
    │       │   │   │   ├── ilaenv.go
    │       │   │   │   └── iparmq.go
    │       │   │   ├── lapack.go
    │       │   │   └── lapack64/
    │       │   │       ├── doc.go
    │       │   │       └── lapack64.go
    │       │   └── mat/
    │       │       ├── band.go
    │       │       ├── cholesky.go
    │       │       ├── cmatrix.go
    │       │       ├── consts.go
    │       │       ├── dense.go
    │       │       ├── dense_arithmetic.go
    │       │       ├── doc.go
    │       │       ├── eigen.go
    │       │       ├── errors.go
    │       │       ├── format.go
    │       │       ├── gsvd.go
    │       │       ├── hogsvd.go
    │       │       ├── index_bound_checks.go
    │       │       ├── index_no_bound_checks.go
    │       │       ├── inner.go
    │       │       ├── io.go
    │       │       ├── lq.go
    │       │       ├── lu.go
    │       │       ├── matrix.go
    │       │       ├── offset.go
    │       │       ├── offset_appengine.go
    │       │       ├── pool.go
    │       │       ├── product.go
    │       │       ├── qr.go
    │       │       ├── shadow.go
    │       │       ├── solve.go
    │       │       ├── svd.go
    │       │       ├── symband.go
    │       │       ├── symmetric.go
    │       │       ├── triangular.go
    │       │       └── vector.go
    │       └── plot/
    │           ├── LICENSE
    │           ├── align.go
    │           ├── axis.go
    │           ├── doc.go
    │           ├── labelling.go
    │           ├── legend.go
    │           ├── palette/
    │           │   ├── hsva.go
    │           │   ├── palette.go
    │           │   └── reverse.go
    │           ├── plot.go
    │           ├── plotter/
    │           │   ├── barchart.go
    │           │   ├── boxplot.go
    │           │   ├── colorbar.go
    │           │   ├── conrec.go
    │           │   ├── contour.go
    │           │   ├── errbars.go
    │           │   ├── functions.go
    │           │   ├── glyphbox.go
    │           │   ├── grid.go
    │           │   ├── heat.go
    │           │   ├── histogram.go
    │           │   ├── image.go
    │           │   ├── johnson.go
    │           │   ├── labels.go
    │           │   ├── line.go
    │           │   ├── palettethumbnailer.go
    │           │   ├── plotter.go
    │           │   ├── polygon.go
    │           │   ├── quartile.go
    │           │   ├── sankey.go
    │           │   ├── scatter.go
    │           │   └── volcano_example.go
    │           ├── plotutil/
    │           │   ├── add.go
    │           │   ├── errorpoints.go
    │           │   ├── main.go
    │           │   └── plotutil.go
    │           ├── tools/
    │           │   └── bezier/
    │           │       └── bezier.go
    │           └── vg/
    │               ├── draw/
    │               │   └── canvas.go
    │               ├── font.go
    │               ├── font_syscall.go
    │               ├── fonts/
    │               │   ├── fonts.go
    │               │   ├── liberation_fonts_generated.go
    │               │   └── mk-fonts.go
    │               ├── geom.go
    │               ├── len.go
    │               ├── vg.go
    │               ├── vgeps/
    │               │   └── vgeps.go
    │               ├── vgimg/
    │               │   └── vgimg.go
    │               ├── vgpdf/
    │               │   └── vgpdf.go
    │               └── vgsvg/
    │                   └── vgsvg.go
    ├── google.golang.org/
    │   ├── api/
    │   │   ├── LICENSE
    │   │   ├── gensupport/
    │   │   │   ├── backoff.go
    │   │   │   ├── buffer.go
    │   │   │   ├── doc.go
    │   │   │   ├── header.go
    │   │   │   ├── json.go
    │   │   │   ├── jsonfloat.go
    │   │   │   ├── media.go
    │   │   │   ├── params.go
    │   │   │   ├── resumable.go
    │   │   │   ├── retry.go
    │   │   │   └── send.go
    │   │   ├── googleapi/
    │   │   │   ├── googleapi.go
    │   │   │   ├── internal/
    │   │   │   │   └── uritemplates/
    │   │   │   │       ├── LICENSE
    │   │   │   │       ├── uritemplates.go
    │   │   │   │       └── utils.go
    │   │   │   ├── transport/
    │   │   │   │   └── apikey.go
    │   │   │   └── types.go
    │   │   ├── internal/
    │   │   │   ├── creds.go
    │   │   │   ├── pool.go
    │   │   │   └── settings.go
    │   │   ├── iterator/
    │   │   │   └── iterator.go
    │   │   ├── option/
    │   │   │   └── option.go
    │   │   ├── storage/
    │   │   │   └── v1/
    │   │   │       └── storage-gen.go
    │   │   └── transport/
    │   │       ├── dial.go
    │   │       └── http/
    │   │           ├── dial.go
    │   │           └── dial_appengine.go
    │   ├── appengine/
    │   │   ├── LICENSE
    │   │   ├── appengine.go
    │   │   ├── appengine_vm.go
    │   │   ├── errors.go
    │   │   ├── identity.go
    │   │   ├── internal/
    │   │   │   ├── api.go
    │   │   │   ├── api_classic.go
    │   │   │   ├── api_common.go
    │   │   │   ├── app_id.go
    │   │   │   ├── app_identity/
    │   │   │   │   └── app_identity_service.pb.go
    │   │   │   ├── base/
    │   │   │   │   └── api_base.pb.go
    │   │   │   ├── datastore/
    │   │   │   │   └── datastore_v3.pb.go
    │   │   │   ├── identity.go
    │   │   │   ├── identity_classic.go
    │   │   │   ├── identity_vm.go
    │   │   │   ├── internal.go
    │   │   │   ├── log/
    │   │   │   │   └── log_service.pb.go
    │   │   │   ├── main.go
    │   │   │   ├── main_vm.go
    │   │   │   ├── metadata.go
    │   │   │   ├── modules/
    │   │   │   │   └── modules_service.pb.go
    │   │   │   ├── net.go
    │   │   │   ├── remote_api/
    │   │   │   │   └── remote_api.pb.go
    │   │   │   ├── transaction.go
    │   │   │   └── urlfetch/
    │   │   │       └── urlfetch_service.pb.go
    │   │   ├── namespace.go
    │   │   ├── timeout.go
    │   │   └── urlfetch/
    │   │       └── urlfetch.go
    │   ├── genproto/
    │   │   ├── LICENSE
    │   │   ├── googleapis/
    │   │   │   ├── api/
    │   │   │   │   ├── annotations/
    │   │   │   │   │   ├── annotations.pb.go
    │   │   │   │   │   └── http.pb.go
    │   │   │   │   ├── authorization_config.pb.go
    │   │   │   │   └── experimental.pb.go
    │   │   │   ├── iam/
    │   │   │   │   └── v1/
    │   │   │   │       ├── iam_policy.pb.go
    │   │   │   │       └── policy.pb.go
    │   │   │   └── rpc/
    │   │   │       └── status/
    │   │   │           └── status.pb.go
    │   │   └── regen.go
    │   └── grpc/
    │       ├── LICENSE
    │       ├── backoff.go
    │       ├── balancer/
    │       │   └── balancer.go
    │       ├── balancer.go
    │       ├── balancer_conn_wrappers.go
    │       ├── balancer_v1_wrapper.go
    │       ├── call.go
    │       ├── clientconn.go
    │       ├── codec.go
    │       ├── codes/
    │       │   ├── code_string.go
    │       │   └── codes.go
    │       ├── connectivity/
    │       │   └── connectivity.go
    │       ├── credentials/
    │       │   ├── credentials.go
    │       │   ├── credentials_util_go17.go
    │       │   ├── credentials_util_go18.go
    │       │   └── credentials_util_pre_go17.go
    │       ├── doc.go
    │       ├── grpclb/
    │       │   └── grpc_lb_v1/
    │       │       ├── doc.go
    │       │       └── messages/
    │       │           └── messages.pb.go
    │       ├── grpclb.go
    │       ├── grpclog/
    │       │   ├── grpclog.go
    │       │   ├── logger.go
    │       │   └── loggerv2.go
    │       ├── health/
    │       │   ├── grpc_health_v1/
    │       │   │   └── health.pb.go
    │       │   └── health.go
    │       ├── interceptor.go
    │       ├── internal/
    │       │   └── internal.go
    │       ├── keepalive/
    │       │   └── keepalive.go
    │       ├── metadata/
    │       │   └── metadata.go
    │       ├── naming/
    │       │   ├── dns_resolver.go
    │       │   ├── go17.go
    │       │   ├── go18.go
    │       │   └── naming.go
    │       ├── peer/
    │       │   └── peer.go
    │       ├── picker_wrapper.go
    │       ├── pickfirst.go
    │       ├── proxy.go
    │       ├── resolver/
    │       │   └── resolver.go
    │       ├── resolver_conn_wrapper.go
    │       ├── rpc_util.go
    │       ├── server.go
    │       ├── stats/
    │       │   ├── handlers.go
    │       │   └── stats.go
    │       ├── status/
    │       │   └── status.go
    │       ├── stream.go
    │       ├── tap/
    │       │   └── tap.go
    │       ├── trace.go
    │       └── transport/
    │           ├── bdp_estimator.go
    │           ├── control.go
    │           ├── handler_server.go
    │           ├── http2_client.go
    │           ├── http2_server.go
    │           ├── http_util.go
    │           ├── log.go
    │           └── transport.go
    └── gopkg.in/
        └── yaml.v2/
            ├── LICENSE
            ├── LICENSE.libyaml
            ├── apic.go
            ├── decode.go
            ├── emitterc.go
            ├── encode.go
            ├── parserc.go
            ├── readerc.go
            ├── resolve.go
            ├── scannerc.go
            ├── sorter.go
            ├── writerc.go
            ├── yaml.go
            ├── yamlh.go
            └── yamlprivateh.go
Download .txt
Showing preview only (6,809K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (85654 symbols across 1207 files)

FILE: agent/agent_cetcd.go
  function startCetcd (line 28) | func startCetcd(fs *flags, t *transporterServer) error {

FILE: agent/agent_consul.go
  function startConsul (line 29) | func startConsul(fs *flags, t *transporterServer) error {

FILE: agent/agent_etcd.go
  function startEtcd (line 29) | func startEtcd(fs *flags, t *transporterServer) error {

FILE: agent/agent_zetcd.go
  function startZetcd (line 28) | func startZetcd(fs *flags, t *transporterServer) error {

FILE: agent/agent_zookeeper.go
  type ZookeeperConfig (line 46) | type ZookeeperConfig struct
  type ZookeeperPeer (line 58) | type ZookeeperPeer struct
  function init (line 65) | func init() {
  constant JavaClassPathZookeeperr353beta (line 79) | JavaClassPathZookeeperr353beta = `-cp zookeeper-3.5.3-beta.jar:lib/slf4j...
  function startZookeeper (line 83) | func startZookeeper(fs *flags, t *transporterServer) error {

FILE: agent/command.go
  type flags (line 33) | type flags struct
  function init (line 59) | func init() {
  function commandFunc (line 104) | func commandFunc(cmd *cobra.Command, args []string) error {

FILE: agent/server.go
  type transporterServer (line 34) | type transporterServer struct
    method Transfer (line 80) | func (t *transporterServer) Transfer(ctx context.Context, req *dbteste...
  function NewServer (line 67) | func NewServer(lg *zap.Logger) dbtesterpb.TransporterServer {
  function measureDatabasSize (line 303) | func measureDatabasSize(flg flags, rdb dbtesterpb.DatabaseID) (int64, er...

FILE: agent/server_system_metrics.go
  function startMetrics (line 28) | func startMetrics(fs *flags, t *transporterServer) (err error) {

FILE: agent/upload_log.go
  function uploadLog (line 30) | func uploadLog(fs *flags, t *transporterServer) error {

FILE: agent/util.go
  function openToAppend (line 22) | func openToAppend(fpath string) (*os.File, error) {
  function openToOverwrite (line 30) | func openToOverwrite(fpath string) (*os.File, error) {
  function toFile (line 38) | func toFile(txt, fpath string) error {
  function homeDir (line 51) | func homeDir() string {
  function exist (line 63) | func exist(fpath string) bool {

FILE: analyze/01_read_raw_data_to_test_data.go
  type testData (line 50) | type testData struct
  function readSystemMetrics (line 58) | func readSystemMetrics(fpath string) (data testData, err error) {

FILE: analyze/02_read_all_metrics_to_analyze_data.go
  type analyzeData (line 23) | type analyzeData struct
    method aggSystemMetrics (line 68) | func (data *analyzeData) aggSystemMetrics() error {
  function readSystemMetricsAll (line 45) | func readSystemMetricsAll(fpaths ...string) (data *analyzeData, err erro...

FILE: analyze/03_read_benchmark_metrics_to_analyze_data.go
  method importBenchMetrics (line 25) | func (data *analyzeData) importBenchMetrics(fpath string) (err error) {
  type rowData (line 223) | type rowData struct
  function findClosest (line 231) | func findClosest(second int64, sec2Data map[int64]rowData) rowData {
  function _findClosestUpper (line 257) | func _findClosestUpper(second int64, sec2Data map[int64]rowData, min, ma...
  function _findClosestLower (line 268) | func _findClosestLower(second int64, sec2Data map[int64]rowData, min, ma...

FILE: analyze/04_aggregate_all_analyze_data.go
  method aggregateAll (line 28) | func (data *analyzeData) aggregateAll(memoryByKeyPath string, readBytesD...
  method save (line 573) | func (data *analyzeData) save() error {

FILE: analyze/05_plot.go
  function init (line 34) | func init() {
  type pair (line 40) | type pair struct
  type triplet (line 45) | type triplet struct
  method draw (line 52) | func (all *allAggregatedData) draw(cfg dbtesterpb.ConfigAnalyzeMachinePl...
  method drawXY (line 91) | func (all *allAggregatedData) drawXY(cfg dbtesterpb.ConfigAnalyzeMachine...
  method drawXYWithErrorPoints (line 130) | func (all *allAggregatedData) drawXYWithErrorPoints(cfg dbtesterpb.Confi...
  function points (line 197) | func points(col dataframe.Column) (plotter.XYs, error) {
  function pointsXY (line 219) | func pointsXY(colX, colY dataframe.Column) (plotter.XYs, error) {

FILE: analyze/command.go
  function init (line 45) | func init() {
  function commandFunc (line 49) | func commandFunc(cmd *cobra.Command, args []string) error {
  type allAggregatedData (line 53) | type allAggregatedData struct
  function do (line 61) | func do(configPath string) error {
  function changeExtToTxt (line 1146) | func changeExtToTxt(fpath string) string {

FILE: analyze/logger.go
  function init (line 21) | func init() {

FILE: analyze/util.go
  function minFloat64 (line 22) | func minFloat64(a, b float64) float64 {
  function maxFloat64 (line 29) | func maxFloat64(a, b float64) float64 {
  function makeHeader (line 36) | func makeHeader(column string, tag string) string {
  function openToRead (line 40) | func openToRead(fpath string) (*os.File, error) {
  function openToOverwrite (line 48) | func openToOverwrite(fpath string) (*os.File, error) {
  function toFile (line 56) | func toFile(txt, fpath string) error {

FILE: broadcast_request.go
  method BroadcaseRequest (line 29) | func (cfg *Config) BroadcaseRequest(databaseID string, op dbtesterpb.Ope...

FILE: cmd/dbtester/main.go
  function init (line 45) | func init() {
  function init (line 49) | func init() {
  function main (line 55) | func main() {

FILE: config_dbtester.go
  function MakeTag (line 30) | func MakeTag(desc string) string {
  type Config (line 40) | type Config struct
    method ToRequest (line 302) | func (cfg *Config) ToRequest(databaseID string, op dbtesterpb.Operatio...
  function ReadConfig (line 59) | func ReadConfig(fpath string, analyze bool) (*Config, error) {
  constant maxEtcdQuotaSize (line 299) | maxEtcdQuotaSize = 8000000000

FILE: config_dbtester_test.go
  function TestConfig (line 24) | func TestConfig(t *testing.T) {

FILE: control/command.go
  function init (line 48) | func init() {
  function commandFunc (line 70) | func commandFunc(cmd *cobra.Command, args []string) error {

FILE: control/logger.go
  function init (line 21) | func init() {

FILE: dbtesterpb/config_analyze_machine.pb.go
  constant _ (line 57) | _ = proto.ProtoPackageIsVersion2
  type ConfigAnalyzeMachineInitial (line 60) | type ConfigAnalyzeMachineInitial struct
    method Reset (line 79) | func (m *ConfigAnalyzeMachineInitial) Reset()         { *m = ConfigAna...
    method String (line 80) | func (m *ConfigAnalyzeMachineInitial) String() string { return proto.C...
    method ProtoMessage (line 81) | func (*ConfigAnalyzeMachineInitial) ProtoMessage()    {}
    method Descriptor (line 82) | func (*ConfigAnalyzeMachineInitial) Descriptor() ([]byte, []int) {
    method Marshal (line 150) | func (m *ConfigAnalyzeMachineInitial) Marshal() (dAtA []byte, err erro...
    method MarshalTo (line 160) | func (m *ConfigAnalyzeMachineInitial) MarshalTo(dAtA []byte) (int, err...
    method Size (line 443) | func (m *ConfigAnalyzeMachineInitial) Size() (n int) {
    method Unmarshal (line 604) | func (m *ConfigAnalyzeMachineInitial) Unmarshal(dAtA []byte) error {
  type ConfigAnalyzeMachineAllAggregatedOutput (line 86) | type ConfigAnalyzeMachineAllAggregatedOutput struct
    method Reset (line 91) | func (m *ConfigAnalyzeMachineAllAggregatedOutput) Reset() {
    method String (line 94) | func (m *ConfigAnalyzeMachineAllAggregatedOutput) String() string { re...
    method ProtoMessage (line 95) | func (*ConfigAnalyzeMachineAllAggregatedOutput) ProtoMessage()    {}
    method Descriptor (line 96) | func (*ConfigAnalyzeMachineAllAggregatedOutput) Descriptor() ([]byte, ...
    method Marshal (line 275) | func (m *ConfigAnalyzeMachineAllAggregatedOutput) Marshal() (dAtA []by...
    method MarshalTo (line 285) | func (m *ConfigAnalyzeMachineAllAggregatedOutput) MarshalTo(dAtA []byt...
    method Size (line 515) | func (m *ConfigAnalyzeMachineAllAggregatedOutput) Size() (n int) {
    method Unmarshal (line 1118) | func (m *ConfigAnalyzeMachineAllAggregatedOutput) Unmarshal(dAtA []byt...
  type ConfigAnalyzeMachinePlot (line 101) | type ConfigAnalyzeMachinePlot struct
    method Reset (line 109) | func (m *ConfigAnalyzeMachinePlot) Reset()         { *m = ConfigAnalyz...
    method String (line 110) | func (m *ConfigAnalyzeMachinePlot) String() string { return proto.Comp...
    method ProtoMessage (line 111) | func (*ConfigAnalyzeMachinePlot) ProtoMessage()    {}
    method Descriptor (line 112) | func (*ConfigAnalyzeMachinePlot) Descriptor() ([]byte, []int) {
    method Marshal (line 305) | func (m *ConfigAnalyzeMachinePlot) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 315) | func (m *ConfigAnalyzeMachinePlot) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 529) | func (m *ConfigAnalyzeMachinePlot) Size() (n int) {
    method Unmarshal (line 1226) | func (m *ConfigAnalyzeMachinePlot) Unmarshal(dAtA []byte) error {
  type ConfigAnalyzeMachineImage (line 117) | type ConfigAnalyzeMachineImage struct
    method Reset (line 123) | func (m *ConfigAnalyzeMachineImage) Reset()         { *m = ConfigAnaly...
    method String (line 124) | func (m *ConfigAnalyzeMachineImage) String() string { return proto.Com...
    method ProtoMessage (line 125) | func (*ConfigAnalyzeMachineImage) ProtoMessage()    {}
    method Descriptor (line 126) | func (*ConfigAnalyzeMachineImage) Descriptor() ([]byte, []int) {
    method Marshal (line 362) | func (m *ConfigAnalyzeMachineImage) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 372) | func (m *ConfigAnalyzeMachineImage) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 557) | func (m *ConfigAnalyzeMachineImage) Size() (n int) {
    method Unmarshal (line 1421) | func (m *ConfigAnalyzeMachineImage) Unmarshal(dAtA []byte) error {
  type ConfigAnalyzeMachineREADME (line 131) | type ConfigAnalyzeMachineREADME struct
    method Reset (line 136) | func (m *ConfigAnalyzeMachineREADME) Reset()         { *m = ConfigAnal...
    method String (line 137) | func (m *ConfigAnalyzeMachineREADME) String() string { return proto.Co...
    method ProtoMessage (line 138) | func (*ConfigAnalyzeMachineREADME) ProtoMessage()    {}
    method Descriptor (line 139) | func (*ConfigAnalyzeMachineREADME) Descriptor() ([]byte, []int) {
    method Marshal (line 398) | func (m *ConfigAnalyzeMachineREADME) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 408) | func (m *ConfigAnalyzeMachineREADME) MarshalTo(dAtA []byte) (int, erro...
    method Size (line 575) | func (m *ConfigAnalyzeMachineREADME) Size() (n int) {
    method Unmarshal (line 1558) | func (m *ConfigAnalyzeMachineREADME) Unmarshal(dAtA []byte) error {
  function init (line 143) | func init() {
  function encodeVarintConfigAnalyzeMachine (line 434) | func encodeVarintConfigAnalyzeMachine(dAtA []byte, offset int, v uint64)...
  function sovConfigAnalyzeMachine (line 591) | func sovConfigAnalyzeMachine(x uint64) (n int) {
  function sozConfigAnalyzeMachine (line 601) | func sozConfigAnalyzeMachine(x uint64) (n int) {
  function skipConfigAnalyzeMachine (line 1668) | func skipConfigAnalyzeMachine(dAtA []byte) (n int, err error) {
  function init (line 1773) | func init() {

FILE: dbtesterpb/config_client_machine.pb.go
  type ConfigClientMachineInitial (line 19) | type ConfigClientMachineInitial struct
    method Reset (line 37) | func (m *ConfigClientMachineInitial) Reset()         { *m = ConfigClie...
    method String (line 38) | func (m *ConfigClientMachineInitial) String() string { return proto.Co...
    method ProtoMessage (line 39) | func (*ConfigClientMachineInitial) ProtoMessage()    {}
    method Descriptor (line 40) | func (*ConfigClientMachineInitial) Descriptor() ([]byte, []int) {
    method Marshal (line 116) | func (m *ConfigClientMachineInitial) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 126) | func (m *ConfigClientMachineInitial) MarshalTo(dAtA []byte) (int, erro...
    method Size (line 610) | func (m *ConfigClientMachineInitial) Size() (n int) {
    method Unmarshal (line 834) | func (m *ConfigClientMachineInitial) Unmarshal(dAtA []byte) error {
  type ConfigClientMachineBenchmarkOptions (line 45) | type ConfigClientMachineBenchmarkOptions struct
    method Reset (line 58) | func (m *ConfigClientMachineBenchmarkOptions) Reset()         { *m = C...
    method String (line 59) | func (m *ConfigClientMachineBenchmarkOptions) String() string { return...
    method ProtoMessage (line 60) | func (*ConfigClientMachineBenchmarkOptions) ProtoMessage()    {}
    method Descriptor (line 61) | func (*ConfigClientMachineBenchmarkOptions) Descriptor() ([]byte, []in...
    method Marshal (line 234) | func (m *ConfigClientMachineBenchmarkOptions) Marshal() (dAtA []byte, ...
    method MarshalTo (line 244) | func (m *ConfigClientMachineBenchmarkOptions) MarshalTo(dAtA []byte) (...
    method Size (line 676) | func (m *ConfigClientMachineBenchmarkOptions) Size() (n int) {
    method Unmarshal (line 1319) | func (m *ConfigClientMachineBenchmarkOptions) Unmarshal(dAtA []byte) e...
  type ConfigClientMachineBenchmarkSteps (line 66) | type ConfigClientMachineBenchmarkSteps struct
    method Reset (line 73) | func (m *ConfigClientMachineBenchmarkSteps) Reset()         { *m = Con...
    method String (line 74) | func (m *ConfigClientMachineBenchmarkSteps) String() string { return p...
    method ProtoMessage (line 75) | func (*ConfigClientMachineBenchmarkSteps) ProtoMessage()    {}
    method Descriptor (line 76) | func (*ConfigClientMachineBenchmarkSteps) Descriptor() ([]byte, []int) {
    method Marshal (line 326) | func (m *ConfigClientMachineBenchmarkSteps) Marshal() (dAtA []byte, er...
    method MarshalTo (line 336) | func (m *ConfigClientMachineBenchmarkSteps) MarshalTo(dAtA []byte) (in...
    method Size (line 717) | func (m *ConfigClientMachineBenchmarkSteps) Size() (n int) {
    method Unmarshal (line 1614) | func (m *ConfigClientMachineBenchmarkSteps) Unmarshal(dAtA []byte) err...
  type ConfigClientMachineAgentControl (line 81) | type ConfigClientMachineAgentControl struct
    method Reset (line 103) | func (m *ConfigClientMachineAgentControl) Reset()         { *m = Confi...
    method String (line 104) | func (m *ConfigClientMachineAgentControl) String() string { return pro...
    method ProtoMessage (line 105) | func (*ConfigClientMachineAgentControl) ProtoMessage()    {}
    method Descriptor (line 106) | func (*ConfigClientMachineAgentControl) Descriptor() ([]byte, []int) {
    method Marshal (line 384) | func (m *ConfigClientMachineAgentControl) Marshal() (dAtA []byte, err ...
    method MarshalTo (line 394) | func (m *ConfigClientMachineAgentControl) MarshalTo(dAtA []byte) (int,...
    method Size (line 735) | func (m *ConfigClientMachineAgentControl) Size() (n int) {
    method Unmarshal (line 1744) | func (m *ConfigClientMachineAgentControl) Unmarshal(dAtA []byte) error {
  function init (line 110) | func init() {
  function encodeVarintConfigClientMachine (line 601) | func encodeVarintConfigClientMachine(dAtA []byte, offset int, v uint64) ...
  function sovConfigClientMachine (line 821) | func sovConfigClientMachine(x uint64) (n int) {
  function sozConfigClientMachine (line 831) | func sozConfigClientMachine(x uint64) (n int) {
  function skipConfigClientMachine (line 2365) | func skipConfigClientMachine(dAtA []byte) (n int, err error) {
  function init (line 2470) | func init() {

FILE: dbtesterpb/database_id.pb.go
  type DatabaseID (line 19) | type DatabaseID
    method String (line 58) | func (x DatabaseID) String() string {
    method EnumDescriptor (line 61) | func (DatabaseID) EnumDescriptor() ([]byte, []int) { return fileDescri...
  constant DatabaseID_etcd__other (line 23) | DatabaseID_etcd__other DatabaseID = 0
  constant DatabaseID_etcd__tip (line 24) | DatabaseID_etcd__tip   DatabaseID = 1
  constant DatabaseID_etcd__v3_2 (line 25) | DatabaseID_etcd__v3_2  DatabaseID = 2
  constant DatabaseID_etcd__v3_3 (line 26) | DatabaseID_etcd__v3_3  DatabaseID = 3
  constant DatabaseID_zookeeper__r3_5_3_beta (line 28) | DatabaseID_zookeeper__r3_5_3_beta DatabaseID = 100
  constant DatabaseID_consul__v1_0_2 (line 30) | DatabaseID_consul__v1_0_2 DatabaseID = 200
  constant DatabaseID_zetcd__beta (line 32) | DatabaseID_zetcd__beta DatabaseID = 300
  constant DatabaseID_cetcd__beta (line 34) | DatabaseID_cetcd__beta DatabaseID = 400
  function init (line 63) | func init() {
  function init (line 67) | func init() { proto.RegisterFile("dbtesterpb/database_id.proto", fileDes...

FILE: dbtesterpb/flag_cetcd.pb.go
  type Flag_Cetcd_Beta (line 20) | type Flag_Cetcd_Beta struct
    method Reset (line 23) | func (m *Flag_Cetcd_Beta) Reset()                    { *m = Flag_Cetcd...
    method String (line 24) | func (m *Flag_Cetcd_Beta) String() string            { return proto.Co...
    method ProtoMessage (line 25) | func (*Flag_Cetcd_Beta) ProtoMessage()               {}
    method Descriptor (line 26) | func (*Flag_Cetcd_Beta) Descriptor() ([]byte, []int) { return fileDesc...
    method Marshal (line 31) | func (m *Flag_Cetcd_Beta) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 41) | func (m *Flag_Cetcd_Beta) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 58) | func (m *Flag_Cetcd_Beta) Size() (n int) {
    method Unmarshal (line 77) | func (m *Flag_Cetcd_Beta) Unmarshal(dAtA []byte) error {
  function init (line 28) | func init() {
  function encodeVarintFlagCetcd (line 49) | func encodeVarintFlagCetcd(dAtA []byte, offset int, v uint64) int {
  function sovFlagCetcd (line 64) | func sovFlagCetcd(x uint64) (n int) {
  function sozFlagCetcd (line 74) | func sozFlagCetcd(x uint64) (n int) {
  function skipFlagCetcd (line 127) | func skipFlagCetcd(dAtA []byte) (n int, err error) {
  function init (line 232) | func init() { proto.RegisterFile("dbtesterpb/flag_cetcd.proto", fileDesc...

FILE: dbtesterpb/flag_consul.pb.go
  type Flag_Consul_V1_0_2 (line 19) | type Flag_Consul_V1_0_2 struct
    method Reset (line 22) | func (m *Flag_Consul_V1_0_2) Reset()                    { *m = Flag_Co...
    method String (line 23) | func (m *Flag_Consul_V1_0_2) String() string            { return proto...
    method ProtoMessage (line 24) | func (*Flag_Consul_V1_0_2) ProtoMessage()               {}
    method Descriptor (line 25) | func (*Flag_Consul_V1_0_2) Descriptor() ([]byte, []int) { return fileD...
    method Marshal (line 30) | func (m *Flag_Consul_V1_0_2) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 40) | func (m *Flag_Consul_V1_0_2) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 57) | func (m *Flag_Consul_V1_0_2) Size() (n int) {
    method Unmarshal (line 76) | func (m *Flag_Consul_V1_0_2) Unmarshal(dAtA []byte) error {
  function init (line 27) | func init() {
  function encodeVarintFlagConsul (line 48) | func encodeVarintFlagConsul(dAtA []byte, offset int, v uint64) int {
  function sovFlagConsul (line 63) | func sovFlagConsul(x uint64) (n int) {
  function sozFlagConsul (line 73) | func sozFlagConsul(x uint64) (n int) {
  function skipFlagConsul (line 126) | func skipFlagConsul(dAtA []byte) (n int, err error) {
  function init (line 231) | func init() { proto.RegisterFile("dbtesterpb/flag_consul.proto", fileDes...

FILE: dbtesterpb/flag_etcd.pb.go
  type Flag_Etcd_Other (line 19) | type Flag_Etcd_Other struct
    method Reset (line 24) | func (m *Flag_Etcd_Other) Reset()                    { *m = Flag_Etcd_...
    method String (line 25) | func (m *Flag_Etcd_Other) String() string            { return proto.Co...
    method ProtoMessage (line 26) | func (*Flag_Etcd_Other) ProtoMessage()               {}
    method Descriptor (line 27) | func (*Flag_Etcd_Other) Descriptor() ([]byte, []int) { return fileDesc...
    method Marshal (line 68) | func (m *Flag_Etcd_Other) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 78) | func (m *Flag_Etcd_Other) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 189) | func (m *Flag_Etcd_Other) Size() (n int) {
    method Unmarshal (line 250) | func (m *Flag_Etcd_Other) Unmarshal(dAtA []byte) error {
  type Flag_Etcd_Tip (line 30) | type Flag_Etcd_Tip struct
    method Reset (line 35) | func (m *Flag_Etcd_Tip) Reset()                    { *m = Flag_Etcd_Ti...
    method String (line 36) | func (m *Flag_Etcd_Tip) String() string            { return proto.Comp...
    method ProtoMessage (line 37) | func (*Flag_Etcd_Tip) ProtoMessage()               {}
    method Descriptor (line 38) | func (*Flag_Etcd_Tip) Descriptor() ([]byte, []int) { return fileDescri...
    method Marshal (line 96) | func (m *Flag_Etcd_Tip) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 106) | func (m *Flag_Etcd_Tip) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 201) | func (m *Flag_Etcd_Tip) Size() (n int) {
    method Unmarshal (line 338) | func (m *Flag_Etcd_Tip) Unmarshal(dAtA []byte) error {
  type Flag_Etcd_V3_2 (line 41) | type Flag_Etcd_V3_2 struct
    method Reset (line 46) | func (m *Flag_Etcd_V3_2) Reset()                    { *m = Flag_Etcd_V...
    method String (line 47) | func (m *Flag_Etcd_V3_2) String() string            { return proto.Com...
    method ProtoMessage (line 48) | func (*Flag_Etcd_V3_2) ProtoMessage()               {}
    method Descriptor (line 49) | func (*Flag_Etcd_V3_2) Descriptor() ([]byte, []int) { return fileDescr...
    method Marshal (line 124) | func (m *Flag_Etcd_V3_2) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 134) | func (m *Flag_Etcd_V3_2) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 213) | func (m *Flag_Etcd_V3_2) Size() (n int) {
    method Unmarshal (line 426) | func (m *Flag_Etcd_V3_2) Unmarshal(dAtA []byte) error {
  type Flag_Etcd_V3_3 (line 52) | type Flag_Etcd_V3_3 struct
    method Reset (line 57) | func (m *Flag_Etcd_V3_3) Reset()                    { *m = Flag_Etcd_V...
    method String (line 58) | func (m *Flag_Etcd_V3_3) String() string            { return proto.Com...
    method ProtoMessage (line 59) | func (*Flag_Etcd_V3_3) ProtoMessage()               {}
    method Descriptor (line 60) | func (*Flag_Etcd_V3_3) Descriptor() ([]byte, []int) { return fileDescr...
    method Marshal (line 152) | func (m *Flag_Etcd_V3_3) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 162) | func (m *Flag_Etcd_V3_3) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 225) | func (m *Flag_Etcd_V3_3) Size() (n int) {
    method Unmarshal (line 514) | func (m *Flag_Etcd_V3_3) Unmarshal(dAtA []byte) error {
  function init (line 62) | func init() {
  function encodeVarintFlagEtcd (line 180) | func encodeVarintFlagEtcd(dAtA []byte, offset int, v uint64) int {
  function sovFlagEtcd (line 237) | func sovFlagEtcd(x uint64) (n int) {
  function sozFlagEtcd (line 247) | func sozFlagEtcd(x uint64) (n int) {
  function skipFlagEtcd (line 602) | func skipFlagEtcd(dAtA []byte) (n int, err error) {
  function init (line 707) | func init() { proto.RegisterFile("dbtesterpb/flag_etcd.proto", fileDescr...

FILE: dbtesterpb/flag_zetcd.pb.go
  type Flag_Zetcd_Beta (line 20) | type Flag_Zetcd_Beta struct
    method Reset (line 23) | func (m *Flag_Zetcd_Beta) Reset()                    { *m = Flag_Zetcd...
    method String (line 24) | func (m *Flag_Zetcd_Beta) String() string            { return proto.Co...
    method ProtoMessage (line 25) | func (*Flag_Zetcd_Beta) ProtoMessage()               {}
    method Descriptor (line 26) | func (*Flag_Zetcd_Beta) Descriptor() ([]byte, []int) { return fileDesc...
    method Marshal (line 31) | func (m *Flag_Zetcd_Beta) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 41) | func (m *Flag_Zetcd_Beta) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 58) | func (m *Flag_Zetcd_Beta) Size() (n int) {
    method Unmarshal (line 77) | func (m *Flag_Zetcd_Beta) Unmarshal(dAtA []byte) error {
  function init (line 28) | func init() {
  function encodeVarintFlagZetcd (line 49) | func encodeVarintFlagZetcd(dAtA []byte, offset int, v uint64) int {
  function sovFlagZetcd (line 64) | func sovFlagZetcd(x uint64) (n int) {
  function sozFlagZetcd (line 74) | func sozFlagZetcd(x uint64) (n int) {
  function skipFlagZetcd (line 127) | func skipFlagZetcd(dAtA []byte) (n int, err error) {
  function init (line 232) | func init() { proto.RegisterFile("dbtesterpb/flag_zetcd.proto", fileDesc...

FILE: dbtesterpb/flag_zookeeper.pb.go
  type Flag_Zookeeper_R3_5_3Beta (line 18) | type Flag_Zookeeper_R3_5_3Beta struct
    method Reset (line 45) | func (m *Flag_Zookeeper_R3_5_3Beta) Reset()         { *m = Flag_Zookee...
    method String (line 46) | func (m *Flag_Zookeeper_R3_5_3Beta) String() string { return proto.Com...
    method ProtoMessage (line 47) | func (*Flag_Zookeeper_R3_5_3Beta) ProtoMessage()    {}
    method Descriptor (line 48) | func (*Flag_Zookeeper_R3_5_3Beta) Descriptor() ([]byte, []int) {
    method Marshal (line 55) | func (m *Flag_Zookeeper_R3_5_3Beta) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 65) | func (m *Flag_Zookeeper_R3_5_3Beta) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 148) | func (m *Flag_Zookeeper_R3_5_3Beta) Size() (n int) {
    method Unmarshal (line 199) | func (m *Flag_Zookeeper_R3_5_3Beta) Unmarshal(dAtA []byte) error {
  function init (line 52) | func init() {
  function encodeVarintFlagZookeeper (line 139) | func encodeVarintFlagZookeeper(dAtA []byte, offset int, v uint64) int {
  function sovFlagZookeeper (line 186) | func sovFlagZookeeper(x uint64) (n int) {
  function sozFlagZookeeper (line 196) | func sozFlagZookeeper(x uint64) (n int) {
  function skipFlagZookeeper (line 459) | func skipFlagZookeeper(dAtA []byte) (n int, err error) {
  function init (line 564) | func init() { proto.RegisterFile("dbtesterpb/flag_zookeeper.proto", file...

FILE: dbtesterpb/message.pb.go
  type Operation (line 21) | type Operation
    method String (line 40) | func (x Operation) String() string {
    method EnumDescriptor (line 43) | func (Operation) EnumDescriptor() ([]byte, []int) { return fileDescrip...
  constant Operation_Start (line 24) | Operation_Start     Operation = 0
  constant Operation_Stop (line 25) | Operation_Stop      Operation = 1
  constant Operation_Heartbeat (line 26) | Operation_Heartbeat Operation = 2
  type Request (line 45) | type Request struct
    method Reset (line 67) | func (m *Request) Reset()                    { *m = Request{} }
    method String (line 68) | func (m *Request) String() string            { return proto.CompactTex...
    method ProtoMessage (line 69) | func (*Request) ProtoMessage()               {}
    method Descriptor (line 70) | func (*Request) Descriptor() ([]byte, []int) { return fileDescriptorMe...
    method Marshal (line 162) | func (m *Request) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 172) | func (m *Request) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 370) | func (m *Request) Size() (n int) {
    method Unmarshal (line 460) | func (m *Request) Unmarshal(dAtA []byte) error {
  type Response (line 72) | type Response struct
    method Reset (line 79) | func (m *Response) Reset()                    { *m = Response{} }
    method String (line 80) | func (m *Response) String() string            { return proto.CompactTe...
    method ProtoMessage (line 81) | func (*Response) ProtoMessage()               {}
    method Descriptor (line 82) | func (*Response) Descriptor() ([]byte, []int) { return fileDescriptorM...
    method Marshal (line 328) | func (m *Response) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 338) | func (m *Response) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 435) | func (m *Response) Size() (n int) {
    method Unmarshal (line 961) | func (m *Response) Unmarshal(dAtA []byte) error {
  function init (line 84) | func init() {
  constant _ (line 96) | _ = grpc.SupportPackageIsVersion4
  type TransporterClient (line 100) | type TransporterClient interface
  type transporterClient (line 104) | type transporterClient struct
    method Transfer (line 112) | func (c *transporterClient) Transfer(ctx context.Context, in *Request,...
  function NewTransporterClient (line 108) | func NewTransporterClient(cc *grpc.ClientConn) TransporterClient {
  type TransporterServer (line 123) | type TransporterServer interface
  function RegisterTransporterServer (line 127) | func RegisterTransporterServer(s *grpc.Server, srv TransporterServer) {
  function _Transporter_Transfer_Handler (line 131) | func _Transporter_Transfer_Handler(srv interface{}, ctx context.Context,...
  function encodeVarintMessage (line 361) | func encodeVarintMessage(dAtA []byte, offset int, v uint64) int {
  function sovMessage (line 447) | func sovMessage(x uint64) (n int) {
  function sozMessage (line 457) | func sozMessage(x uint64) (n int) {
  function skipMessage (line 1050) | func skipMessage(dAtA []byte) (n int, err error) {
  function init (line 1155) | func init() { proto.RegisterFile("dbtesterpb/message.proto", fileDescrip...

FILE: dbtesterpb/util.go
  function IsValidDatabaseID (line 25) | func IsValidDatabaseID(id string) bool {
  function GetAllDatabaseIDs (line 31) | func GetAllDatabaseIDs() []string {
  function GetRGBI (line 40) | func GetRGBI(databaseID string, i int) color.Color {
  function GetRGBII (line 62) | func GetRGBII(databaseID string, i int) color.Color {
  function GetRGBIII (line 84) | func GetRGBIII(databaseID string, i int) color.Color {

FILE: find_ranges.go
  type CumulativeKeyNumToAvgLatency (line 27) | type CumulativeKeyNumToAvgLatency struct
  type CumulativeKeyNumToAvgLatencySlice (line 36) | type CumulativeKeyNumToAvgLatencySlice
    method Swap (line 38) | func (t CumulativeKeyNumToAvgLatencySlice) Swap(i, j int) { t[i], t[j]...
    method Len (line 39) | func (t CumulativeKeyNumToAvgLatencySlice) Len() int      { return len...
    method Less (line 40) | func (t CumulativeKeyNumToAvgLatencySlice) Less(i, j int) bool {
  function FindRangesLatency (line 59) | func FindRangesLatency(data report.TimeSeries, unit int64, totalRequests...
  type CumulativeKeyNumAndOtherData (line 123) | type CumulativeKeyNumAndOtherData struct
  type CumulativeKeyNumAndOtherDataSlice (line 138) | type CumulativeKeyNumAndOtherDataSlice
    method Swap (line 140) | func (t CumulativeKeyNumAndOtherDataSlice) Swap(i, j int) { t[i], t[j]...
    method Len (line 141) | func (t CumulativeKeyNumAndOtherDataSlice) Len() int      { return len...
    method Less (line 142) | func (t CumulativeKeyNumAndOtherDataSlice) Less(i, j int) bool {
  type CumulativeKeyNumAndOtherDataByUnixSecond (line 147) | type CumulativeKeyNumAndOtherDataByUnixSecond
    method Swap (line 149) | func (t CumulativeKeyNumAndOtherDataByUnixSecond) Swap(i, j int) { t[i...
    method Len (line 150) | func (t CumulativeKeyNumAndOtherDataByUnixSecond) Len() int      { ret...
    method Less (line 151) | func (t CumulativeKeyNumAndOtherDataByUnixSecond) Less(i, j int) bool {
  function FindRangesData (line 158) | func FindRangesData(data []CumulativeKeyNumAndOtherData, unit int64, tot...

FILE: find_ranges_test.go
  function TestFindRangesLatency (line 25) | func TestFindRangesLatency(t *testing.T) {
  function TestFindRangesData (line 77) | func TestFindRangesData(t *testing.T) {

FILE: pkg/fileinspect/fileinspect.go
  function Walk (line 28) | func Walk(targetDir string) (map[string]os.FileInfo, error) {
  function Size (line 51) | func Size(targetDir string) (int64, error) {
  function walk (line 63) | func walk(targetDir string) (map[string]os.FileInfo, error) {
  type filepathSize (line 86) | type filepathSize struct
  function filterByKbs (line 92) | func filterByKbs(fs []filepathSize, kbLimit int) []filepathSize {
  type filepathSizeSlice (line 103) | type filepathSizeSlice
    method Len (line 105) | func (f filepathSizeSlice) Len() int           { return len(f) }
    method Swap (line 106) | func (f filepathSizeSlice) Swap(i, j int)      { f[i], f[j] = f[j], f[...
    method Less (line 107) | func (f filepathSizeSlice) Less(i, j int) bool { return f[i].size < f[...
  function walkDir (line 109) | func walkDir(targetDir string) ([]filepathSize, error) {

FILE: pkg/fileinspect/fileinspect_test.go
  function openToOverwrite (line 26) | func openToOverwrite(fpath string) (*os.File, error) {
  function writeData (line 34) | func writeData(fpath string, data []byte) (n int, err error) {
  function createData (line 47) | func createData() (dir string, n int64, err error) {
  function TestWalkSize (line 69) | func TestWalkSize(t *testing.T) {

FILE: pkg/ntp/ntp.go
  function DefaultSync (line 33) | func DefaultSync() (string, error) {
  function Sync (line 45) | func Sync(ntpPath string, server string) (string, error) {
  function startNTP (line 79) | func startNTP(ntpPath string, server string, w io.Writer) error {
  function serviceNTP (line 90) | func serviceNTP(command string) (string, error) {
  function exist (line 100) | func exist(fpath string) bool {

FILE: pkg/ntp/ntp_test.go
  function TestSync (line 22) | func TestSync(t *testing.T) {

FILE: pkg/remotestorage/example/main.go
  function main (line 26) | func main() {

FILE: pkg/remotestorage/op.go
  type Op (line 17) | type Op struct
    method applyOpts (line 29) | func (op *Op) applyOpts(opts []OpOption) {
  type OpOption (line 21) | type OpOption
  function WithContentType (line 23) | func WithContentType(t string) OpOption {

FILE: pkg/remotestorage/uploader.go
  type Uploader (line 32) | type Uploader interface
  type GoogleCloudStorage (line 41) | type GoogleCloudStorage struct
    method UploadFile (line 66) | func (g *GoogleCloudStorage) UploadFile(bucket, src, dst string, opts ...
    method UploadDir (line 110) | func (g *GoogleCloudStorage) UploadDir(bucket, src, dst string, opts ....
  function NewGoogleCloudStorage (line 49) | func NewGoogleCloudStorage(lg *zap.Logger, key []byte, project string) (...

FILE: pkg/remotestorage/util.go
  function walkRecursive (line 23) | func walkRecursive(dir string) (map[string]string, error) {

FILE: readme.go
  method WriteREADME (line 24) | func (cfg *Config) WriteREADME(summary string) error {

FILE: report.go
  type benchmark (line 28) | type benchmark struct
    method reset (line 61) | func (b *benchmark) reset(clientsN int64, reqHandlers []ReqHandler, re...
    method getInflightsReqs (line 75) | func (b *benchmark) getInflightsReqs() (ch chan request) {
    method startRequests (line 82) | func (b *benchmark) startRequests() {
    method waitRequestsEnd (line 102) | func (b *benchmark) waitRequestsEnd() {
    method finishReports (line 109) | func (b *benchmark) finishReports() {
    method waitAll (line 116) | func (b *benchmark) waitAll() {
  function newBenchmark (line 44) | func newBenchmark(totalN int64, clientsN int64, reqHandlers []ReqHandler...
  function printStats (line 121) | func printStats(st report.Stats) {
  method generateReport (line 139) | func (cfg *Config) generateReport(gcfg dbtesterpb.ConfigClientMachineAge...

FILE: report_save_upload.go
  method SaveDiskSpaceUsageSummary (line 41) | func (cfg *Config) SaveDiskSpaceUsageSummary(databaseID string, idxToRes...
  method saveDataLatencyDistributionSummary (line 75) | func (cfg *Config) saveDataLatencyDistributionSummary(st report.Stats) {
  method saveDataLatencyDistributionPercentile (line 135) | func (cfg *Config) saveDataLatencyDistributionPercentile(st report.Stats) {
  method saveDataLatencyDistributionAll (line 161) | func (cfg *Config) saveDataLatencyDistributionAll(st report.Stats) {
  method saveDataLatencyThroughputTimeseries (line 214) | func (cfg *Config) saveDataLatencyThroughputTimeseries(gcfg dbtesterpb.C...
  method saveAllStats (line 293) | func (cfg *Config) saveAllStats(gcfg dbtesterpb.ConfigClientMachineAgent...
  method UploadToGoogle (line 301) | func (cfg *Config) UploadToGoogle(databaseID string, targetPath string) ...

FILE: stress.go
  type values (line 35) | type values struct
  function newValues (line 41) | func newValues(gcfg dbtesterpb.ConfigClientMachineAgentControl) (v value...
  method Stress (line 49) | func (cfg *Config) Stress(databaseID string) error {
  function newReadHandlers (line 301) | func newReadHandlers(gcfg dbtesterpb.ConfigClientMachineAgentControl) (r...
  function newWriteHandlers (line 341) | func newWriteHandlers(lg *zap.Logger, gcfg dbtesterpb.ConfigClientMachin...
  function newReadOneshotHandlers (line 420) | func newReadOneshotHandlers(lg *zap.Logger, gcfg dbtesterpb.ConfigClient...
  function generateReads (line 457) | func generateReads(gcfg dbtesterpb.ConfigClientMachineAgentControl, key ...
  function generateWrites (line 500) | func generateWrites(gcfg dbtesterpb.ConfigClientMachineAgentControl, sta...

FILE: stress_client.go
  type request (line 22) | type request struct
  type ReqHandler (line 29) | type ReqHandler

FILE: stress_client_consul.go
  type consulOp (line 23) | type consulOp struct
  function mustCreateConnsConsul (line 29) | func mustCreateConnsConsul(endpoints []string, total int64) []*consulapi...
  function newPutConsul (line 47) | func newPutConsul(conn *consulapi.KV) ReqHandler {
  function newGetConsul (line 55) | func newGetConsul(conn *consulapi.KV) ReqHandler {
  function getTotalKeysConsul (line 71) | func getTotalKeysConsul(lg *zap.Logger, endpoints []string) map[string]i...

FILE: stress_client_etcdv3.go
  function newPutEtcd3 (line 30) | func newPutEtcd3(conn clientv3.KV) ReqHandler {
  function mustCreateConnEtcdv3 (line 41) | func mustCreateConnEtcdv3(endpoints []string) *clientv3.Client {
  type etcdv3ClientCfg (line 62) | type etcdv3ClientCfg struct
  function mustCreateClientsEtcdv3 (line 67) | func mustCreateClientsEtcdv3(endpoints []string, cfg etcdv3ClientCfg) []...
  function newGetEtcd3 (line 80) | func newGetEtcd3(conn clientv3.KV) ReqHandler {
  function getTotalKeysEtcdv3 (line 87) | func getTotalKeysEtcdv3(lg *zap.Logger, endpoints []string) map[string]i...

FILE: stress_client_zookeeper.go
  type zkOp (line 32) | type zkOp struct
  function mustCreateConnsZk (line 38) | func mustCreateConnsZk(endpoints []string, total int64) []*zk.Conn {
  function newPutCreateZK (line 52) | func newPutCreateZK(conn *zk.Conn) ReqHandler {
  function newPutOverwriteZK (line 60) | func newPutOverwriteZK(conn *zk.Conn) ReqHandler {
  function newGetZK (line 69) | func newGetZK(conn *zk.Conn) ReqHandler {
  function getTotalKeysZk (line 92) | func getTotalKeysZk(lg *zap.Logger, endpoints []string) map[string]int64 {

FILE: util.go
  function toMillisecond (line 28) | func toMillisecond(d time.Duration) float64 {
  function assignRequest (line 32) | func assignRequest(ranges []int64, total int64) (rs []int64) {
  function toFile (line 56) | func toFile(txt, fpath string) error {
  function exist (line 71) | func exist(fpath string) bool {
  function gracefulClose (line 92) | func gracefulClose(resp *http.Response) {
  function sequentialKey (line 98) | func sequentialKey(size, num int64) string {
  function sameKey (line 107) | func sameKey(size int64) string {
  function randBytes (line 111) | func randBytes(bytesN int64) []byte {

FILE: util_test.go
  function Test_assignRequest (line 22) | func Test_assignRequest(t *testing.T) {

FILE: vendor/bitbucket.org/zombiezen/gopdf/pdf/canvas.go
  function writeCommand (line 14) | func writeCommand(w io.Writer, op string, args ...interface{}) error {
  type Canvas (line 36) | type Canvas struct
    method Document (line 45) | func (canvas *Canvas) Document() *Document {
    method Close (line 51) | func (canvas *Canvas) Close() error {
    method Size (line 56) | func (canvas *Canvas) Size() (width, height Unit) {
    method SetSize (line 62) | func (canvas *Canvas) SetSize(width, height Unit) {
    method CropBox (line 67) | func (canvas *Canvas) CropBox() Rectangle {
    method SetCropBox (line 72) | func (canvas *Canvas) SetCropBox(crop Rectangle) {
    method FillStroke (line 79) | func (canvas *Canvas) FillStroke(p *Path) {
    method Fill (line 85) | func (canvas *Canvas) Fill(p *Path) {
    method Stroke (line 91) | func (canvas *Canvas) Stroke(p *Path) {
    method SetLineWidth (line 97) | func (canvas *Canvas) SetLineWidth(w Unit) {
    method SetLineDash (line 108) | func (canvas *Canvas) SetLineDash(phase Unit, dash []Unit) {
    method SetColor (line 114) | func (canvas *Canvas) SetColor(r, g, b float32) {
    method SetStrokeColor (line 120) | func (canvas *Canvas) SetStrokeColor(r, g, b float32) {
    method Push (line 126) | func (canvas *Canvas) Push() {
    method Pop (line 132) | func (canvas *Canvas) Pop() {
    method Translate (line 137) | func (canvas *Canvas) Translate(x, y Unit) {
    method Rotate (line 142) | func (canvas *Canvas) Rotate(theta float32) {
    method Scale (line 148) | func (canvas *Canvas) Scale(x, y float32) {
    method Transform (line 160) | func (canvas *Canvas) Transform(a, b, c, d, e, f float32) {
    method DrawText (line 165) | func (canvas *Canvas) DrawText(text *Text) {
    method DrawImage (line 179) | func (canvas *Canvas) DrawImage(img image.Image, rect Rectangle) {
    method DrawImageReference (line 185) | func (canvas *Canvas) DrawImageReference(ref Reference, rect Rectangle) {
    method DrawLine (line 197) | func (canvas *Canvas) DrawLine(pt1, pt2 Point) {
    method nextImageName (line 206) | func (canvas *Canvas) nextImageName() name {
  constant anonymousImageFormat (line 204) | anonymousImageFormat = "__image%d__"
  type Path (line 220) | type Path struct
    method Move (line 225) | func (path *Path) Move(pt Point) {
    method Line (line 230) | func (path *Path) Line(pt Point) {
    method Curve (line 235) | func (path *Path) Curve(pt1, pt2, pt3 Point) {
    method Rectangle (line 240) | func (path *Path) Rectangle(rect Rectangle) {
    method Close (line 246) | func (path *Path) Close() {

FILE: vendor/bitbucket.org/zombiezen/gopdf/pdf/encode.go
  type encoder (line 11) | type encoder struct
    method add (line 23) | func (enc *encoder) add(v interface{}) Reference {
    method encode (line 48) | func (enc *encoder) encode(wr io.Writer) error {
    method writeHeader (line 73) | func (enc *encoder) writeHeader(w *offsetWriter) error {
    method writeBody (line 78) | func (enc *encoder) writeBody(w *offsetWriter) ([]int64, error) {
    method writeXrefTable (line 94) | func (enc *encoder) writeXrefTable(w *offsetWriter, objectOffsets []in...
    method writeTrailer (line 112) | func (enc *encoder) writeTrailer(w *offsetWriter) error {
    method writeStartxref (line 129) | func (enc *encoder) writeStartxref(w *offsetWriter, tableOffset int64)...
    method writeEOF (line 134) | func (enc *encoder) writeEOF(w *offsetWriter) error {
  type trailer (line 16) | type trailer struct
  constant header (line 29) | header  = "%PDF-1.7" + newline + "%\x93\x8c\x8b\x9e" + newline
  constant newline (line 30) | newline = "\r\n"
  constant crossReferenceSectionHeader (line 35) | crossReferenceSectionHeader    = "xref" + newline
  constant crossReferenceSubsectionFormat (line 36) | crossReferenceSubsectionFormat = "%d %d" + newline
  constant crossReferenceFormat (line 37) | crossReferenceFormat           = "%010d %05d n" + newline
  constant crossReferenceFreeFormat (line 38) | crossReferenceFreeFormat       = "%010d %05d f" + newline
  constant trailerHeader (line 41) | trailerHeader = "trailer" + newline
  constant startxrefFormat (line 43) | startxrefFormat = "startxref" + newline + "%d" + newline
  constant eofString (line 45) | eofString = "%%EOF" + newline
  type offsetWriter (line 140) | type offsetWriter struct
    method Write (line 145) | func (w *offsetWriter) Write(p []byte) (n int, err error) {

FILE: vendor/bitbucket.org/zombiezen/gopdf/pdf/image.go
  constant deviceRGBColorSpace (line 12) | deviceRGBColorSpace name = "DeviceRGB"
  type imageStream (line 15) | type imageStream struct
    method marshalPDF (line 44) | func (st *imageStream) marshalPDF(dst []byte) ([]byte, error) {
  type imageStreamInfo (line 23) | type imageStreamInfo struct
  function newImageStream (line 34) | func newImageStream(filter name, w, h int) *imageStream {
  function encodeImageStream (line 58) | func encodeImageStream(w io.Writer, img image.Image) error {
  function encodeRGBAStream (line 83) | func encodeRGBAStream(w io.Writer, img *image.RGBA) error {
  function encodeNRGBAStream (line 98) | func encodeNRGBAStream(w io.Writer, img *image.NRGBA) error {
  function encodeYCbCrStream (line 109) | func encodeYCbCrStream(w io.Writer, img *image.YCbCr) error {

FILE: vendor/bitbucket.org/zombiezen/gopdf/pdf/marshal.go
  type marshaler (line 13) | type marshaler interface
  function marshal (line 22) | func marshal(dst []byte, v interface{}) ([]byte, error) {
  type marshalState (line 30) | type marshalState struct
    method writeString (line 36) | func (state *marshalState) writeString(s string) {
    method marshalValue (line 40) | func (state *marshalState) marshalValue(v reflect.Value) error {
    method marshalSlice (line 95) | func (state *marshalState) marshalSlice(v reflect.Value) error {
    method marshalDictionary (line 107) | func (state *marshalState) marshalDictionary(v reflect.Value) error {
    method marshalStruct (line 120) | func (state *marshalState) marshalStruct(v reflect.Value) error {
    method marshalKeyValue (line 154) | func (state *marshalState) marshalKeyValue(k name, v reflect.Value) er...
  constant marshalFloatPrec (line 34) | marshalFloatPrec = 5
  function quote (line 82) | func quote(s string) string {
  type tagOptions (line 170) | type tagOptions
    method Contains (line 177) | func (options tagOptions) Contains(opt string) bool {
  function parseTag (line 172) | func parseTag(tag string) (name string, options tagOptions) {
  function isEmptyValue (line 186) | func isEmptyValue(v reflect.Value) bool {

FILE: vendor/bitbucket.org/zombiezen/gopdf/pdf/objects.go
  type name (line 11) | type name
    method String (line 13) | func (n name) String() string {
    method marshalPDF (line 17) | func (n name) marshalPDF(dst []byte) ([]byte, error) {
  type indirectObject (line 23) | type indirectObject struct
    method marshalPDF (line 33) | func (obj indirectObject) marshalPDF(dst []byte) ([]byte, error) {
  constant objectBegin (line 29) | objectBegin = " obj\r\n"
  constant objectEnd (line 30) | objectEnd   = "\r\nendobj"
  type Reference (line 48) | type Reference struct
    method marshalPDF (line 53) | func (ref Reference) marshalPDF(dst []byte) ([]byte, error) {

FILE: vendor/bitbucket.org/zombiezen/gopdf/pdf/pdf.go
  type Unit (line 13) | type Unit
    method String (line 15) | func (unit Unit) String() string {
  constant Pt (line 21) | Pt   Unit = 1
  constant Inch (line 22) | Inch Unit = 72
  constant Cm (line 23) | Cm   Unit = 28.35
  constant USLetterWidth (line 28) | USLetterWidth  Unit = 8.5 * Inch
  constant USLetterHeight (line 29) | USLetterHeight Unit = 11.0 * Inch
  constant A4Width (line 31) | A4Width  Unit = 21.0 * Cm
  constant A4Height (line 32) | A4Height Unit = 29.7 * Cm
  type Document (line 36) | type Document struct
    method NewPage (line 55) | func (doc *Document) NewPage(width, height Unit) *Canvas {
    method standardFont (line 83) | func (doc *Document) standardFont(fontName name) Reference {
    method AddImage (line 101) | func (doc *Document) AddImage(img image.Image) Reference {
    method Encode (line 120) | func (doc *Document) Encode(w io.Writer) error {
  function New (line 44) | func New() *Document {
  constant catalogType (line 137) | catalogType  name = "Catalog"
  constant pageNodeType (line 138) | pageNodeType name = "Pages"
  constant pageType (line 139) | pageType     name = "Page"
  constant fontType (line 140) | fontType     name = "Font"
  constant xobjectType (line 141) | xobjectType  name = "XObject"
  constant imageSubtype (line 146) | imageSubtype name = "Image"
  constant fontType1Subtype (line 148) | fontType1Subtype name = "Type1"
  type catalog (line 151) | type catalog struct
  type pageRootNode (line 156) | type pageRootNode struct
  type pageNode (line 162) | type pageNode struct
  type pageDict (line 169) | type pageDict struct
  type Point (line 179) | type Point struct
  type Rectangle (line 184) | type Rectangle struct
    method Dx (line 189) | func (r Rectangle) Dx() Unit {
    method Dy (line 194) | func (r Rectangle) Dy() Unit {
    method marshalPDF (line 198) | func (r Rectangle) marshalPDF(dst []byte) ([]byte, error) {
  type resources (line 211) | type resources struct
  constant pdfProcSet (line 219) | pdfProcSet    name = "PDF"
  constant textProcSet (line 220) | textProcSet   name = "Text"
  constant imageBProcSet (line 221) | imageBProcSet name = "ImageB"
  constant imageCProcSet (line 222) | imageCProcSet name = "ImageC"
  constant imageIProcSet (line 223) | imageIProcSet name = "ImageI"
  type standardFontDict (line 226) | type standardFontDict struct

FILE: vendor/bitbucket.org/zombiezen/gopdf/pdf/stream.go
  constant streamNoFilter (line 11) | streamNoFilter    name = ""
  constant streamLZWDecode (line 12) | streamLZWDecode   name = "LZWDecode"
  constant streamFlateDecode (line 13) | streamFlateDecode name = "FlateDecode"
  type stream (line 17) | type stream struct
    method ReadFrom (line 43) | func (st *stream) ReadFrom(r io.Reader) (n int64, err error) {
    method Write (line 47) | func (st *stream) Write(p []byte) (n int, err error) {
    method WriteByte (line 51) | func (st *stream) WriteByte(c byte) error {
    method WriteString (line 56) | func (st *stream) WriteString(s string) (n int, err error) {
    method Close (line 60) | func (st *stream) Close() error {
    method marshalPDF (line 67) | func (st *stream) marshalPDF(dst []byte) ([]byte, error) {
  type streamInfo (line 23) | type streamInfo struct
  function newStream (line 28) | func newStream(filter name) *stream {
  constant streamBegin (line 75) | streamBegin = " stream\r\n"
  constant streamEnd (line 76) | streamEnd   = "\r\nendstream"
  function marshalStream (line 82) | func marshalStream(dst []byte, obj interface{}, data []byte) ([]byte, er...

FILE: vendor/bitbucket.org/zombiezen/gopdf/pdf/text.go
  type Text (line 10) | type Text struct
    method Text (line 21) | func (text *Text) Text(s string) {
    method SetFont (line 32) | func (text *Text) SetFont(fontName string, size Unit) {
    method SetLeading (line 43) | func (text *Text) SetLeading(leading Unit) {
    method NextLine (line 50) | func (text *Text) NextLine() {
    method NextLineOffset (line 58) | func (text *Text) NextLineOffset(tx, ty Unit) {
    method X (line 65) | func (text *Text) X() Unit {
    method Y (line 70) | func (text *Text) Y() Unit {
  constant defaultLeadingScalar (line 28) | defaultLeadingScalar = 1.2
  constant Courier (line 76) | Courier            = "Courier"
  constant CourierBold (line 77) | CourierBold        = "Courier-Bold"
  constant CourierOblique (line 78) | CourierOblique     = "Courier-Oblique"
  constant CourierBoldOblique (line 79) | CourierBoldOblique = "Courier-BoldOblique"
  constant Helvetica (line 81) | Helvetica            = "Helvetica"
  constant HelveticaBold (line 82) | HelveticaBold        = "Helvetica-Bold"
  constant HelveticaOblique (line 83) | HelveticaOblique     = "Helvetica-Oblique"
  constant HelveticaBoldOblique (line 84) | HelveticaBoldOblique = "Helvetica-BoldOblique"
  constant Symbol (line 86) | Symbol = "Symbol"
  constant Times (line 88) | Times           = "Times-Roman"
  constant TimesBold (line 89) | TimesBold       = "Times-Bold"
  constant TimesItalic (line 90) | TimesItalic     = "Times-Italic"
  constant TimesBoldItalic (line 91) | TimesBoldItalic = "Times-BoldItalic"
  constant ZapfDingbats (line 93) | ZapfDingbats = "ZapfDingbats"
  function getFontWidths (line 96) | func getFontWidths(fontName name) []uint16 {
  function computeStringWidth (line 130) | func computeStringWidth(s string, widths []uint16, fontSize Unit) Unit {

FILE: vendor/cloud.google.com/go/compute/metadata/metadata.go
  constant metadataIP (line 41) | metadataIP = "169.254.169.254"
  constant metadataHostEnv (line 48) | metadataHostEnv = "GCE_METADATA_HOST"
  constant userAgent (line 50) | userAgent = "gcloud-golang/0.1"
  type cachedValue (line 53) | type cachedValue struct
    method get (line 156) | func (c *cachedValue) get() (v string, err error) {
  type NotDefinedError (line 92) | type NotDefinedError
    method Error (line 94) | func (suffix NotDefinedError) Error() string {
  function Get (line 106) | func Get(suffix string) (string, error) {
  function getETag (line 113) | func getETag(client *http.Client, suffix string) (value, etag string, er...
  function getTrimmed (line 150) | func getTrimmed(suffix string) (s string, err error) {
  function OnGCE (line 179) | func OnGCE() bool {
  function initOnGCE (line 184) | func initOnGCE() {
  function testOnGCE (line 188) | func testOnGCE() bool {
  function systemInfoSuggestsGCE (line 259) | func systemInfoSuggestsGCE() bool {
  function Subscribe (line 278) | func Subscribe(suffix string, fn func(v string, ok bool) error) error {
  function ProjectID (line 315) | func ProjectID() (string, error) { return projID.get() }
  function NumericProjectID (line 318) | func NumericProjectID() (string, error) { return projNum.get() }
  function InternalIP (line 321) | func InternalIP() (string, error) {
  function ExternalIP (line 326) | func ExternalIP() (string, error) {
  function Hostname (line 332) | func Hostname() (string, error) {
  function InstanceTags (line 338) | func InstanceTags() ([]string, error) {
  function InstanceID (line 351) | func InstanceID() (string, error) {
  function InstanceName (line 356) | func InstanceName() (string, error) {
  function Zone (line 365) | func Zone() (string, error) {
  function InstanceAttributes (line 377) | func InstanceAttributes() ([]string, error) { return lines("instance/att...
  function ProjectAttributes (line 382) | func ProjectAttributes() ([]string, error) { return lines("project/attri...
  function lines (line 384) | func lines(suffix string) ([]string, error) {
  function InstanceAttributeValue (line 404) | func InstanceAttributeValue(attr string) (string, error) {
  function ProjectAttributeValue (line 416) | func ProjectAttributeValue(attr string) (string, error) {
  function Scopes (line 423) | func Scopes(serviceAccount string) ([]string, error) {
  function strsContains (line 430) | func strsContains(ss []string, s string) bool {

FILE: vendor/cloud.google.com/go/iam/iam.go
  type client (line 31) | type client interface
  type grpcClient (line 38) | type grpcClient struct
    method Get (line 42) | func (g *grpcClient) Get(ctx context.Context, resource string) (*pb.Po...
    method Set (line 49) | func (g *grpcClient) Set(ctx context.Context, resource string, p *pb.P...
    method Test (line 57) | func (g *grpcClient) Test(ctx context.Context, resource string, perms ...
  type Handle (line 69) | type Handle struct
    method Policy (line 94) | func (h *Handle) Policy(ctx context.Context) (*Policy, error) {
    method SetPolicy (line 106) | func (h *Handle) SetPolicy(ctx context.Context, policy *Policy) error {
    method TestPermissions (line 111) | func (h *Handle) TestPermissions(ctx context.Context, permissions []st...
  function InternalNewHandle (line 78) | func InternalNewHandle(conn *grpc.ClientConn, resource string) *Handle {
  function InternalNewHandleClient (line 86) | func InternalNewHandleClient(c client, resource string) *Handle {
  type RoleName (line 116) | type RoleName
  constant Owner (line 120) | Owner  RoleName = "roles/owner"
  constant Editor (line 121) | Editor RoleName = "roles/editor"
  constant Viewer (line 122) | Viewer RoleName = "roles/viewer"
  constant AllUsers (line 127) | AllUsers = "allUsers"
  constant AllAuthenticatedUsers (line 130) | AllAuthenticatedUsers = "allAuthenticatedUsers"
  type Policy (line 137) | type Policy struct
    method Members (line 149) | func (p *Policy) Members(r RoleName) []string {
    method HasRole (line 158) | func (p *Policy) HasRole(member string, r RoleName) bool {
    method Add (line 164) | func (p *Policy) Add(member string, r RoleName) {
    method Remove (line 183) | func (p *Policy) Remove(member string, r RoleName) {
    method Roles (line 213) | func (p *Policy) Roles() []RoleName {
    method binding (line 225) | func (p *Policy) binding(r RoleName) *pb.Binding {
    method bindingIndex (line 233) | func (p *Policy) bindingIndex(r RoleName) int {
  function memberIndex (line 246) | func memberIndex(m string, b *pb.Binding) int {

FILE: vendor/cloud.google.com/go/internal/annotate.go
  function Annotate (line 35) | func Annotate(err error, msg string) error {
  function Annotatef (line 52) | func Annotatef(err error, format string, args ...interface{}) error {

FILE: vendor/cloud.google.com/go/internal/optional/optional.go
  type Bool (line 28) | type Bool interface
  type String (line 31) | type String interface
  type Int (line 34) | type Int interface
  type Uint (line 37) | type Uint interface
  type Float64 (line 40) | type Float64 interface
  type Duration (line 43) | type Duration interface
  function ToBool (line 48) | func ToBool(v Bool) bool {
  function ToString (line 58) | func ToString(v String) string {
  function ToInt (line 68) | func ToInt(v Int) int {
  function ToUint (line 78) | func ToUint(v Uint) uint {
  function ToFloat64 (line 88) | func ToFloat64(v Float64) float64 {
  function ToDuration (line 98) | func ToDuration(v Duration) time.Duration {
  function doPanic (line 106) | func doPanic(capType string, v interface{}) {

FILE: vendor/cloud.google.com/go/internal/retry.go
  function Retry (line 31) | func Retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err...
  function retry (line 35) | func retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err...

FILE: vendor/cloud.google.com/go/internal/version/version.go
  constant Repo (line 29) | Repo = "20171211"
  function Go (line 33) | func Go() string {
  constant develPrefix (line 39) | develPrefix = "devel +"
  function goVer (line 41) | func goVer(s string) string {
  function notSemverRune (line 69) | func notSemverRune(r rune) bool {

FILE: vendor/cloud.google.com/go/storage/acl.go
  type ACLRole (line 27) | type ACLRole
  constant RoleOwner (line 30) | RoleOwner  ACLRole = "OWNER"
  constant RoleReader (line 31) | RoleReader ACLRole = "READER"
  constant RoleWriter (line 32) | RoleWriter ACLRole = "WRITER"
  type ACLEntity (line 43) | type ACLEntity
  constant AllUsers (line 46) | AllUsers              ACLEntity = "allUsers"
  constant AllAuthenticatedUsers (line 47) | AllAuthenticatedUsers ACLEntity = "allAuthenticatedUsers"
  type ACLRule (line 51) | type ACLRule struct
  type ACLHandle (line 57) | type ACLHandle struct
    method Delete (line 66) | func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) error {
    method Set (line 77) | func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role AC...
    method List (line 88) | func (a *ACLHandle) List(ctx context.Context) ([]ACLRule, error) {
    method bucketDefaultList (line 98) | func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule,...
    method bucketDefaultDelete (line 113) | func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity AC...
    method bucketList (line 121) | func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) {
    method bucketSet (line 141) | func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, r...
    method bucketDelete (line 159) | func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity...
    method objectList (line 171) | func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) {
    method objectSet (line 186) | func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, r...
    method objectDelete (line 210) | func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity...
    method configureCall (line 218) | func (a *ACLHandle) configureCall(call interface {
  function toACLRules (line 229) | func toACLRules(items []*raw.ObjectAccessControl) []ACLRule {

FILE: vendor/cloud.google.com/go/storage/bucket.go
  type BucketHandle (line 32) | type BucketHandle struct
    method Create (line 66) | func (b *BucketHandle) Create(ctx context.Context, projectID string, a...
    method Delete (line 85) | func (b *BucketHandle) Delete(ctx context.Context) error {
    method newDeleteCall (line 93) | func (b *BucketHandle) newDeleteCall() (*raw.BucketsDeleteCall, error) {
    method ACL (line 108) | func (b *BucketHandle) ACL() *ACLHandle {
    method DefaultObjectACL (line 115) | func (b *BucketHandle) DefaultObjectACL() *ACLHandle {
    method Object (line 125) | func (b *BucketHandle) Object(name string) *ObjectHandle {
    method Attrs (line 142) | func (b *BucketHandle) Attrs(ctx context.Context) (*BucketAttrs, error) {
    method newGetCall (line 161) | func (b *BucketHandle) newGetCall() (*raw.BucketsGetCall, error) {
    method Update (line 173) | func (b *BucketHandle) Update(ctx context.Context, uattrs BucketAttrsT...
    method newPatchCall (line 186) | func (b *BucketHandle) newPatchCall(uattrs *BucketAttrsToUpdate) (*raw...
    method If (line 480) | func (b *BucketHandle) If(conds BucketConditions) *BucketHandle {
    method UserProject (line 516) | func (b *BucketHandle) UserProject(projectID string) *BucketHandle {
    method Objects (line 619) | func (b *BucketHandle) Objects(ctx context.Context, q *Query) *ObjectI...
  method Bucket (line 48) | func (c *Client) Bucket(name string) *BucketHandle {
  type BucketAttrs (line 201) | type BucketAttrs struct
    method toRawBucket (line 373) | func (b *BucketAttrs) toRawBucket() *raw.Bucket {
  type Lifecycle (line 249) | type Lifecycle struct
  constant rfc3339Date (line 255) | rfc3339Date = "2006-01-02"
  constant DeleteAction (line 259) | DeleteAction = "Delete"
  constant SetStorageClassAction (line 263) | SetStorageClassAction = "SetStorageClass"
  type LifecycleRule (line 270) | type LifecycleRule struct
  type LifecycleAction (line 281) | type LifecycleAction struct
  type Liveness (line 295) | type Liveness
  constant LiveAndArchived (line 299) | LiveAndArchived Liveness = iota
  constant Live (line 301) | Live
  constant Archived (line 303) | Archived
  type LifecycleCondition (line 310) | type LifecycleCondition struct
  function newBucket (line 338) | func newBucket(b *raw.Bucket) *BucketAttrs {
  type BucketAttrsToUpdate (line 417) | type BucketAttrsToUpdate struct
    method SetLabel (line 430) | func (ua *BucketAttrsToUpdate) SetLabel(name, value string) {
    method DeleteLabel (line 439) | func (ua *BucketAttrsToUpdate) DeleteLabel(name string) {
    method toRawBucket (line 446) | func (ua *BucketAttrsToUpdate) toRawBucket() *raw.Bucket {
  type BucketConditions (line 489) | type BucketConditions struct
    method validate (line 501) | func (c *BucketConditions) validate(method string) error {
  function applyBucketConds (line 526) | func applyBucketConds(method string, conds *BucketConditions, call inter...
  function toRawLifecycle (line 547) | func toRawLifecycle(l Lifecycle) *raw.BucketLifecycle {
  function toLifecycle (line 582) | func toLifecycle(rl *raw.BucketLifecycle) Lifecycle {
  type ObjectIterator (line 635) | type ObjectIterator struct
    method PageInfo (line 645) | func (it *ObjectIterator) PageInfo() *iterator.PageInfo { return it.pa...
    method Next (line 654) | func (it *ObjectIterator) Next() (*ObjectAttrs, error) {
    method fetch (line 663) | func (it *ObjectIterator) fetch(pageSize int, pageToken string) (strin...
  method Buckets (line 704) | func (c *Client) Buckets(ctx context.Context, projectID string) *BucketI...
  type BucketIterator (line 718) | type BucketIterator struct
    method Next (line 733) | func (it *BucketIterator) Next() (*BucketAttrs, error) {
    method PageInfo (line 743) | func (it *BucketIterator) PageInfo() *iterator.PageInfo { return it.pa...
    method fetch (line 745) | func (it *BucketIterator) fetch(pageSize int, pageToken string) (strin...

FILE: vendor/cloud.google.com/go/storage/copy.go
  method CopierFrom (line 31) | func (dst *ObjectHandle) CopierFrom(src *ObjectHandle) *Copier {
  type Copier (line 36) | type Copier struct
    method Run (line 66) | func (c *Copier) Run(ctx context.Context) (*ObjectAttrs, error) {
    method callRewrite (line 92) | func (c *Copier) callRewrite(ctx context.Context, rawObj *raw.Object) ...
  method ComposerFrom (line 134) | func (dst *ObjectHandle) ComposerFrom(srcs ...*ObjectHandle) *Composer {
  type Composer (line 141) | type Composer struct
    method Run (line 152) | func (c *Composer) Run(ctx context.Context) (*ObjectAttrs, error) {

FILE: vendor/cloud.google.com/go/storage/go110.go
  function shouldRetry (line 21) | func shouldRetry(err error) bool {

FILE: vendor/cloud.google.com/go/storage/go17.go
  function withContext (line 24) | func withContext(r *http.Request, ctx context.Context) *http.Request {

FILE: vendor/cloud.google.com/go/storage/iam.go
  method IAM (line 25) | func (b *BucketHandle) IAM() *iam.Handle {
  type iamClient (line 33) | type iamClient struct
    method Get (line 38) | func (c *iamClient) Get(ctx context.Context, resource string) (*iampb....
    method Set (line 56) | func (c *iamClient) Set(ctx context.Context, resource string, p *iampb...
    method Test (line 69) | func (c *iamClient) Test(ctx context.Context, resource string, perms [...
  function iamToStoragePolicy (line 87) | func iamToStoragePolicy(ip *iampb.Policy) *raw.Policy {
  function iamToStorageBindings (line 94) | func iamToStorageBindings(ibs []*iampb.Binding) []*raw.PolicyBindings {
  function iamFromStoragePolicy (line 105) | func iamFromStoragePolicy(rp *raw.Policy) *iampb.Policy {
  function iamFromStorageBindings (line 112) | func iamFromStorageBindings(rbs []*raw.PolicyBindings) []*iampb.Binding {

FILE: vendor/cloud.google.com/go/storage/invoke.go
  function runWithRetry (line 25) | func runWithRetry(ctx context.Context, call func() error) error {

FILE: vendor/cloud.google.com/go/storage/not_go110.go
  function shouldRetry (line 26) | func shouldRetry(err error) bool {

FILE: vendor/cloud.google.com/go/storage/not_go17.go
  function withContext (line 23) | func withContext(r *http.Request, _ interface{}) *http.Request {

FILE: vendor/cloud.google.com/go/storage/notifications.go
  type Notification (line 28) | type Notification struct
  constant NoPayload (line 59) | NoPayload = "NONE"
  constant JSONPayload (line 62) | JSONPayload = "JSON_API_V1"
  constant ObjectFinalizeEvent (line 68) | ObjectFinalizeEvent = "OBJECT_FINALIZE"
  constant ObjectMetadataUpdateEvent (line 71) | ObjectMetadataUpdateEvent = "OBJECT_METADATA_UPDATE"
  constant ObjectDeleteEvent (line 74) | ObjectDeleteEvent = "OBJECT_DELETE"
  constant ObjectArchiveEvent (line 78) | ObjectArchiveEvent = "OBJECT_ARCHIVE"
  function toNotification (line 81) | func toNotification(rn *raw.Notification) *Notification {
  function parseNotificationTopic (line 98) | func parseNotificationTopic(nt string) (projectID, topicID string) {
  function toRawNotification (line 106) | func toRawNotification(n *Notification) *raw.Notification {
  method AddNotification (line 121) | func (b *BucketHandle) AddNotification(ctx context.Context, n *Notificat...
  method Notifications (line 145) | func (b *BucketHandle) Notifications(ctx context.Context) (map[string]*N...
  function notificationsToMap (line 163) | func notificationsToMap(rns []*raw.Notification) map[string]*Notification {
  method DeleteNotification (line 172) | func (b *BucketHandle) DeleteNotification(ctx context.Context, id string...

FILE: vendor/cloud.google.com/go/storage/reader.go
  type Reader (line 31) | type Reader struct
    method Close (line 44) | func (r *Reader) Close() error {
    method Read (line 48) | func (r *Reader) Read(p []byte) (int, error) {
    method Size (line 72) | func (r *Reader) Size() int64 {
    method Remain (line 77) | func (r *Reader) Remain() int64 {
    method ContentType (line 82) | func (r *Reader) ContentType() string {
    method ContentEncoding (line 87) | func (r *Reader) ContentEncoding() string {
    method CacheControl (line 92) | func (r *Reader) CacheControl() string {

FILE: vendor/cloud.google.com/go/storage/storage.go
  constant userAgent (line 55) | userAgent = "gcloud-golang-storage/20151204"
  constant ScopeFullControl (line 60) | ScopeFullControl = raw.DevstorageFullControlScope
  constant ScopeReadOnly (line 64) | ScopeReadOnly = raw.DevstorageReadOnlyScope
  constant ScopeReadWrite (line 68) | ScopeReadWrite = raw.DevstorageReadWriteScope
  function setClientHeader (line 73) | func setClientHeader(headers http.Header) {
  type Client (line 81) | type Client struct
    method Close (line 114) | func (c *Client) Close() error {
  function NewClient (line 88) | func NewClient(ctx context.Context, opts ...option.ClientOption) (*Clien...
  type SignedURLOptions (line 123) | type SignedURLOptions struct
  function sanitizeHeaders (line 197) | func sanitizeHeaders(hdrs []string) []string {
  function SignedURL (line 245) | func SignedURL(bucket, name string, opts *SignedURLOptions) (string, err...
  type ObjectHandle (line 317) | type ObjectHandle struct
    method ACL (line 332) | func (o *ObjectHandle) ACL() *ACLHandle {
    method Generation (line 341) | func (o *ObjectHandle) Generation(gen int64) *ObjectHandle {
    method If (line 352) | func (o *ObjectHandle) If(conds Conditions) *ObjectHandle {
    method Key (line 363) | func (o *ObjectHandle) Key(encryptionKey []byte) *ObjectHandle {
    method Attrs (line 371) | func (o *ObjectHandle) Attrs(ctx context.Context) (*ObjectAttrs, error) {
    method Update (line 401) | func (o *ObjectHandle) Update(ctx context.Context, uattrs ObjectAttrsT...
    method Delete (line 503) | func (o *ObjectHandle) Delete(ctx context.Context) error {
    method ReadCompressed (line 529) | func (o *ObjectHandle) ReadCompressed(compressed bool) *ObjectHandle {
    method NewReader (line 540) | func (o *ObjectHandle) NewReader(ctx context.Context) (*Reader, error) {
    method NewRangeReader (line 547) | func (o *ObjectHandle) NewRangeReader(ctx context.Context, offset, len...
    method NewWriter (line 687) | func (o *ObjectHandle) NewWriter(ctx context.Context) *Writer {
    method validate (line 697) | func (o *ObjectHandle) validate() error {
  type ObjectAttrsToUpdate (line 492) | type ObjectAttrsToUpdate struct
  function parseCRC32c (line 658) | func parseCRC32c(res *http.Response) (uint32, bool) {
  function parseKey (line 714) | func parseKey(key []byte) (*rsa.PrivateKey, error) {
  function toRawObjectACL (line 732) | func toRawObjectACL(oldACL []ACLRule) []*raw.ObjectAccessControl {
  type ObjectAttrs (line 764) | type ObjectAttrs struct
    method toRawObject (line 747) | func (o *ObjectAttrs) toRawObject(bucket string) *raw.Object {
  function convertTime (line 868) | func convertTime(t string) time.Time {
  function newObject (line 876) | func newObject(o *raw.Object) *ObjectAttrs {
  function decodeUint32 (line 923) | func decodeUint32(b64 string) (uint32, error) {
  function encodeUint32 (line 935) | func encodeUint32(u uint32) string {
  type Query (line 941) | type Query struct
  type contentTyper (line 963) | type contentTyper struct
    method ContentType (line 968) | func (c *contentTyper) ContentType() string {
  type Conditions (line 979) | type Conditions struct
    method validate (line 1013) | func (c *Conditions) validate(method string) error {
    method isGenerationValid (line 1026) | func (c *Conditions) isGenerationValid() bool {
    method isMetagenerationValid (line 1040) | func (c *Conditions) isMetagenerationValid() bool {
  function applyConds (line 1046) | func applyConds(method string, gen int64, conds *Conditions, call interf...
  function applySourceConds (line 1086) | func applySourceConds(gen int64, conds *Conditions, call *raw.ObjectsRew...
  function setConditionField (line 1116) | func setConditionField(call reflect.Value, name string, value interface{...
  function conditionsQuery (line 1128) | func conditionsQuery(gen int64, conds *Conditions) string {
  type composeSourceObj (line 1165) | type composeSourceObj struct
    method Generation (line 1169) | func (c composeSourceObj) Generation(gen int64) {
    method IfGenerationMatch (line 1173) | func (c composeSourceObj) IfGenerationMatch(gen int64) {
  function setEncryptionHeaders (line 1181) | func setEncryptionHeaders(headers http.Header, key []byte, copySource bo...

FILE: vendor/cloud.google.com/go/storage/writer.go
  type Writer (line 30) | type Writer struct
    method open (line 75) | func (w *Writer) open() error {
    method Write (line 160) | func (w *Writer) Write(p []byte) (n int, err error) {
    method Close (line 175) | func (w *Writer) Close() error {
    method CloseWithError (line 192) | func (w *Writer) CloseWithError(err error) error {
    method Attrs (line 201) | func (w *Writer) Attrs() *ObjectAttrs {

FILE: vendor/github.com/ajstarks/svgo/svg.go
  type SVG (line 35) | type SVG struct
    method print (line 67) | func (svg *SVG) print(a ...interface{}) (n int, errno error) {
    method println (line 71) | func (svg *SVG) println(a ...interface{}) (n int, errno error) {
    method printf (line 75) | func (svg *SVG) printf(format string, a ...interface{}) (n int, errno ...
    method genattr (line 79) | func (svg *SVG) genattr(ns []string) {
    method Start (line 91) | func (svg *SVG) Start(w int, h int, ns ...string) {
    method Startunit (line 98) | func (svg *SVG) Startunit(w int, h int, unit string, ns ...string) {
    method Startpercent (line 105) | func (svg *SVG) Startpercent(w int, h int, ns ...string) {
    method Startview (line 112) | func (svg *SVG) Startview(w, h, minx, miny, vw, vh int) {
    method StartviewUnit (line 116) | func (svg *SVG) StartviewUnit(w, h int, unit string, minx, miny, vw, v...
    method Startraw (line 121) | func (svg *SVG) Startraw(ns ...string) {
    method End (line 127) | func (svg *SVG) End() { svg.println("</svg>") }
    method linkembed (line 134) | func (svg *SVG) linkembed(tag string, scriptype string, data ...string) {
    method Script (line 153) | func (svg *SVG) Script(scriptype string, data ...string) {
    method Style (line 158) | func (svg *SVG) Style(scriptype string, data ...string) {
    method Gstyle (line 164) | func (svg *SVG) Gstyle(s string) { svg.println(group("style", s)) }
    method Gtransform (line 168) | func (svg *SVG) Gtransform(s string) { svg.println(group("transform", ...
    method Translate (line 172) | func (svg *SVG) Translate(x, y int) { svg.Gtransform(translate(x, y)) }
    method Scale (line 176) | func (svg *SVG) Scale(n float64) { svg.Gtransform(scale(n)) }
    method ScaleXY (line 180) | func (svg *SVG) ScaleXY(dx, dy float64) { svg.Gtransform(scaleXY(dx, d...
    method SkewX (line 184) | func (svg *SVG) SkewX(a float64) { svg.Gtransform(skewX(a)) }
    method SkewY (line 188) | func (svg *SVG) SkewY(a float64) { svg.Gtransform(skewY(a)) }
    method SkewXY (line 192) | func (svg *SVG) SkewXY(ax, ay float64) { svg.Gtransform(skewX(ax) + " ...
    method Rotate (line 196) | func (svg *SVG) Rotate(r float64) { svg.Gtransform(rotate(r)) }
    method TranslateRotate (line 199) | func (svg *SVG) TranslateRotate(x, y int, r float64) {
    method RotateTranslate (line 204) | func (svg *SVG) RotateTranslate(x, y int, r float64) {
    method Group (line 209) | func (svg *SVG) Group(s ...string) { svg.printf("<g %s\n", endstyle(s,...
    method Gid (line 212) | func (svg *SVG) Gid(s string) {
    method Gend (line 219) | func (svg *SVG) Gend() { svg.println(`</g>`) }
    method ClipPath (line 222) | func (svg *SVG) ClipPath(s ...string) { svg.printf(`<clipPath %s`, end...
    method ClipEnd (line 225) | func (svg *SVG) ClipEnd() {
    method Def (line 231) | func (svg *SVG) Def() { svg.println(`<defs>`) }
    method DefEnd (line 234) | func (svg *SVG) DefEnd() { svg.println(`</defs>`) }
    method Marker (line 238) | func (svg *SVG) Marker(id string, x, y, width, height int, s ...string) {
    method MarkerEnd (line 244) | func (svg *SVG) MarkerEnd() { svg.println(`</marker>`) }
    method Pattern (line 250) | func (svg *SVG) Pattern(id string, x, y, width, height int, putype str...
    method PatternEnd (line 260) | func (svg *SVG) PatternEnd() { svg.println(`</pattern>`) }
    method Desc (line 264) | func (svg *SVG) Desc(s string) { svg.tt("desc", s) }
    method Title (line 268) | func (svg *SVG) Title(s string) { svg.tt("title", s) }
    method Link (line 272) | func (svg *SVG) Link(href string, title string) {
    method LinkEnd (line 279) | func (svg *SVG) LinkEnd() { svg.println(`</a>`) }
    method Use (line 283) | func (svg *SVG) Use(x int, y int, link string, s ...string) {
    method Mask (line 288) | func (svg *SVG) Mask(id string, x int, y int, w int, h int, s ...strin...
    method MaskEnd (line 293) | func (svg *SVG) MaskEnd() { svg.println(`</mask>`) }
    method Circle (line 299) | func (svg *SVG) Circle(x int, y int, r int, s ...string) {
    method Ellipse (line 305) | func (svg *SVG) Ellipse(x int, y int, w int, h int, s ...string) {
    method Polygon (line 312) | func (svg *SVG) Polygon(x []int, y []int, s ...string) {
    method Rect (line 318) | func (svg *SVG) Rect(x int, y int, w int, h int, s ...string) {
    method CenterRect (line 323) | func (svg *SVG) CenterRect(x int, y int, w int, h int, s ...string) {
    method Roundrect (line 332) | func (svg *SVG) Roundrect(x int, y int, w int, h int, rx int, ry int, ...
    method Square (line 337) | func (svg *SVG) Square(x int, y int, l int, s ...string) {
    method Path (line 344) | func (svg *SVG) Path(d string, s ...string) {
    method Arc (line 355) | func (svg *SVG) Arc(sx int, sy int, ax int, ay int, r int, large bool,...
    method Bezier (line 363) | func (svg *SVG) Bezier(sx int, sy int, cx int, cy int, px int, py int,...
    method Qbez (line 371) | func (svg *SVG) Qbez(sx int, sy int, cx int, cy int, ex int, ey int, s...
    method Qbezier (line 379) | func (svg *SVG) Qbezier(sx int, sy int, cx int, cy int, ex int, ey int...
    method Line (line 388) | func (svg *SVG) Line(x1 int, y1 int, x2 int, y2 int, s ...string) {
    method Polyline (line 394) | func (svg *SVG) Polyline(x []int, y []int, s ...string) {
    method Image (line 401) | func (svg *SVG) Image(x int, y int, w int, h int, link string, s ...st...
    method Text (line 407) | func (svg *SVG) Text(x int, y int, t string, s ...string) {
    method Textpath (line 415) | func (svg *SVG) Textpath(t string, pathid string, s ...string) {
    method Textlines (line 423) | func (svg *SVG) Textlines(x, y int, s []string, size, spacing int, fil...
    method RGB (line 436) | func (svg *SVG) RGB(r int, g int, b int) string {
    method RGBA (line 441) | func (svg *SVG) RGBA(r int, g int, b int, a float64) string {
    method LinearGradient (line 450) | func (svg *SVG) LinearGradient(id string, x1, y1, x2, y2 uint8, sc []O...
    method RadialGradient (line 462) | func (svg *SVG) RadialGradient(id string, cx, cy, r, fx, fy uint8, sc ...
    method stopcolor (line 471) | func (svg *SVG) stopcolor(oc []Offcolor) {
    method Filter (line 484) | func (svg *SVG) Filter(id string, s ...string) {
    method Fend (line 490) | func (svg *SVG) Fend() {
    method FeBlend (line 496) | func (svg *SVG) FeBlend(fs Filterspec, mode string, s ...string) {
    method FeColorMatrix (line 509) | func (svg *SVG) FeColorMatrix(fs Filterspec, values [20]float64, s ......
    method FeColorMatrixHue (line 519) | func (svg *SVG) FeColorMatrixHue(fs Filterspec, value float64, s ...st...
    method FeColorMatrixSaturate (line 529) | func (svg *SVG) FeColorMatrixSaturate(fs Filterspec, value float64, s ...
    method FeColorMatrixLuminence (line 539) | func (svg *SVG) FeColorMatrixLuminence(fs Filterspec, s ...string) {
    method FeComponentTransfer (line 546) | func (svg *SVG) FeComponentTransfer() {
    method FeCompEnd (line 552) | func (svg *SVG) FeCompEnd() {
    method FeComposite (line 558) | func (svg *SVG) FeComposite(fs Filterspec, operator string, k1, k2, k3...
    method FeConvolveMatrix (line 571) | func (svg *SVG) FeConvolveMatrix(fs Filterspec, matrix [9]int, s ...st...
    method FeDiffuseLighting (line 582) | func (svg *SVG) FeDiffuseLighting(fs Filterspec, scale, constant float...
    method FeDiffEnd (line 589) | func (svg *SVG) FeDiffEnd() {
    method FeDisplacementMap (line 595) | func (svg *SVG) FeDisplacementMap(fs Filterspec, scale float64, xchann...
    method FeDistantLight (line 602) | func (svg *SVG) FeDistantLight(fs Filterspec, azimuth, elevation float...
    method FeFlood (line 609) | func (svg *SVG) FeFlood(fs Filterspec, color string, opacity float64, ...
    method FeFuncLinear (line 619) | func (svg *SVG) FeFuncLinear(channel string, slope, intercept float64) {
    method FeFuncGamma (line 626) | func (svg *SVG) FeFuncGamma(channel string, amplitude, exponent, offse...
    method FeFuncTable (line 633) | func (svg *SVG) FeFuncTable(channel string, tv []float64) {
    method FeFuncDiscrete (line 640) | func (svg *SVG) FeFuncDiscrete(channel string, tv []float64) {
    method FeGaussianBlur (line 647) | func (svg *SVG) FeGaussianBlur(fs Filterspec, stdx, stdy float64, s .....
    method FeImage (line 660) | func (svg *SVG) FeImage(href string, result string, s ...string) {
    method FeMerge (line 667) | func (svg *SVG) FeMerge(nodes []string, s ...string) {
    method FeMorphology (line 677) | func (svg *SVG) FeMorphology(fs Filterspec, operator string, xradius, ...
    method FeOffset (line 690) | func (svg *SVG) FeOffset(fs Filterspec, dx, dy int, s ...string) {
    method FePointLight (line 697) | func (svg *SVG) FePointLight(x, y, z float64, s ...string) {
    method FeSpecularLighting (line 705) | func (svg *SVG) FeSpecularLighting(fs Filterspec, scale, constant floa...
    method FeSpecEnd (line 712) | func (svg *SVG) FeSpecEnd() {
    method FeSpotLight (line 718) | func (svg *SVG) FeSpotLight(fs Filterspec, x, y, z, px, py, pz float64...
    method FeTile (line 725) | func (svg *SVG) FeTile(fs Filterspec, in string, s ...string) {
    method FeTurbulence (line 731) | func (svg *SVG) FeTurbulence(fs Filterspec, ftype string, bfx, bfy flo...
    method Blur (line 760) | func (svg *SVG) Blur(p float64) {
    method Brightness (line 765) | func (svg *SVG) Brightness(p float64) {
    method Grayscale (line 782) | func (svg *SVG) Grayscale() {
    method HueRotate (line 787) | func (svg *SVG) HueRotate(a float64) {
    method Invert (line 792) | func (svg *SVG) Invert() {
    method Saturate (line 801) | func (svg *SVG) Saturate(p float64) {
    method Sepia (line 806) | func (svg *SVG) Sepia() {
    method Grid (line 819) | func (svg *SVG) Grid(x int, y int, w int, h int, n int, s ...string) {
    method pp (line 848) | func (svg *SVG) pp(x []int, y []int, tag string) {
    method tt (line 880) | func (svg *SVG) tt(tag string, s string) {
    method poly (line 887) | func (svg *SVG) poly(x []int, y []int, tag string, s ...string) {
    method tablevalues (line 968) | func (svg *SVG) tablevalues(s string, t []float64) {
  type Offcolor (line 40) | type Offcolor struct
  type Filterspec (line 47) | type Filterspec struct
  constant svgtop (line 52) | svgtop = `<?xml version="1.0"?>
  constant svginitfmt (line 55) | svginitfmt = `%s width="%d%s" height="%d%s"`
  constant svgns (line 56) | svgns      = `
  constant vbfmt (line 59) | vbfmt = `viewBox="%d %d %d %d"`
  constant emptyclose (line 61) | emptyclose = "/>\n"
  function New (line 65) | func New(w io.Writer) *SVG { return &SVG{w} }
  function style (line 840) | func style(s string) string {
  function endstyle (line 863) | func endstyle(s []string, endtag string) string {
  function onezero (line 893) | func onezero(flag bool) string {
  function pct (line 901) | func pct(n uint8) uint8 {
  function islink (line 909) | func islink(link string) bool {
  function group (line 915) | func group(tag string, value string) string { return fmt.Sprintf(`<g %s=...
  function scale (line 918) | func scale(n float64) string { return fmt.Sprintf(`scale(%g)`, n) }
  function scaleXY (line 921) | func scaleXY(dx, dy float64) string { return fmt.Sprintf(`scale(%g,%g)`,...
  function skewX (line 924) | func skewX(angle float64) string { return fmt.Sprintf(`skewX(%g)`, angle) }
  function skewY (line 927) | func skewY(angle float64) string { return fmt.Sprintf(`skewY(%g)`, angle) }
  function rotate (line 930) | func rotate(r float64) string { return fmt.Sprintf(`rotate(%g)`, r) }
  function translate (line 933) | func translate(x, y int) string { return fmt.Sprintf(`translate(%d,%d)`,...
  function coord (line 936) | func coord(x int, y int) string { return fmt.Sprintf(`%d,%d`, x, y) }
  function ptag (line 939) | func ptag(x int, y int) string { return fmt.Sprintf(`<path d="M%s`, coor...
  function loc (line 942) | func loc(x int, y int) string { return fmt.Sprintf(`x="%d" y="%d"`, x, y) }
  function href (line 945) | func href(s string) string { return fmt.Sprintf(`xlink:href="%s"`, s) }
  function dim (line 948) | func dim(x int, y int, w int, h int) string {
  function fsattr (line 953) | func fsattr(s Filterspec) string {
  function imgchannel (line 977) | func imgchannel(c string) string {

FILE: vendor/github.com/cheggaaa/pb/format.go
  type Units (line 8) | type Units
  constant U_NO (line 12) | U_NO Units = iota
  constant U_BYTES (line 14) | U_BYTES
  constant U_BYTES_DEC (line 16) | U_BYTES_DEC
  constant U_DURATION (line 18) | U_DURATION
  constant KiB (line 22) | KiB = 1024
  constant MiB (line 23) | MiB = 1048576
  constant GiB (line 24) | GiB = 1073741824
  constant TiB (line 25) | TiB = 1099511627776
  constant KB (line 27) | KB = 1e3
  constant MB (line 28) | MB = 1e6
  constant GB (line 29) | GB = 1e9
  constant TB (line 30) | TB = 1e12
  function Format (line 33) | func Format(i int64) *formatter {
  type formatter (line 37) | type formatter struct
    method To (line 44) | func (f *formatter) To(unit Units) *formatter {
    method Width (line 49) | func (f *formatter) Width(width int) *formatter {
    method PerSec (line 54) | func (f *formatter) PerSec() *formatter {
    method String (line 59) | func (f *formatter) String() (out string) {
  function formatBytes (line 77) | func formatBytes(i int64) (result string) {
  function formatBytesDec (line 94) | func formatBytesDec(i int64) (result string) {
  function formatDuration (line 110) | func formatDuration(n int64) (result string) {

FILE: vendor/github.com/cheggaaa/pb/pb.go
  constant Version (line 16) | Version = "1.0.19"
  constant DEFAULT_REFRESH_RATE (line 20) | DEFAULT_REFRESH_RATE = time.Millisecond * 200
  constant FORMAT (line 21) | FORMAT               = "[=>-]"
  function New (line 33) | func New(total int) *ProgressBar {
  function New64 (line 38) | func New64(total int64) *ProgressBar {
  function StartNew (line 55) | func StartNew(total int) *ProgressBar {
  type Callback (line 65) | type Callback
  type ProgressBar (line 67) | type ProgressBar struct
    method Start (line 113) | func (pb *ProgressBar) Start() *ProgressBar {
    method Increment (line 129) | func (pb *ProgressBar) Increment() int {
    method Get (line 134) | func (pb *ProgressBar) Get() int64 {
    method Set (line 140) | func (pb *ProgressBar) Set(current int) *ProgressBar {
    method Set64 (line 145) | func (pb *ProgressBar) Set64(current int64) *ProgressBar {
    method Add (line 151) | func (pb *ProgressBar) Add(add int) int {
    method Add64 (line 155) | func (pb *ProgressBar) Add64(add int64) int64 {
    method Prefix (line 160) | func (pb *ProgressBar) Prefix(prefix string) *ProgressBar {
    method Postfix (line 166) | func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
    method Format (line 174) | func (pb *ProgressBar) Format(format string) *ProgressBar {
    method SetRefreshRate (line 192) | func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar {
    method SetUnits (line 200) | func (pb *ProgressBar) SetUnits(units Units) *ProgressBar {
    method SetMaxWidth (line 206) | func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar {
    method SetWidth (line 213) | func (pb *ProgressBar) SetWidth(width int) *ProgressBar {
    method Finish (line 220) | func (pb *ProgressBar) Finish() {
    method IsFinished (line 238) | func (pb *ProgressBar) IsFinished() bool {
    method FinishPrint (line 245) | func (pb *ProgressBar) FinishPrint(str string) {
    method Write (line 255) | func (pb *ProgressBar) Write(p []byte) (n int, err error) {
    method Read (line 262) | func (pb *ProgressBar) Read(p []byte) (n int, err error) {
    method NewProxyReader (line 270) | func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader {
    method write (line 274) | func (pb *ProgressBar) write(current int64) {
    method GetWidth (line 417) | func (pb *ProgressBar) GetWidth() int {
    method Update (line 432) | func (pb *ProgressBar) Update() {
    method String (line 453) | func (pb *ProgressBar) String() string {
    method refresher (line 460) | func (pb *ProgressBar) refresher() {
  function GetTerminalWidth (line 413) | func GetTerminalWidth() (int, error) {

FILE: vendor/github.com/cheggaaa/pb/pb_appengine.go
  function terminalWidth (line 9) | func terminalWidth() (int, error) {

FILE: vendor/github.com/cheggaaa/pb/pb_win.go
  type smallRect (line 45) | type smallRect struct
  type coordinates (line 54) | type coordinates struct
  type word (line 58) | type word
  type consoleScreenBufferInfo (line 62) | type consoleScreenBufferInfo struct
  function terminalWidth (line 72) | func terminalWidth() (width int, err error) {
  function getCursorPos (line 81) | func getCursorPos() (pos coordinates, err error) {
  function setCursorPos (line 90) | func setCursorPos(pos coordinates) error {
  function lockEcho (line 105) | func lockEcho() (quit chan int, err error) {
  function unlockEcho (line 130) | func unlockEcho() (err error) {

FILE: vendor/github.com/cheggaaa/pb/pb_x.go
  function init (line 25) | func init() {
  function terminalWidth (line 37) | func terminalWidth() (int, error) {
  function lockEcho (line 51) | func lockEcho() (quit chan int, err error) {
  function unlockEcho (line 79) | func unlockEcho() error {
  function catchTerminate (line 98) | func catchTerminate(quit chan int) {

FILE: vendor/github.com/cheggaaa/pb/pool.go
  function StartPool (line 13) | func StartPool(pbs ...*ProgressBar) (pool *Pool, err error) {
  type Pool (line 22) | type Pool struct
    method Add (line 33) | func (p *Pool) Add(pbs ...*ProgressBar) {
    method start (line 44) | func (p *Pool) start() (err error) {
    method writer (line 55) | func (p *Pool) writer(finish chan int) {
    method Stop (line 74) | func (p *Pool) Stop() error {

FILE: vendor/github.com/cheggaaa/pb/pool_win.go
  method print (line 10) | func (p *Pool) print(first bool) bool {

FILE: vendor/github.com/cheggaaa/pb/pool_x.go
  method print (line 7) | func (p *Pool) print(first bool) bool {

FILE: vendor/github.com/cheggaaa/pb/reader.go
  type Reader (line 8) | type Reader struct
    method Read (line 13) | func (r *Reader) Read(p []byte) (n int, err error) {
    method Close (line 20) | func (r *Reader) Close() (err error) {

FILE: vendor/github.com/cheggaaa/pb/runecount.go
  function escapeAwareRuneCountInString (line 11) | func escapeAwareRuneCountInString(s string) int {

FILE: vendor/github.com/cheggaaa/pb/termios_bsd.go
  constant ioctlReadTermios (line 8) | ioctlReadTermios = syscall.TIOCGETA
  constant ioctlWriteTermios (line 9) | ioctlWriteTermios = syscall.TIOCSETA

FILE: vendor/github.com/cheggaaa/pb/termios_sysv.go
  constant ioctlReadTermios (line 12) | ioctlReadTermios = unix.TCGETS
  constant ioctlWriteTermios (line 13) | ioctlWriteTermios = unix.TCSETS

FILE: vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go
  constant _ (line 38) | _ = proto.ProtoPackageIsVersion2
  type Permission_Type (line 40) | type Permission_Type
    method String (line 59) | func (x Permission_Type) String() string {
    method EnumDescriptor (line 62) | func (Permission_Type) EnumDescriptor() ([]byte, []int) { return fileD...
  constant READ (line 43) | READ      Permission_Type = 0
  constant WRITE (line 44) | WRITE     Permission_Type = 1
  constant READWRITE (line 45) | READWRITE Permission_Type = 2
  type User (line 65) | type User struct
    method Reset (line 71) | func (m *User) Reset()                    { *m = User{} }
    method String (line 72) | func (m *User) String() string            { return proto.CompactTextSt...
    method ProtoMessage (line 73) | func (*User) ProtoMessage()               {}
    method Descriptor (line 74) | func (*User) Descriptor() ([]byte, []int) { return fileDescriptorAuth,...
    method Marshal (line 105) | func (m *User) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 115) | func (m *User) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 230) | func (m *User) Size() (n int) {
    method Unmarshal (line 296) | func (m *User) Unmarshal(dAtA []byte) error {
  type Permission (line 77) | type Permission struct
    method Reset (line 83) | func (m *Permission) Reset()                    { *m = Permission{} }
    method String (line 84) | func (m *Permission) String() string            { return proto.Compact...
    method ProtoMessage (line 85) | func (*Permission) ProtoMessage()               {}
    method Descriptor (line 86) | func (*Permission) Descriptor() ([]byte, []int) { return fileDescripto...
    method Marshal (line 150) | func (m *Permission) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 160) | func (m *Permission) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 250) | func (m *Permission) Size() (n int) {
    method Unmarshal (line 437) | func (m *Permission) Unmarshal(dAtA []byte) error {
  type Role (line 89) | type Role struct
    method Reset (line 94) | func (m *Role) Reset()                    { *m = Role{} }
    method String (line 95) | func (m *Role) String() string            { return proto.CompactTextSt...
    method ProtoMessage (line 96) | func (*Role) ProtoMessage()               {}
    method Descriptor (line 97) | func (*Role) Descriptor() ([]byte, []int) { return fileDescriptorAuth,...
    method Marshal (line 185) | func (m *Role) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 195) | func (m *Role) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 267) | func (m *Role) Size() (n int) {
    method Unmarshal (line 568) | func (m *Role) Unmarshal(dAtA []byte) error {
  function init (line 99) | func init() {
  function encodeVarintAuth (line 221) | func encodeVarintAuth(dAtA []byte, offset int, v uint64) int {
  function sovAuth (line 283) | func sovAuth(x uint64) (n int) {
  function sozAuth (line 293) | func sozAuth(x uint64) (n int) {
  function skipAuth (line 680) | func skipAuth(dAtA []byte) (n int, err error) {
  function init (line 785) | func init() { proto.RegisterFile("auth.proto", fileDescriptorAuth) }

FILE: vendor/github.com/coreos/etcd/auth/jwt.go
  type tokenJWT (line 27) | type tokenJWT struct
    method enable (line 35) | func (t *tokenJWT) enable()                         {}
    method disable (line 36) | func (t *tokenJWT) disable()                        {}
    method invalidateUser (line 37) | func (t *tokenJWT) invalidateUser(string)           {}
    method genTokenPrefix (line 38) | func (t *tokenJWT) genTokenPrefix() (string, error) { return "", nil }
    method info (line 40) | func (t *tokenJWT) info(ctx context.Context, token string, rev uint64)...
    method assign (line 82) | func (t *tokenJWT) assign(ctx context.Context, username string, revisi...
  function prepareOpts (line 120) | func prepareOpts(lg *zap.Logger, opts map[string]string) (jwtSignMethod,...
  function newTokenProviderJWT (line 158) | func newTokenProviderJWT(lg *zap.Logger, opts map[string]string) (*token...

FILE: vendor/github.com/coreos/etcd/auth/nop.go
  type tokenNop (line 21) | type tokenNop struct
    method enable (line 23) | func (t *tokenNop) enable()                         {}
    method disable (line 24) | func (t *tokenNop) disable()                        {}
    method invalidateUser (line 25) | func (t *tokenNop) invalidateUser(string)           {}
    method genTokenPrefix (line 26) | func (t *tokenNop) genTokenPrefix() (string, error) { return "", nil }
    method info (line 27) | func (t *tokenNop) info(ctx context.Context, token string, rev uint64)...
    method assign (line 30) | func (t *tokenNop) assign(ctx context.Context, username string, revisi...
  function newTokenProviderNop (line 33) | func newTokenProviderNop() (*tokenNop, error) {

FILE: vendor/github.com/coreos/etcd/auth/range_perm_cache.go
  function getMergedPerms (line 25) | func getMergedPerms(lg *zap.Logger, tx backend.BatchTx, userName string)...
  function checkKeyInterval (line 74) | func checkKeyInterval(
  function checkKeyPoint (line 99) | func checkKeyPoint(lg *zap.Logger, cachedPerms *unifiedRangePermissions,...
  method isRangeOpPermitted (line 116) | func (as *authStore) isRangeOpPermitted(tx backend.BatchTx, userName str...
  method clearCachedPerm (line 142) | func (as *authStore) clearCachedPerm() {
  method invalidateCachedPerm (line 146) | func (as *authStore) invalidateCachedPerm(userName string) {
  type unifiedRangePermissions (line 150) | type unifiedRangePermissions struct

FILE: vendor/github.com/coreos/etcd/auth/simple_token.go
  constant letters (line 34) | letters                  = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR...
  constant defaultSimpleTokenLength (line 35) | defaultSimpleTokenLength = 16
  type simpleTokenTTLKeeper (line 44) | type simpleTokenTTLKeeper struct
    method stop (line 52) | func (tm *simpleTokenTTLKeeper) stop() {
    method addSimpleToken (line 60) | func (tm *simpleTokenTTLKeeper) addSimpleToken(token string) {
    method resetSimpleToken (line 64) | func (tm *simpleTokenTTLKeeper) resetSimpleToken(token string) {
    method deleteSimpleToken (line 70) | func (tm *simpleTokenTTLKeeper) deleteSimpleToken(token string) {
    method run (line 74) | func (tm *simpleTokenTTLKeeper) run() {
  type tokenSimple (line 98) | type tokenSimple struct
    method genTokenPrefix (line 106) | func (t *tokenSimple) genTokenPrefix() (string, error) {
    method assignSimpleTokenToUser (line 121) | func (t *tokenSimple) assignSimpleTokenToUser(username, token string) {
    method invalidateUser (line 145) | func (t *tokenSimple) invalidateUser(username string) {
    method enable (line 159) | func (t *tokenSimple) enable() {
    method disable (line 184) | func (t *tokenSimple) disable() {
    method info (line 195) | func (t *tokenSimple) info(ctx context.Context, token string, revision...
    method assign (line 208) | func (t *tokenSimple) assign(ctx context.Context, username string, rev...
    method isValidSimpleToken (line 218) | func (t *tokenSimple) isValidSimpleToken(ctx context.Context, token st...
  function newTokenProviderSimple (line 237) | func newTokenProviderSimple(lg *zap.Logger, indexWaiter func(uint64) <-c...

FILE: vendor/github.com/coreos/etcd/auth/store.go
  constant rootUser (line 72) | rootUser = "root"
  constant rootRole (line 73) | rootRole = "root"
  constant tokenTypeSimple (line 75) | tokenTypeSimple = "simple"
  constant tokenTypeJWT (line 76) | tokenTypeJWT    = "jwt"
  constant revBytesLen (line 78) | revBytesLen = 8
  type AuthInfo (line 81) | type AuthInfo struct
  type AuthenticateParamIndex (line 87) | type AuthenticateParamIndex struct
  type AuthenticateParamSimpleTokenPrefix (line 90) | type AuthenticateParamSimpleTokenPrefix struct
  type AuthStore (line 93) | type AuthStore interface
  type TokenProvider (line 186) | type TokenProvider interface
  type authStore (line 196) | type authStore struct
    method AuthEnable (line 211) | func (as *authStore) AuthEnable() error {
    method AuthDisable (line 256) | func (as *authStore) AuthDisable() {
    method Close (line 280) | func (as *authStore) Close() error {
    method Authenticate (line 290) | func (as *authStore) Authenticate(ctx context.Context, username, passw...
    method CheckPassword (line 324) | func (as *authStore) CheckPassword(username, password string) (uint64,...
    method Recover (line 349) | func (as *authStore) Recover(be backend.Backend) {
    method UserAdd (line 370) | func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAd...
    method UserDelete (line 415) | func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.Auth...
    method UserChangePassword (line 453) | func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRe...
    method UserGrantRole (line 504) | func (as *authStore) UserGrantRole(r *pb.AuthUserGrantRoleRequest) (*p...
    method UserGet (line 558) | func (as *authStore) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUserGe...
    method UserList (line 573) | func (as *authStore) UserList(r *pb.AuthUserListRequest) (*pb.AuthUser...
    method UserRevokeRole (line 586) | func (as *authStore) UserRevokeRole(r *pb.AuthUserRevokeRoleRequest) (...
    method RoleGet (line 644) | func (as *authStore) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRoleGe...
    method RoleList (line 659) | func (as *authStore) RoleList(r *pb.AuthRoleListRequest) (*pb.AuthRole...
    method RoleRevokePermission (line 672) | func (as *authStore) RoleRevokePermission(r *pb.AuthRoleRevokePermissi...
    method RoleDelete (line 717) | func (as *authStore) RoleDelete(r *pb.AuthRoleDeleteRequest) (*pb.Auth...
    method RoleAdd (line 770) | func (as *authStore) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAd...
    method authInfoFromToken (line 796) | func (as *authStore) authInfoFromToken(ctx context.Context, token stri...
    method RoleGrantPermission (line 814) | func (as *authStore) RoleGrantPermission(r *pb.AuthRoleGrantPermission...
    method isOpPermitted (line 863) | func (as *authStore) isOpPermitted(userName string, revision uint64, k...
    method IsPutPermitted (line 904) | func (as *authStore) IsPutPermitted(authInfo *AuthInfo, key []byte) er...
    method IsRangePermitted (line 908) | func (as *authStore) IsRangePermitted(authInfo *AuthInfo, key, rangeEn...
    method IsDeleteRangePermitted (line 912) | func (as *authStore) IsDeleteRangePermitted(authInfo *AuthInfo, key, r...
    method IsAdminPermitted (line 916) | func (as *authStore) IsAdminPermitted(authInfo *AuthInfo) error {
    method IsAuthEnabled (line 1057) | func (as *authStore) IsAuthEnabled() bool {
    method commitRevision (line 1126) | func (as *authStore) commitRevision(tx backend.BatchTx) {
    method setRevision (line 1142) | func (as *authStore) setRevision(rev uint64) {
    method Revision (line 1146) | func (as *authStore) Revision() uint64 {
    method AuthInfoFromTLS (line 1150) | func (as *authStore) AuthInfoFromTLS(ctx context.Context) (ai *AuthInf...
    method AuthInfoFromCtx (line 1180) | func (as *authStore) AuthInfoFromCtx(ctx context.Context) (*AuthInfo, ...
    method GenTokenPrefix (line 1209) | func (as *authStore) GenTokenPrefix() (string, error) {
    method WithRoot (line 1289) | func (as *authStore) WithRoot(ctx context.Context) context.Context {
    method HasRole (line 1337) | func (as *authStore) HasRole(user, role string) bool {
    method BcryptCost (line 1364) | func (as *authStore) BcryptCost() int {
  type permSlice (line 800) | type permSlice
    method Len (line 802) | func (perms permSlice) Len() int {
    method Less (line 806) | func (perms permSlice) Less(i, j int) bool {
    method Swap (line 810) | func (perms permSlice) Swap(i, j int) {
  function getUser (line 940) | func getUser(lg *zap.Logger, tx backend.BatchTx, username string) *authp...
  function getAllUsers (line 962) | func getAllUsers(lg *zap.Logger, tx backend.BatchTx) []*authpb.User {
  function putUser (line 984) | func putUser(lg *zap.Logger, tx backend.BatchTx, user *authpb.User) {
  function delUser (line 996) | func delUser(tx backend.BatchTx, username string) {
  function getRole (line 1000) | func getRole(tx backend.BatchTx, rolename string) *authpb.Role {
  function getAllRoles (line 1014) | func getAllRoles(lg *zap.Logger, tx backend.BatchTx) []*authpb.Role {
  function putRole (line 1036) | func putRole(lg *zap.Logger, tx backend.BatchTx, role *authpb.Role) {
  function delRole (line 1053) | func delRole(tx backend.BatchTx, rolename string) {
  function NewAuthStore (line 1064) | func NewAuthStore(lg *zap.Logger, be backend.Backend, tp TokenProvider, ...
  function hasRootRole (line 1120) | func hasRootRole(u *authpb.User) bool {
  function getRevision (line 1133) | func getRevision(tx backend.BatchTx) uint64 {
  function decomposeOpts (line 1213) | func decomposeOpts(lg *zap.Logger, optstr string) (string, map[string]st...
  function NewTokenProvider (line 1251) | func NewTokenProvider(

FILE: vendor/github.com/coreos/etcd/client/auth_role.go
  type Role (line 25) | type Role struct
  type Permissions (line 32) | type Permissions struct
  type rwPermission (line 36) | type rwPermission struct
  type PermissionType (line 41) | type PermissionType
  constant ReadPermission (line 44) | ReadPermission PermissionType = iota
  constant WritePermission (line 45) | WritePermission
  constant ReadWritePermission (line 46) | ReadWritePermission
  function NewAuthRoleAPI (line 51) | func NewAuthRoleAPI(c Client) AuthRoleAPI {
  type AuthRoleAPI (line 57) | type AuthRoleAPI interface
  type httpAuthRoleAPI (line 77) | type httpAuthRoleAPI struct
    method ListRoles (line 112) | func (r *httpAuthRoleAPI) ListRoles(ctx context.Context) ([]string, er...
    method AddRole (line 133) | func (r *httpAuthRoleAPI) AddRole(ctx context.Context, rolename string...
    method RemoveRole (line 144) | func (r *httpAuthRoleAPI) RemoveRole(ctx context.Context, rolename str...
    method addRemoveRole (line 151) | func (r *httpAuthRoleAPI) addRemoveRole(ctx context.Context, req *auth...
    method GetRole (line 167) | func (r *httpAuthRoleAPI) GetRole(ctx context.Context, rolename string...
    method GrantRoleKV (line 188) | func (r *httpAuthRoleAPI) GrantRoleKV(ctx context.Context, rolename st...
    method RevokeRoleKV (line 203) | func (r *httpAuthRoleAPI) RevokeRoleKV(ctx context.Context, rolename s...
    method modRole (line 218) | func (r *httpAuthRoleAPI) modRole(ctx context.Context, req *authRoleAP...
  type authRoleAPIAction (line 81) | type authRoleAPIAction struct
    method HTTPRequest (line 96) | func (l *authRoleAPIAction) HTTPRequest(ep url.URL) *http.Request {
  type authRoleAPIList (line 87) | type authRoleAPIList struct
    method HTTPRequest (line 89) | func (list *authRoleAPIList) HTTPRequest(ep url.URL) *http.Request {
  function buildRWPermission (line 174) | func buildRWPermission(prefixes []string, permType PermissionType) rwPer...

FILE: vendor/github.com/coreos/etcd/client/auth_user.go
  type User (line 30) | type User struct
  type userListEntry (line 39) | type userListEntry struct
  type UserRoles (line 44) | type UserRoles struct
  function v2AuthURL (line 49) | func v2AuthURL(ep url.URL, action string, name string) *url.URL {
  function NewAuthAPI (line 60) | func NewAuthAPI(c Client) AuthAPI {
  type AuthAPI (line 66) | type AuthAPI interface
  type httpAuthAPI (line 74) | type httpAuthAPI struct
    method Enable (line 78) | func (s *httpAuthAPI) Enable(ctx context.Context) error {
    method Disable (line 82) | func (s *httpAuthAPI) Disable(ctx context.Context) error {
    method enableDisable (line 86) | func (s *httpAuthAPI) enableDisable(ctx context.Context, req httpActio...
  type authAPIAction (line 102) | type authAPIAction struct
    method HTTPRequest (line 106) | func (l *authAPIAction) HTTPRequest(ep url.URL) *http.Request {
  type authError (line 112) | type authError struct
    method Error (line 117) | func (e authError) Error() string {
  function NewAuthUserAPI (line 123) | func NewAuthUserAPI(c Client) AuthUserAPI {
  type AuthUserAPI (line 129) | type AuthUserAPI interface
  type httpAuthUserAPI (line 152) | type httpAuthUserAPI struct
    method ListUsers (line 187) | func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, er...
    method AddUser (line 216) | func (u *httpAuthUserAPI) AddUser(ctx context.Context, username string...
    method RemoveUser (line 228) | func (u *httpAuthUserAPI) RemoveUser(ctx context.Context, username str...
    method addRemoveUser (line 235) | func (u *httpAuthUserAPI) addRemoveUser(ctx context.Context, req *auth...
    method GetUser (line 251) | func (u *httpAuthUserAPI) GetUser(ctx context.Context, username string...
    method GrantUser (line 258) | func (u *httpAuthUserAPI) GrantUser(ctx context.Context, username stri...
    method RevokeUser (line 270) | func (u *httpAuthUserAPI) RevokeUser(ctx context.Context, username str...
    method ChangePassword (line 282) | func (u *httpAuthUserAPI) ChangePassword(ctx context.Context, username...
    method modUser (line 294) | func (u *httpAuthUserAPI) modUser(ctx context.Context, req *authUserAP...
  type authUserAPIAction (line 156) | type authUserAPIAction struct
    method HTTPRequest (line 171) | func (l *authUserAPIAction) HTTPRequest(ep url.URL) *http.Request {
  type authUserAPIList (line 162) | type authUserAPIList struct
    method HTTPRequest (line 164) | func (list *authUserAPIList) HTTPRequest(ep url.URL) *http.Request {

FILE: vendor/github.com/coreos/etcd/client/cancelreq.go
  function requestCanceler (line 11) | func requestCanceler(tr CancelableTransport, req *http.Request) func() {

FILE: vendor/github.com/coreos/etcd/client/client.go
  type EndpointSelectionMode (line 58) | type EndpointSelectionMode
  constant EndpointSelectionRandom (line 66) | EndpointSelectionRandom EndpointSelectionMode = iota
  constant EndpointSelectionPrioritizeLeader (line 78) | EndpointSelectionPrioritizeLeader
  type Config (line 81) | type Config struct
    method transport (line 145) | func (cfg *Config) transport() CancelableTransport {
    method checkRedirect (line 152) | func (cfg *Config) checkRedirect() CheckRedirectFunc {
  type CancelableTransport (line 161) | type CancelableTransport interface
  type CheckRedirectFunc (line 166) | type CheckRedirectFunc
  type Client (line 176) | type Client interface
  function New (line 212) | func New(cfg Config) (Client, error) {
  type httpClient (line 230) | type httpClient interface
  function newHTTPClientFactory (line 234) | func newHTTPClientFactory(tr CancelableTransport, cr CheckRedirectFunc, ...
  type credentials (line 247) | type credentials struct
  type httpClientFactory (line 252) | type httpClientFactory
  type httpAction (line 254) | type httpAction interface
  type httpClusterClient (line 258) | type httpClusterClient struct
    method getLeaderEndpoint (line 268) | func (c *httpClusterClient) getLeaderEndpoint(ctx context.Context, eps...
    method parseEndpoints (line 295) | func (c *httpClusterClient) parseEndpoints(eps []string) ([]url.URL, e...
    method SetEndpoints (line 311) | func (c *httpClusterClient) SetEndpoints(eps []string) error {
    method Do (line 332) | func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*...
    method Endpoints (line 404) | func (c *httpClusterClient) Endpoints() []string {
    method Sync (line 416) | func (c *httpClusterClient) Sync(ctx context.Context) error {
    method AutoSync (line 470) | func (c *httpClusterClient) AutoSync(ctx context.Context, interval tim...
    method GetVersion (line 486) | func (c *httpClusterClient) GetVersion(ctx context.Context) (*version....
  type roundTripResponse (line 513) | type roundTripResponse struct
  type simpleHTTPClient (line 518) | type simpleHTTPClient struct
    method Do (line 524) | func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*h...
  type authedAction (line 612) | type authedAction struct
    method HTTPRequest (line 617) | func (a *authedAction) HTTPRequest(url url.URL) *http.Request {
  type redirectFollowingHTTPClient (line 623) | type redirectFollowingHTTPClient struct
    method Do (line 628) | func (r *redirectFollowingHTTPClient) Do(ctx context.Context, act http...
  type redirectedHTTPAction (line 661) | type redirectedHTTPAction struct
    method HTTPRequest (line 666) | func (r *redirectedHTTPAction) HTTPRequest(ep url.URL) *http.Request {
  function shuffleEndpoints (line 672) | func shuffleEndpoints(r *rand.Rand, eps []url.URL) []url.URL {
  function endpointsEqual (line 688) | func endpointsEqual(left, right []url.URL) bool {

FILE: vendor/github.com/coreos/etcd/client/cluster_error.go
  type ClusterError (line 19) | type ClusterError struct
    method Error (line 23) | func (ce *ClusterError) Error() string {
    method Detail (line 31) | func (ce *ClusterError) Detail() string {

FILE: vendor/github.com/coreos/etcd/client/curl.go
  function EnablecURLDebug (line 29) | func EnablecURLDebug() {
  function DisablecURLDebug (line 33) | func DisablecURLDebug() {
  function printcURL (line 41) | func printcURL(req *http.Request) error {

FILE: vendor/github.com/coreos/etcd/client/discover.go
  type Discoverer (line 22) | type Discoverer interface
  type srvDiscover (line 27) | type srvDiscover struct
    method Discover (line 34) | func (d *srvDiscover) Discover(domain string) ([]string, error) {
  function NewSRVDiscover (line 30) | func NewSRVDiscover() Discoverer {

FILE: vendor/github.com/coreos/etcd/client/keys.generated.go
  constant codecSelferCcUTF86628 (line 16) | codecSelferCcUTF86628 = 1
  constant codecSelferCcRAW6628 (line 17) | codecSelferCcRAW6628  = 0
  constant codecSelferValueTypeArray6628 (line 19) | codecSelferValueTypeArray6628  = 10
  constant codecSelferValueTypeMap6628 (line 20) | codecSelferValueTypeMap6628    = 9
  constant codecSelferValueTypeString6628 (line 21) | codecSelferValueTypeString6628 = 6
  constant codecSelferValueTypeInt6628 (line 22) | codecSelferValueTypeInt6628    = 2
  constant codecSelferValueTypeUint6628 (line 23) | codecSelferValueTypeUint6628   = 3
  constant codecSelferValueTypeFloat6628 (line 24) | codecSelferValueTypeFloat6628  = 4
  constant codecSelferBitsize6628 (line 25) | codecSelferBitsize6628         = uint8(32 << (^uint(0) >> 63))
  type codecSelfer6628 (line 32) | type codecSelfer6628 struct
    method encNodes (line 4141) | func (x codecSelfer6628) encNodes(v Nodes, e *codec1978.Encoder) {
    method decNodes (line 4157) | func (x codecSelfer6628) decNodes(v *Nodes, d *codec1978.Decoder) {
  function init (line 34) | func init() {
  method CodecEncodeSelf (line 45) | func (x *Error) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 134) | func (x *Error) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 163) | func (x *Error) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 213) | func (x *Error) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
  method CodecEncodeSelf (line 300) | func (x PrevExistType) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 312) | func (x *PrevExistType) CodecDecodeSelf(d *codec1978.Decoder) {
  method CodecEncodeSelf (line 324) | func (x *WatcherOptions) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 383) | func (x *WatcherOptions) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 412) | func (x *WatcherOptions) codecDecodeSelfFromMap(l int, d *codec1978.Deco...
  method codecDecodeSelfFromArray (line 450) | func (x *WatcherOptions) codecDecodeSelfFromArray(l int, d *codec1978.De...
  method CodecEncodeSelf (line 505) | func (x *CreateInOrderOptions) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 553) | func (x *CreateInOrderOptions) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 582) | func (x *CreateInOrderOptions) codecDecodeSelfFromMap(l int, d *codec197...
  method codecDecodeSelfFromArray (line 619) | func (x *CreateInOrderOptions) codecDecodeSelfFromArray(l int, d *codec1...
  method CodecEncodeSelf (line 663) | func (x *SetOptions) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 795) | func (x *SetOptions) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 824) | func (x *SetOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 897) | func (x *SetOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decode...
  method CodecEncodeSelf (line 1037) | func (x *GetOptions) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 1111) | func (x *GetOptions) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 1140) | func (x *GetOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 1184) | func (x *GetOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decode...
  method CodecEncodeSelf (line 1255) | func (x *DeleteOptions) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 1344) | func (x *DeleteOptions) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 1373) | func (x *DeleteOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decod...
  method codecDecodeSelfFromArray (line 1423) | func (x *DeleteOptions) codecDecodeSelfFromArray(l int, d *codec1978.Dec...
  method CodecEncodeSelf (line 1510) | func (x *Response) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 1618) | func (x *Response) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 1647) | func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 1703) | func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
  method CodecEncodeSelf (line 1786) | func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 1997) | func (x *Node) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 2026) | func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 2109) | func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
  method CodecEncodeSelf (line 2269) | func (x Nodes) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 2285) | func (x *Nodes) CodecDecodeSelf(d *codec1978.Decoder) {
  method CodecEncodeSelf (line 2297) | func (x *httpKeysAPI) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 2326) | func (x *httpKeysAPI) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 2355) | func (x *httpKeysAPI) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 2381) | func (x *httpKeysAPI) codecDecodeSelfFromArray(l int, d *codec1978.Decod...
  method CodecEncodeSelf (line 2404) | func (x *httpWatcher) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 2433) | func (x *httpWatcher) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 2462) | func (x *httpWatcher) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 2488) | func (x *httpWatcher) codecDecodeSelfFromArray(l int, d *codec1978.Decod...
  method CodecEncodeSelf (line 2511) | func (x *getAction) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 2615) | func (x *getAction) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 2644) | func (x *getAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 2700) | func (x *getAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
  method CodecEncodeSelf (line 2803) | func (x *waitAction) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 2892) | func (x *waitAction) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 2921) | func (x *waitAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 2971) | func (x *waitAction) codecDecodeSelfFromArray(l int, d *codec1978.Decode...
  method CodecEncodeSelf (line 3058) | func (x *setAction) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 3235) | func (x *setAction) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 3264) | func (x *setAction) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
  method codecDecodeSelfFromArray (line 3355) | func (x *setAction) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
  method CodecEncodeSelf (line 3543) | func (x *deleteAction) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 3662) | func (x *deleteAction) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 3691) | func (x *deleteAction) codecDecodeSelfFromMap(l int, d *codec1978.Decode...
  method codecDecodeSelfFromArray (line 3753) | func (x *deleteAction) codecDecodeSelfFromArray(l int, d *codec1978.Deco...
  method CodecEncodeSelf (line 3872) | func (x *createInOrderAction) CodecEncodeSelf(e *codec1978.Encoder) {
  method CodecDecodeSelf (line 3965) | func (x *createInOrderAction) CodecDecodeSelf(d *codec1978.Decoder) {
  method codecDecodeSelfFromMap (line 3994) | func (x *createInOrderAction) codecDecodeSelfFromMap(l int, d *codec1978...
  method codecDecodeSelfFromArray (line 4049) | func (x *createInOrderAction) codecDecodeSelfFromArray(l int, d *codec19...

FILE: vendor/github.com/coreos/etcd/client/keys.go
  constant ErrorCodeKeyNotFound (line 35) | ErrorCodeKeyNotFound  = 100
  constant ErrorCodeTestFailed (line 36) | ErrorCodeTestFailed   = 101
  constant ErrorCodeNotFile (line 37) | ErrorCodeNotFile      = 102
  constant ErrorCodeNotDir (line 38) | ErrorCodeNotDir       = 104
  constant ErrorCodeNodeExist (line 39) | ErrorCodeNodeExist    = 105
  constant ErrorCodeRootROnly (line 40) | ErrorCodeRootROnly    = 107
  constant ErrorCodeDirNotEmpty (line 41) | ErrorCodeDirNotEmpty  = 108
  constant ErrorCodeUnauthorized (line 42) | ErrorCodeUnauthorized = 110
  constant ErrorCodePrevValueRequired (line 44) | ErrorCodePrevValueRequired = 201
  constant ErrorCodeTTLNaN (line 45) | ErrorCodeTTLNaN            = 202
  constant ErrorCodeIndexNaN (line 46) | ErrorCodeIndexNaN          = 203
  constant ErrorCodeInvalidField (line 47) | ErrorCodeInvalidField      = 209
  constant ErrorCodeInvalidForm (line 48) | ErrorCodeInvalidForm       = 210
  constant ErrorCodeRaftInternal (line 50) | ErrorCodeRaftInternal = 300
  constant ErrorCodeLeaderElect (line 51) | ErrorCodeLeaderElect  = 301
  constant ErrorCodeWatcherCleared (line 53) | ErrorCodeWatcherCleared    = 400
  constant ErrorCodeEventIndexCleared (line 54) | ErrorCodeEventIndexCleared = 401
  type Error (line 57) | type Error struct
    method Error (line 64) | func (e Error) Error() string {
  type PrevExistType (line 75) | type PrevExistType
  constant PrevIgnore (line 78) | PrevIgnore  = PrevExistType("")
  constant PrevExist (line 79) | PrevExist   = PrevExistType("true")
  constant PrevNoExist (line 80) | PrevNoExist = PrevExistType("false")
  function NewKeysAPI (line 89) | func NewKeysAPI(c Client) KeysAPI {
  function NewKeysAPIWithPrefix (line 96) | func NewKeysAPIWithPrefix(c Client, p string) KeysAPI {
  type KeysAPI (line 103) | type KeysAPI interface
  type WatcherOptions (line 133) | type WatcherOptions struct
  type CreateInOrderOptions (line 150) | type CreateInOrderOptions struct
  type SetOptions (line 158) | type SetOptions struct
  type GetOptions (line 200) | type GetOptions struct
  type DeleteOptions (line 218) | type DeleteOptions struct
  type Watcher (line 244) | type Watcher interface
  type Response (line 258) | type Response struct
  type Node (line 281) | type Node struct
    method String (line 310) | func (n *Node) String() string {
    method TTLDuration (line 315) | func (n *Node) TTLDuration() time.Duration {
  type Nodes (line 319) | type Nodes
    method Len (line 323) | func (ns Nodes) Len() int           { return len(ns) }
    method Less (line 324) | func (ns Nodes) Less(i, j int) bool { return ns[i].Key < ns[j].Key }
    method Swap (line 325) | func (ns Nodes) Swap(i, j int)      { ns[i], ns[j] = ns[j], ns[i] }
  type httpKeysAPI (line 327) | type httpKeysAPI struct
    method Set (line 332) | func (k *httpKeysAPI) Set(ctx context.Context, key, val string, opts *...
    method Create (line 361) | func (k *httpKeysAPI) Create(ctx context.Context, key, val string) (*R...
    method CreateInOrder (line 365) | func (k *httpKeysAPI) CreateInOrder(ctx context.Context, dir, val stri...
    method Update (line 384) | func (k *httpKeysAPI) Update(ctx context.Context, key, val string) (*R...
    method Delete (line 388) | func (k *httpKeysAPI) Delete(ctx context.Context, key string, opts *De...
    method Get (line 410) | func (k *httpKeysAPI) Get(ctx context.Context, key string, opts *GetOp...
    method Watcher (line 430) | func (k *httpKeysAPI) Watcher(key string, opts *WatcherOptions) Watcher {
  type httpWatcher (line 449) | type httpWatcher struct
    method Next (line 454) | func (hw *httpWatcher) Next(ctx context.Context) (*Response, error) {
  function v2KeysURL (line 479) | func v2KeysURL(ep url.URL, prefix, key string) *url.URL {
  type getAction (line 493) | type getAction struct
    method HTTPRequest (line 501) | func (g *getAction) HTTPRequest(ep url.URL) *http.Request {
  type waitAction (line 514) | type waitAction struct
    method HTTPRequest (line 521) | func (w *waitAction) HTTPRequest(ep url.URL) *http.Request {
  type setAction (line 534) | type setAction struct
    method HTTPRequest (line 547) | func (a *setAction) HTTPRequest(ep url.URL) *http.Request {
  type deleteAction (line 591) | type deleteAction struct
    method HTTPRequest (line 600) | func (a *deleteAction) HTTPRequest(ep url.URL) *http.Request {
  type createInOrderAction (line 624) | type createInOrderAction struct
    method HTTPRequest (line 631) | func (a *createInOrderAction) HTTPRequest(ep url.URL) *http.Request {
  function unmarshalHTTPResponse (line 646) | func unmarshalHTTPResponse(code int, header http.Header, body []byte) (r...
  function unmarshalSuccessfulKeysResponse (line 659) | func unmarshalSuccessfulKeysResponse(header http.Header, body []byte) (*...
  function unmarshalFailedKeysResponse (line 675) | func unmarshalFailedKeysResponse(body []byte) error {

FILE: vendor/github.com/coreos/etcd/client/members.go
  type Member (line 34) | type Member struct
  type memberCollection (line 50) | type memberCollection
    method UnmarshalJSON (line 52) | func (c *memberCollection) UnmarshalJSON(data []byte) error {
  type memberCreateOrUpdateRequest (line 70) | type memberCreateOrUpdateRequest struct
    method MarshalJSON (line 74) | func (m *memberCreateOrUpdateRequest) MarshalJSON() ([]byte, error) {
  function NewMembersAPI (line 90) | func NewMembersAPI(c Client) MembersAPI {
  type MembersAPI (line 96) | type MembersAPI interface
  type httpMembersAPI (line 113) | type httpMembersAPI struct
    method List (line 117) | func (m *httpMembersAPI) List(ctx context.Context) ([]Member, error) {
    method Add (line 136) | func (m *httpMembersAPI) Add(ctx context.Context, peerURL string) (*Me...
    method Update (line 168) | func (m *httpMembersAPI) Update(ctx context.Context, memberID string, ...
    method Remove (line 195) | func (m *httpMembersAPI) Remove(ctx context.Context, memberID string) ...
    method Leader (line 205) | func (m *httpMembersAPI) Leader(ctx context.Context) (*Member, error) {
  type membersAPIActionList (line 224) | type membersAPIActionList struct
    method HTTPRequest (line 226) | func (l *membersAPIActionList) HTTPRequest(ep url.URL) *http.Request {
  type membersAPIActionRemove (line 232) | type membersAPIActionRemove struct
    method HTTPRequest (line 236) | func (d *membersAPIActionRemove) HTTPRequest(ep url.URL) *http.Request {
  type membersAPIActionAdd (line 243) | type membersAPIActionAdd struct
    method HTTPRequest (line 247) | func (a *membersAPIActionAdd) HTTPRequest(ep url.URL) *http.Request {
  type membersAPIActionUpdate (line 256) | type membersAPIActionUpdate struct
    method HTTPRequest (line 261) | func (a *membersAPIActionUpdate) HTTPRequest(ep url.URL) *http.Request {
  function assertStatusCode (line 271) | func assertStatusCode(got int, want ...int) (err error) {
  type membersAPIActionLeader (line 280) | type membersAPIActionLeader struct
    method HTTPRequest (line 282) | func (l *membersAPIActionLeader) HTTPRequest(ep url.URL) *http.Request {
  function v2MembersURL (line 291) | func v2MembersURL(ep url.URL) *url.URL {
  type membersError (line 296) | type membersError struct
    method Error (line 301) | func (e membersError) Error() string {

FILE: vendor/github.com/coreos/etcd/client/util.go
  function init (line 26) | func init() {
  function IsKeyNotFound (line 32) | func IsKeyNotFound(err error) bool {
  function IsRoleNotFound (line 40) | func IsRoleNotFound(err error) bool {
  function IsUserNotFound (line 48) | func IsUserNotFound(err error) bool {

FILE: vendor/github.com/coreos/etcd/clientv3/auth.go
  type AuthEnableResponse (line 29) | type AuthEnableResponse
  type AuthDisableResponse (line 30) | type AuthDisableResponse
  type AuthenticateResponse (line 31) | type AuthenticateResponse
  type AuthUserAddResponse (line 32) | type AuthUserAddResponse
  type AuthUserDeleteResponse (line 33) | type AuthUserDeleteResponse
  type AuthUserChangePasswordResponse (line 34) | type AuthUserChangePasswordResponse
  type AuthUserGrantRoleResponse (line 35) | type AuthUserGrantRoleResponse
  type AuthUserGetResponse (line 36) | type AuthUserGetResponse
  type AuthUserRevokeRoleResponse (line 37) | type AuthUserRevokeRoleResponse
  type AuthRoleAddResponse (line 38) | type AuthRoleAddResponse
  type AuthRoleGrantPermissionResponse (line 39) | type AuthRoleGrantPermissionResponse
  type AuthRoleGetResponse (line 40) | type AuthRoleGetResponse
  type AuthRoleRevokePermissionResponse (line 41) | type AuthRoleRevokePermissionResponse
  type AuthRoleDeleteResponse (line 42) | type AuthRoleDeleteResponse
  type AuthUserListResponse (line 43) | type AuthUserListResponse
  type AuthRoleListResponse (line 44) | type AuthRoleListResponse
  type PermissionType (line 46) | type PermissionType
  type Permission (line 47) | type Permission
  constant PermRead (line 51) | PermRead      = authpb.READ
  constant PermWrite (line 52) | PermWrite     = authpb.WRITE
  constant PermReadWrite (line 53) | PermReadWrite = authpb.READWRITE
  type Auth (line 56) | type Auth interface
  type authClient (line 103) | type authClient struct
    method AuthEnable (line 116) | func (auth *authClient) AuthEnable(ctx context.Context) (*AuthEnableRe...
    method AuthDisable (line 121) | func (auth *authClient) AuthDisable(ctx context.Context) (*AuthDisable...
    method UserAdd (line 126) | func (auth *authClient) UserAdd(ctx context.Context, name string, pass...
    method UserDelete (line 131) | func (auth *authClient) UserDelete(ctx context.Context, name string) (...
    method UserChangePassword (line 136) | func (auth *authClient) UserChangePassword(ctx context.Context, name s...
    method UserGrantRole (line 141) | func (auth *authClient) UserGrantRole(ctx context.Context, user string...
    method UserGet (line 146) | func (auth *authClient) UserGet(ctx context.Context, name string) (*Au...
    method UserList (line 151) | func (auth *authClient) UserList(ctx context.Context) (*AuthUserListRe...
    method UserRevokeRole (line 156) | func (auth *authClient) UserRevokeRole(ctx context.Context, name strin...
    method RoleAdd (line 161) | func (auth *authClient) RoleAdd(ctx context.Context, name string) (*Au...
    method RoleGrantPermission (line 166) | func (auth *authClient) RoleGrantPermission(ctx context.Context, name ...
    method RoleGet (line 176) | func (auth *authClient) RoleGet(ctx context.Context, role string) (*Au...
    method RoleList (line 181) | func (auth *authClient) RoleList(ctx context.Context) (*AuthRoleListRe...
    method RoleRevokePermission (line 186) | func (auth *authClient) RoleRevokePermission(ctx context.Context, role...
    method RoleDelete (line 191) | func (auth *authClient) RoleDelete(ctx context.Context, role string) (...
  function NewAuth (line 108) | func NewAuth(c *Client) Auth {
  function StrToPermissionType (line 196) | func StrToPermissionType(s string) (PermissionType, error) {
  type authenticator (line 204) | type authenticator struct
    method authenticate (line 210) | func (auth *authenticator) authenticate(ctx context.Context, name stri...
    method close (line 215) | func (auth *authenticator) close() {
  function newAuthenticator (line 219) | func newAuthenticator(endpoint string, opts []grpc.DialOption, c *Client...

FILE: vendor/github.com/coreos/etcd/clientv3/balancer/grpc1.7-health.go
  constant minHealthRetryDuration (line 37) | minHealthRetryDuration = 3 * time.Second
  constant unknownService (line 38) | unknownService         = "unknown service grpc.health.v1.Health"
  type NotifyMsg (line 46) | type NotifyMsg
  constant NotifyReset (line 49) | NotifyReset NotifyMsg = iota
  constant NotifyNext (line 50) | NotifyNext
  type GRPC17Health (line 55) | type GRPC17Health struct
    method Start (line 148) | func (b *GRPC17Health) Start(target string, config grpc.BalancerConfig...
    method ConnectNotify (line 150) | func (b *GRPC17Health) ConnectNotify() <-chan struct{} {
    method UpdateAddrsC (line 156) | func (b *GRPC17Health) UpdateAddrsC() chan NotifyMsg { return b.update...
    method StopC (line 157) | func (b *GRPC17Health) StopC() chan struct{}         { return b.stopc }
    method Ready (line 159) | func (b *GRPC17Health) Ready() <-chan struct{} { return b.readyc }
    method Endpoint (line 161) | func (b *GRPC17Health) Endpoint(hostPort string) string {
    method Pinned (line 167) | func (b *GRPC17Health) Pinned() string {
    method HostPortError (line 173) | func (b *GRPC17Health) HostPortError(hostPort string, err error) {
    method removeUnhealthy (line 185) | func (b *GRPC17Health) removeUnhealthy(hostPort, msg string) {
    method countUnhealthy (line 197) | func (b *GRPC17Health) countUnhealthy() (count int) {
    method isUnhealthy (line 204) | func (b *GRPC17Health) isUnhealthy(hostPort string) (unhealthy bool) {
    method cleanupUnhealthy (line 211) | func (b *GRPC17Health) cleanupUnhealthy() {
    method liveAddrs (line 222) | func (b *GRPC17Health) liveAddrs() ([]grpc.Address, map[string]struct{...
    method updateUnhealthy (line 248) | func (b *GRPC17Health) updateUnhealthy() {
    method NeedUpdate (line 269) | func (b *GRPC17Health) NeedUpdate() bool {
    method UpdateAddrs (line 279) | func (b *GRPC17Health) UpdateAddrs(eps ...string) {
    method Next (line 307) | func (b *GRPC17Health) Next() {
    method updateNotifyLoop (line 322) | func (b *GRPC17Health) updateNotifyLoop() {
    method notifyAddrs (line 377) | func (b *GRPC17Health) notifyAddrs(msg NotifyMsg) {
    method Up (line 409) | func (b *GRPC17Health) Up(addr grpc.Address) func(error) {
    method mayPin (line 460) | func (b *GRPC17Health) mayPin(addr grpc.Address) bool {
    method Get (line 496) | func (b *GRPC17Health) Get(ctx context.Context, opts grpc.BalancerGetO...
    method Notify (line 544) | func (b *GRPC17Health) Notify() <-chan []grpc.Address { return b.notif...
    method Close (line 546) | func (b *GRPC17Health) Close() error {
  type DialFunc (line 109) | type DialFunc
  function NewGRPC17Health (line 112) | func NewGRPC17Health(
  function grpcHealthCheck (line 582) | func grpcHealthCheck(ep string, dialFunc func(ep string, dopts ...grpc.D...
  function hasAddr (line 603) | func hasAddr(addrs []grpc.Address, targetAddr string) bool {
  function getHost (line 612) | func getHost(ep string) string {
  function eps2addrs (line 620) | func eps2addrs(eps []string) []grpc.Address {
  function getHostPort2ep (line 628) | func getHostPort2ep(eps []string) map[string]string {
  function parseEndpoint (line 637) | func parseEndpoint(endpoint string) (proto string, host string, scheme s...

FILE: vendor/github.com/coreos/etcd/clientv3/client.go
  type Client (line 46) | type Client struct
    method Close (line 103) | func (c *Client) Close() error {
    method Ctx (line 116) | func (c *Client) Ctx() context.Context { return c.ctx }
    method Endpoints (line 119) | func (c *Client) Endpoints() (eps []string) {
    method SetEndpoints (line 127) | func (c *Client) SetEndpoints(eps ...string) {
    method Sync (line 142) | func (c *Client) Sync(ctx context.Context) error {
    method autoSync (line 155) | func (c *Client) autoSync() {
    method processCreds (line 214) | func (c *Client) processCreds(scheme string) (creds *credentials.Trans...
    method dialSetupOpts (line 234) | func (c *Client) dialSetupOpts(endpoint string, dopts ...grpc.DialOpti...
    method Dial (line 288) | func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error) {
    method getToken (line 292) | func (c *Client) getToken(ctx context.Context) error {
    method dial (line 322) | func (c *Client) dial(endpoint string, dopts ...grpc.DialOption) (*grp...
    method checkVersion (line 468) | func (c *Client) checkVersion() (err error) {
    method ActiveConnection (line 509) | func (c *Client) ActiveConnection() *grpc.ClientConn { return c.conn }
  function New (line 76) | func New(cfg Config) (*Client, error) {
  function NewCtxClient (line 87) | func NewCtxClient(ctx context.Context) *Client {
  function NewFromURL (line 93) | func NewFromURL(url string) (*Client, error) {
  function NewFromURLs (line 98) | func NewFromURLs(urls []string) (*Client, error) {
  type authTokenCredential (line 175) | type authTokenCredential struct
    method RequireTransportSecurity (line 180) | func (cred authTokenCredential) RequireTransportSecurity() bool {
    method GetRequestMetadata (line 184) | func (cred authTokenCredential) GetRequestMetadata(ctx context.Context...
  function parseEndpoint (line 192) | func parseEndpoint(endpoint string) (proto string, host string, scheme s...
  function WithRequireLeader (line 361) | func WithRequireLeader(ctx context.Context) context.Context {
  function newClient (line 366) | func newClient(cfg *Config) (*Client, error) {
  function isHaltErr (line 513) | func isHaltErr(ctx context.Context, err error) bool {
  function isUnavailableErr (line 531) | func isUnavailableErr(ctx context.Context, err error) bool {
  function toErr (line 544) | func toErr(ctx context.Context, err error) error {
  function canceledByCaller (line 569) | func canceledByCaller(stopCtx context.Context, err error) bool {
  function getHost (line 577) | func getHost(ep string) string {

FILE: vendor/github.com/coreos/etcd/clientv3/cluster.go
  type Member (line 27) | type Member
  type MemberListResponse (line 28) | type MemberListResponse
  type MemberAddResponse (line 29) | type MemberAddResponse
  type MemberRemoveResponse (line 30) | type MemberRemoveResponse
  type MemberUpdateResponse (line 31) | type MemberUpdateResponse
  type Cluster (line 34) | type Cluster interface
  type cluster (line 48) | type cluster struct
    method MemberAdd (line 69) | func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (...
    method MemberRemove (line 83) | func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*Membe...
    method MemberUpdate (line 92) | func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAdd...
    method MemberList (line 107) | func (c *cluster) MemberList(ctx context.Context) (*MemberListResponse...
  function NewCluster (line 53) | func NewCluster(c *Client) Cluster {
  function NewClusterFromClusterClient (line 61) | func NewClusterFromClusterClient(remote pb.ClusterClient, c *Client) Clu...

FILE: vendor/github.com/coreos/etcd/clientv3/compact_op.go
  type CompactOp (line 22) | type CompactOp struct
    method applyCompactOpts (line 30) | func (op *CompactOp) applyCompactOpts(opts []CompactOption) {
    method toRequest (line 43) | func (op CompactOp) toRequest() *pb.CompactionRequest {
  type CompactOption (line 28) | type CompactOption
  function OpCompact (line 37) | func OpCompact(rev int64, opts ...CompactOption) CompactOp {
  function WithCompactPhysical (line 49) | func WithCompactPhysical() CompactOption {

FILE: vendor/github.com/coreos/etcd/clientv3/compare.go
  type CompareTarget (line 21) | type CompareTarget
  type CompareResult (line 22) | type CompareResult
  constant CompareVersion (line 25) | CompareVersion CompareTarget = iota
  constant CompareCreated (line 26) | CompareCreated
  constant CompareModified (line 27) | CompareModified
  constant CompareValue (line 28) | CompareValue
  type Cmp (line 31) | type Cmp
    method KeyBytes (line 94) | func (cmp *Cmp) KeyBytes() []byte { return cmp.Key }
    method WithKeyBytes (line 97) | func (cmp *Cmp) WithKeyBytes(key []byte) { cmp.Key = key }
    method ValueBytes (line 100) | func (cmp *Cmp) ValueBytes() []byte {
    method WithValueBytes (line 108) | func (cmp *Cmp) WithValueBytes(v []byte) { cmp.TargetUnion.(*pb.Compar...
    method WithRange (line 111) | func (cmp Cmp) WithRange(end string) Cmp {
    method WithPrefix (line 117) | func (cmp Cmp) WithPrefix() Cmp {
  function Compare (line 33) | func Compare(cmp Cmp, result string, v interface{}) Cmp {
  function Value (line 71) | func Value(key string) Cmp {
  function Version (line 75) | func Version(key string) Cmp {
  function CreateRevision (line 79) | func CreateRevision(key string) Cmp {
  function ModRevision (line 83) | func ModRevision(key string) Cmp {
  function LeaseValue (line 89) | func LeaseValue(key string) Cmp {
  function mustInt64 (line 123) | func mustInt64(val interface{}) int64 {
  function mustInt64orLeaseID (line 135) | func mustInt64orLeaseID(val interface{}) int64 {

FILE: vendor/github.com/coreos/etcd/clientv3/config.go
  type Config (line 25) | type Config struct

FILE: vendor/github.com/coreos/etcd/clientv3/kv.go
  type CompactResponse (line 26) | type CompactResponse
  type PutResponse (line 27) | type PutResponse
    method OpResponse (line 79) | func (resp *PutResponse) OpResponse() OpResponse {
  type GetResponse (line 28) | type GetResponse
    method OpResponse (line 82) | func (resp *GetResponse) OpResponse() OpResponse {
  type DeleteResponse (line 29) | type DeleteResponse
    method OpResponse (line 85) | func (resp *DeleteResponse) OpResponse() OpResponse {
  type TxnResponse (line 30) | type TxnResponse
    method OpResponse (line 88) | func (resp *TxnResponse) OpResponse() OpResponse {
  type KV (line 33) | type KV interface
  type OpResponse (line 67) | type OpResponse struct
    method Put (line 74) | func (op OpResponse) Put() *PutResponse    { return op.put }
    method Get (line 75) | func (op OpResponse) Get() *GetResponse    { return op.get }
    method Del (line 76) | func (op OpResponse) Del() *DeleteResponse { return op.del }
    method Txn (line 77) | func (op OpResponse) Txn() *TxnResponse    { return op.txn }
  type kv (line 92) | type kv struct
    method Put (line 113) | func (kv *kv) Put(ctx context.Context, key, val string, opts ...OpOpti...
    method Get (line 118) | func (kv *kv) Get(ctx context.Context, key string, opts ...OpOption) (...
    method Delete (line 123) | func (kv *kv) Delete(ctx context.Context, key string, opts ...OpOption...
    method Compact (line 128) | func (kv *kv) Compact(ctx context.Context, rev int64, opts ...CompactO...
    method Txn (line 136) | func (kv *kv) Txn(ctx context.Context) Txn {
    method Do (line 144) | func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) {
  function NewKV (line 97) | func NewKV(c *Client) KV {
  function NewKVFromKVClient (line 105) | func NewKVFromKVClient(remote pb.KVClient, c *Client) KV {

FILE: vendor/github.com/coreos/etcd/clientv3/lease.go
  type LeaseRevokeResponse (line 30) | type LeaseRevokeResponse
  type LeaseID (line 31) | type LeaseID
  type LeaseGrantResponse (line 35) | type LeaseGrantResponse struct
  type LeaseKeepAliveResponse (line 43) | type LeaseKeepAliveResponse struct
  type LeaseTimeToLiveResponse (line 50) | type LeaseTimeToLiveResponse struct
  type LeaseStatus (line 65) | type LeaseStatus struct
  type LeaseLeasesResponse (line 71) | type LeaseLeasesResponse struct
  constant defaultTTL (line 79) | defaultTTL = 5 * time.Second
  constant leaseResponseChSize (line 81) | leaseResponseChSize = 16
  constant NoLease (line 83) | NoLease LeaseID = 0
  constant retryConnWait (line 86) | retryConnWait = 500 * time.Millisecond
  type ErrKeepAliveHalted (line 92) | type ErrKeepAliveHalted struct
    method Error (line 96) | func (e ErrKeepAliveHalted) Error() string {
  type Lease (line 104) | type Lease interface
  type lessor (line 147) | type lessor struct
    method Grant (line 208) | func (l *lessor) Grant(ctx context.Context, ttl int64) (*LeaseGrantRes...
    method Revoke (line 223) | func (l *lessor) Revoke(ctx context.Context, id LeaseID) (*LeaseRevoke...
    method TimeToLive (line 232) | func (l *lessor) TimeToLive(ctx context.Context, id LeaseID, opts ...L...
    method Leases (line 248) | func (l *lessor) Leases(ctx context.Context) (*LeaseLeasesResponse, er...
    method KeepAlive (line 260) | func (l *lessor) KeepAlive(ctx context.Context, id LeaseID) (<-chan *L...
    method KeepAliveOnce (line 300) | func (l *lessor) KeepAliveOnce(ctx context.Context, id LeaseID) (*Leas...
    method Close (line 315) | func (l *lessor) Close() error {
    method keepAliveCtxCloser (line 323) | func (l *lessor) keepAliveCtxCloser(id LeaseID, ctx context.Context, d...
    method closeRequireLeader (line 357) | func (l *lessor) closeRequireLeader() {
    method keepAliveOnce (line 394) | func (l *lessor) keepAliveOnce(ctx context.Context, id LeaseID) (*Leas...
    method recvKeepAliveLoop (line 421) | func (l *lessor) recvKeepAliveLoop() (gerr error) {
    method resetRecv (line 467) | func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) {
    method recvKeepAlive (line 489) | func (l *lessor) recvKeepAlive(resp *pb.LeaseKeepAliveResponse) {
    method deadlineLoop (line 525) | func (l *lessor) deadlineLoop() {
    method sendKeepAliveLoop (line 546) | func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClien...
  type keepAlive (line 175) | type keepAlive struct
    method close (line 579) | func (ka *keepAlive) close() {
  function NewLease (line 186) | func NewLease(c *Client) Lease {
  function NewLeaseFromLeaseClient (line 190) | func NewLeaseFromLeaseClient(remote pb.LeaseClient, c *Client, keepAlive...

FILE: vendor/github.com/coreos/etcd/clientv3/logger.go
  type settableLogger (line 31) | type settableLogger struct
    method get (line 64) | func (s *settableLogger) get() grpclog.LoggerV2 {
    method Info (line 73) | func (s *settableLogger) Info(args ...interface{})                 { s...
    method Infof (line 74) | func (s *settableLogger) Infof(format string, args ...interface{}) { s...
    method Infoln (line 75) | func (s *settableLogger) Infoln(args ...interface{})               { s...
    method Warning (line 76) | func (s *settableLogger) Warning(args ...interface{})              { s...
    method Warningf (line 77) | func (s *settableLogger) Warningf(format string, args ...interface{}) {
    method Warningln (line 80) | func (s *settableLogger) Warningln(args ...interface{}) { s.get().Warn...
    method Error (line 81) | func (s *settableLogger) Error(args ...interface{})     { s.get().Erro...
    method Errorf (line 82) | func (s *settableLogger) Errorf(format string, args ...interface{}) {
    method Errorln (line 85) | func (s *settableLogger) Errorln(args ...interface{})               { ...
    method Fatal (line 86) | func (s *settableLogger) Fatal(args ...interface{})                 { ...
    method Fatalf (line 87) | func (s *settableLogger) Fatalf(format string, args ...interface{}) { ...
    method Fatalln (line 88) | func (s *settableLogger) Fatalln(args ...interface{})               { ...
    method Print (line 89) | func (s *settableLogger) Print(args ...interface{})                 { ...
    method Printf (line 90) | func (s *settableLogger) Printf(format string, args ...interface{}) { ...
    method Println (line 91) | func (s *settableLogger) Println(args ...interface{})               { ...
    method V (line 92) | func (s *settableLogger) V(l int) bool                              { ...
    method Lvl (line 93) | func (s *settableLogger) Lvl(lvl int) grpclog.LoggerV2 {
  function init (line 36) | func init() {
  function SetLogger (line 43) | func SetLogger(l grpclog.LoggerV2) {
  function GetLogger (line 52) | func GetLogger() logutil.Logger {
  function NewLogger (line 60) | func NewLogger(gl grpclog.LoggerV2) logutil.Logger {

FILE: vendor/github.com/coreos/etcd/clientv3/maintenance.go
  type DefragmentResponse (line 27) | type DefragmentResponse
  type AlarmResponse (line 28) | type AlarmResponse
  type AlarmMember (line 29) | type AlarmMember
  type StatusResponse (line 30) | type StatusResponse
  type HashKVResponse (line 31) | type HashKVResponse
  type MoveLeaderResponse (line 32) | type MoveLeaderResponse
  type Maintenance (line 35) | type Maintenance interface
  type maintenance (line 69) | type maintenance struct
    method AlarmList (line 106) | func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, ...
    method AlarmDisarm (line 119) | func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember...
    method Defragment (line 149) | func (m *maintenance) Defragment(ctx context.Context, endpoint string)...
    method Status (line 162) | func (m *maintenance) Status(ctx context.Context, endpoint string) (*S...
    method HashKV (line 175) | func (m *maintenance) HashKV(ctx context.Context, endpoint string, rev...
    method Snapshot (line 188) | func (m *maintenance) Snapshot(ctx context.Context) (io.ReadCloser, er...
    method MoveLeader (line 225) | func (m *maintenance) MoveLeader(ctx context.Context, transfereeID uin...
  function NewMaintenance (line 75) | func NewMaintenance(c *Client) Maintenance {
  function NewMaintenanceFromMaintenanceClient (line 93) | func NewMaintenanceFromMaintenanceClient(remote pb.MaintenanceClient, c ...
  type snapshotReadCloser (line 215) | type snapshotReadCloser struct
    method Read (line 220) | func (rc *snapshotReadCloser) Read(p []byte) (n int, err error) {

FILE: vendor/github.com/coreos/etcd/clientv3/op.go
  type opType (line 19) | type opType
  constant tRange (line 23) | tRange opType = iota + 1
  constant tPut (line 24) | tPut
  constant tDeleteRange (line 25) | tDeleteRange
  constant tTxn (line 26) | tTxn
  type Op (line 32) | type Op struct
    method IsTxn (line 85) | func (op Op) IsTxn() bool {
    method Txn (line 90) | func (op Op) Txn() ([]Cmp, []Op, []Op) {
    method KeyBytes (line 95) | func (op Op) KeyBytes() []byte { return op.key }
    method WithKeyBytes (line 98) | func (op *Op) WithKeyBytes(key []byte) { op.key = key }
    method RangeBytes (line 101) | func (op Op) RangeBytes() []byte { return op.end }
    method Rev (line 104) | func (op Op) Rev() int64 { return op.rev }
    method IsPut (line 107) | func (op Op) IsPut() bool { return op.t == tPut }
    method IsGet (line 110) | func (op Op) IsGet() bool { return op.t == tRange }
    method IsDelete (line 113) | func (op Op) IsDelete() bool { return op.t == tDeleteRange }
    method IsSerializable (line 116) | func (op Op) IsSerializable() bool { return op.serializable == true }
    method IsKeysOnly (line 119) | func (op Op) IsKeysOnly() bool { return op.keysOnly == true }
    method IsCountOnly (line 122) | func (op Op) IsCountOnly() bool { return op.countOnly == true }
    method MinModRev (line 125) | func (op Op) MinModRev() int64 { return op.minModRev }
    method MaxModRev (line 128) | func (op Op) MaxModRev() int64 { return op.maxModRev }
    method MinCreateRev (line 131) | func (op Op) MinCreateRev() int64 { return op.minCreateRev }
    method MaxCreateRev (line 134) | func (op Op) MaxCreateRev() int64 { return op.maxCreateRev }
    method WithRangeBytes (line 137) | func (op *Op) WithRangeBytes(end []byte) { op.end = end }
    method ValueBytes (line 140) | func (op Op) ValueBytes() []byte { return op.val }
    method WithValueBytes (line 143) | func (op *Op) WithValueBytes(v []byte) { op.val = v }
    method toRangeRequest (line 145) | func (op Op) toRangeRequest() *pb.RangeRequest {
    method toTxnRequest (line 169) | func (op Op) toTxnRequest() *pb.TxnRequest {
    method toRequestOp (line 185) | func (op Op) toRequestOp() *pb.RequestOp {
    method isWrite (line 202) | func (op Op) isWrite() bool {
    method applyOpts (line 311) | func (op *Op) applyOpts(opts []OpOption) {
  function OpGet (line 220) | func OpGet(key string, opts ...OpOption) Op {
  function OpDelete (line 227) | func OpDelete(key string, opts ...OpOption) Op {
  function OpPut (line 256) | func OpPut(key, val string, opts ...OpOption) Op {
  function OpTxn (line 285) | func OpTxn(cmps []Cmp, thenOps []Op, elseOps []Op) Op {
  function opWatch (line 289) | func opWatch(key string, opts ...OpOption) Op {
  type OpOption (line 318) | type OpOption
  function WithLease (line 321) | func WithLease(leaseID LeaseID) OpOption {
  function WithLimit (line 327) | func WithLimit(n int64) OpOption { return func(op *Op) { op.limit = n } }
  function WithRev (line 331) | func WithRev(rev int64) OpOption { return func(op *Op) { op.rev = rev } }
  function WithSort (line 337) | func WithSort(target SortTarget, order SortOrder) OpOption {
  function GetPrefixRangeEnd (line 353) | func GetPrefixRangeEnd(prefix string) string {
  function getPrefix (line 357) | func getPrefix(key []byte) []byte {
  function WithPrefix (line 375) | func WithPrefix() OpOption {
  function WithRange (line 389) | func WithRange(endKey string) OpOption {
  function WithFromKey (line 395) | func WithFromKey() OpOption { return WithRange("\x00") }
  function WithSerializable (line 400) | func WithSerializable() OpOption {
  function WithKeysOnly (line 406) | func WithKeysOnly() OpOption {
  function WithCountOnly (line 411) | func WithCountOnly() OpOption {
  function WithMinModRev (line 416) | func WithMinModRev(rev int64) OpOption { return func(op *Op) { op.minMod...
  function WithMaxModRev (line 419) | func WithMaxModRev(rev int64) OpOption { return func(op *Op) { op.maxMod...
  function WithMinCreateRev (line 422) | func WithMinCreateRev(rev int64) OpOption { return func(op *Op) { op.min...
  function WithMaxCreateRev (line 425) | func WithMaxCreateRev(rev int64) OpOption { return func(op *Op) { op.max...
  function WithFirstCreate (line 428) | func WithFirstCreate() []OpOption { return withTop(SortByCreateRevision,...
  function WithLastCreate (line 431) | func WithLastCreate() []OpOption { return withTop(SortByCreateRevision, ...
  function WithFirstKey (line 434) | func WithFirstKey() []OpOption { return withTop(SortByKey, SortAscend) }
  function WithLastKey (line 437) | func WithLastKey() []OpOption { return withTop(SortByKey, SortDescend) }
  function WithFirstRev (line 440) | func WithFirstRev() []OpOption { return withTop(SortByModRevision, SortA...
  function WithLastRev (line 443) | func WithLastRev() []OpOption { return withTop(SortByModRevision, SortDe...
  function withTop (line 446) | func withTop(target SortTarget, order SortOrder) []OpOption {
  function WithProgressNotify (line 453) | func WithProgressNotify() OpOption {
  function WithCreatedNotify (line 460) | func WithCreatedNotify() OpOption {
  function WithFilterPut (line 467) | func WithFilterPut() OpOption {
  function WithFilterDelete (line 472) | func WithFilterDelete() OpOption {
  function WithPrevKV (line 478) | func WithPrevKV() OpOption {
  function WithFragment (line 491) | func WithFragment() OpOption {
  function WithIgnoreValue (line 498) | func WithIgnoreValue() OpOption {
  function WithIgnoreLease (line 507) | func WithIgnoreLease() OpOption {
  type LeaseOp (line 514) | type LeaseOp struct
    method applyOpts (line 524) | func (op *LeaseOp) applyOpts(opts []LeaseOption) {
  type LeaseOption (line 522) | type LeaseOption
  function WithAttachedKeys (line 531) | func WithAttachedKeys() LeaseOption {
  function toLeaseTimeToLiveRequest (line 535) | func toLeaseTimeToLiveRequest(id LeaseID, opts ...LeaseOption) *pb.Lease...

FILE: vendor/github.com/coreos/etcd/clientv3/options.go
  constant MaxLeaseTTL (line 49) | MaxLeaseTTL = 9000000000

FILE: vendor/github.com/coreos/etcd/clientv3/ready_wait.go
  function readyWait (line 21) | func readyWait(rpcCtx, clientCtx context.Context, ready <-chan struct{})...

FILE: vendor/github.com/coreos/etcd/clientv3/retry.go
  type retryPolicy (line 28) | type retryPolicy
  constant repeatable (line 31) | repeatable retryPolicy = iota
  constant nonRepeatable (line 32) | nonRepeatable
  type rpcFunc (line 35) | type rpcFunc
  type retryRPCFunc (line 36) | type retryRPCFunc
  type retryStopErrFunc (line 37) | type retryStopErrFunc
  function isRepeatableStopError (line 48) | func isRepeatableStopError(err error) bool {
  function isNonRepeatableStopError (line 73) | func isNonRepeatableStopError(err error) bool {
  method newRetryWrapper (line 81) | func (c *Client) newRetryWrapper() retryRPCFunc {
  method newAuthRetryWrapper (line 115) | func (c *Client) newAuthRetryWrapper(retryf retryRPCFunc) retryRPCFunc {
  type retryKVClient (line 138) | type retryKVClient struct
    method Range (line 150) | func (rkv *retryKVClient) Range(ctx context.Context, in *pb.RangeReque...
    method Put (line 158) | func (rkv *retryKVClient) Put(ctx context.Context, in *pb.PutRequest, ...
    method DeleteRange (line 166) | func (rkv *retryKVClient) DeleteRange(ctx context.Context, in *pb.Dele...
    method Txn (line 174) | func (rkv *retryKVClient) Txn(ctx context.Context, in *pb.TxnRequest, ...
    method Compact (line 183) | func (rkv *retryKVClient) Compact(ctx context.Context, in *pb.Compacti...
  function RetryKVClient (line 144) | func RetryKVClient(c *Client) pb.KVClient {
  type retryLeaseClient (line 191) | type retryLeaseClient struct
    method LeaseTimeToLive (line 204) | func (rlc *retryLeaseClient) LeaseTimeToLive(ctx context.Context, in *...
    method LeaseLeases (line 212) | func (rlc *retryLeaseClient) LeaseLeases(ctx context.Context, in *pb.L...
    method LeaseGrant (line 220) | func (rlc *retryLeaseClient) LeaseGrant(ctx context.Context, in *pb.Le...
    method LeaseRevoke (line 229) | func (rlc *retryLeaseClient) LeaseRevoke(ctx context.Context, in *pb.L...
    method LeaseKeepAlive (line 237) | func (rlc *retryLeaseClient) LeaseKeepAlive(ctx context.Context, opts ...
  function RetryLeaseClient (line 197) | func RetryLeaseClient(c *Client) pb.LeaseClient {
  type retryClusterClient (line 245) | type retryClusterClient struct
    method MemberList (line 258) | func (rcc *retryClusterClient) MemberList(ctx context.Context, in *pb....
    method MemberAdd (line 266) | func (rcc *retryClusterClient) MemberAdd(ctx context.Context, in *pb.M...
    method MemberRemove (line 274) | func (rcc *retryClusterClient) MemberRemove(ctx context.Context, in *p...
    method MemberUpdate (line 282) | func (rcc *retryClusterClient) MemberUpdate(ctx context.Context, in *p...
  function RetryClusterClient (line 251) | func RetryClusterClient(c *Client) pb.ClusterClient {
  type retryMaintenanceClient (line 290) | type retryMaintenanceClient struct
    method Alarm (line 303) | func (rmc *retryMaintenanceClient) Alarm(ctx context.Context, in *pb.A...
    method Status (line 311) | func (rmc *retryMaintenanceClient) Status(ctx context.Context, in *pb....
    method Hash (line 319) | func (rmc *retryMaintenanceClient) Hash(ctx context.Context, in *pb.Ha...
    method HashKV (line 327) | func (rmc *retryMaintenanceClient) HashKV(ctx context.Context, in *pb....
    method Snapshot (line 335) | func (rmc *retryMaintenanceClient) Snapshot(ctx context.Context, in *p...
    method MoveLeader (line 343) | func (rmc *retryMaintenanceClient) MoveLeader(ctx context.Context, in ...
    method Defragment (line 351) | func (rmc *retryMaintenanceClient) Defragment(ctx context.Context, in ...
  function RetryMaintenanceClient (line 296) | func RetryMaintenanceClient(c *Client, conn *grpc.ClientConn) pb.Mainten...
  type retryAuthClient (line 359) | type retryAuthClient struct
    method UserList (line 372) | func (rac *retryAuthClient) UserList(ctx context.Context, in *pb.AuthU...
    method UserGet (line 380) | func (rac *retryAuthClient) UserGet(ctx context.Context, in *pb.AuthUs...
    method RoleGet (line 388) | func (rac *retryAuthClient) RoleGet(ctx context.Context, in *pb.AuthRo...
    method RoleList (line 396) | func (rac *retryAuthClient) RoleList(ctx context.Context, in *pb.AuthR...
    method AuthEnable (line 404) | func (rac *retryAuthClient) AuthEnable(ctx context.Context, in *pb.Aut...
    method AuthDisable (line 412) | func (rac *retryAuthClient) AuthDisable(ctx context.Context, in *pb.Au...
    method UserAdd (line 420) | func (rac *retryAuthClient) UserAdd(ctx context.Context, in *pb.AuthUs...
    method UserDelete (line 428) | func (rac *retryAuthClient) UserDelete(ctx context.Context, in *pb.Aut...
    method UserChangePassword (line 436) | func (rac *retryAuthClient) UserChangePassword(ctx context.Context, in...
    method UserGrantRole (line 444) | func (rac *retryAuthClient) UserGrantRole(ctx context.Context, in *pb....
    method UserRevokeRole (line 452) | func (rac *retryAuthClient) UserRevokeRole(ctx context.Context, in *pb...
    method RoleAdd (line 460) | func (rac *retryAuthClient) RoleAdd(ctx context.Context, in *pb.AuthRo...
    method RoleDelete (line 468) | func (rac *retryAuthClient) RoleDelete(ctx context.Context, in *pb.Aut...
    method RoleGrantPermission (line 476) | func (rac *retryAuthClient) RoleGrantPermission(ctx context.Context, i...
    method RoleRevokePermission (line 484) | func (rac *retryAuthClient) RoleRevokePermission(ctx context.Context, ...
    method Authenticate (line 492) | func (rac *retryAuthClient) Authenticate(ctx context.Context, in *pb.A...
  function RetryAuthClient (line 365) | func RetryAuthClient(c *Client) pb.AuthClient {

FILE: vendor/github.com/coreos/etcd/clientv3/sort.go
  type SortTarget (line 17) | type SortTarget
  type SortOrder (line 18) | type SortOrder
  constant SortNone (line 21) | SortNone SortOrder = iota
  constant SortAscend (line 22) | SortAscend
  constant SortDescend (line 23) | SortDescend
  constant SortByKey (line 27) | SortByKey SortTarget = iota
  constant SortByVersion (line 28) | SortByVersion
  constant SortByCreateRevision (line 29) | SortByCreateRevision
  constant SortByModRevision (line 30) | SortByModRevision
  constant SortByValue (line 31) | SortByValue
  type SortOption (line 34) | type SortOption struct

FILE: vendor/github.com/coreos/etcd/clientv3/txn.go
  type Txn (line 37) | type Txn interface
  type txn (line 55) | type txn struct
    method If (line 74) | func (txn *txn) If(cs ...Cmp) Txn {
    method Then (line 99) | func (txn *txn) Then(ops ...Op) Txn {
    method Else (line 120) | func (txn *txn) Else(ops ...Op) Txn {
    method Commit (line 138) | func (txn *txn) Commit() (*TxnResponse, error) {

FILE: vendor/github.com/coreos/etcd/clientv3/watch.go
  constant EventTypeDelete (line 34) | EventTypeDelete = mvccpb.DELETE
  constant EventTypePut (line 35) | EventTypePut    = mvccpb.PUT
  constant closeSendErrTimeout (line 37) | closeSendErrTimeout = 250 * time.Millisecond
  type Event (line 40) | type Event
    method IsCreate (line 93) | func (e *Event) IsCreate() bool {
    method IsModify (line 98) | func (e *Event) IsModify() bool {
  type WatchChan (line 42) | type WatchChan
  type Watcher (line 44) | type Watcher interface
  type WatchResponse (line 71) | type WatchResponse struct
    method Err (line 103) | func (wr *WatchResponse) Err() error {
    method IsProgressNotify (line 119) | func (wr *WatchResponse) IsProgressNotify() bool {
  type watcher (line 124) | type watcher struct
    method newWatcherGrpcStream (line 241) | func (w *watcher) newWatcherGrpcStream(inctx context.Context) *watchGr...
    method Watch (line 263) | func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOpt...
    method Close (line 345) | func (w *watcher) Close() (err error) {
    method closeStream (line 368) | func (w *watcher) closeStream(wgs *watchGrpcStream) {
  type watchGrpcStream (line 136) | type watchGrpcStream struct
    method close (line 358) | func (w *watchGrpcStream) close() (err error) {
    method addSubstream (line 378) | func (w *watchGrpcStream) addSubstream(resp *pb.WatchResponse, ws *wat...
    method sendCloseSubstream (line 389) | func (w *watchGrpcStream) sendCloseSubstream(ws *watcherStream, resp *...
    method closeSubstream (line 398) | func (w *watchGrpcStream) closeSubstream(ws *watcherStream) {
    method run (line 423) | func (w *watchGrpcStream) run() {
    method nextResume (line 586) | func (w *watchGrpcStream) nextResume() *watcherStream {
    method dispatchEvent (line 597) | func (w *watchGrpcStream) dispatchEvent(pbresp *pb.WatchResponse) bool {
    method serveWatchClient (line 624) | func (w *watchGrpcStream) serveWatchClient(wc pb.Watch_WatchClient) {
    method serveSubstream (line 643) | func (w *watchGrpcStream) serveSubstream(ws *watcherStream, resumec ch...
    method newWatchClient (line 739) | func (w *watchGrpcStream) newWatchClient() (pb.Watch_WatchClient, erro...
    method waitCancelSubstreams (line 785) | func (w *watchGrpcStream) waitCancelSubstreams(stopc <-chan struct{}) ...
    method joinSubstreams (line 822) | func (w *watchGrpcStream) joinSubstreams() {
    method openWatchClient (line 838) | func (w *watchGrpcStream) openWatchClient() (ws pb.Watch_WatchClient, ...
  type watchRequest (line 172) | type watchRequest struct
    method toPB (line 871) | func (wr *watchRequest) toPB() *pb.WatchRequest {
  type watcherStream (line 196) | type watcherStream struct
  function NewWatcher (line 215) | func NewWatcher(c *Client) Watcher {
  function NewWatchFromWatchClient (line 219) | func NewWatchFromWatchClient(wc pb.WatchClient, c *Client) Watcher {
  type valCtx (line 235) | type valCtx struct
    method Deadline (line 237) | func (vc *valCtx) Deadline() (time.Time, bool) { return zeroTime, false }
    method Done (line 238) | func (vc *valCtx) Done() <-chan struct{}       { return valCtxCh }
    method Err (line 239) | func (vc *valCtx) Err() error                  { return nil }
  function streamKeyFromCtx (line 885) | func streamKeyFromCtx(ctx context.Context) string {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/capability.go
  type Capability (line 27) | type Capability
  constant AuthCapability (line 30) | AuthCapability  Capability = "auth"
  constant V3rpcCapability (line 31) | V3rpcCapability Capability = "v3rpc"
  function init (line 52) | func init() {
  function UpdateCapability (line 60) | func UpdateCapability(lg *zap.Logger, v *semver.Version) {
  function IsCapabilityEnabled (line 84) | func IsCapabilityEnabled(c Capability) bool {
  function EnableCapability (line 93) | func EnableCapability(c Capability) {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/cluster.go
  type Cluster (line 25) | type Cluster interface

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go
  type AuthServer (line 24) | type AuthServer struct
    method AuthEnable (line 32) | func (as *AuthServer) AuthEnable(ctx context.Context, r *pb.AuthEnable...
    method AuthDisable (line 40) | func (as *AuthServer) AuthDisable(ctx context.Context, r *pb.AuthDisab...
    method Authenticate (line 48) | func (as *AuthServer) Authenticate(ctx context.Context, r *pb.Authenti...
    method RoleAdd (line 56) | func (as *AuthServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRe...
    method RoleDelete (line 64) | func (as *AuthServer) RoleDelete(ctx context.Context, r *pb.AuthRoleDe...
    method RoleGet (line 72) | func (as *AuthServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRe...
    method RoleList (line 80) | func (as *AuthServer) RoleList(ctx context.Context, r *pb.AuthRoleList...
    method RoleRevokePermission (line 88) | func (as *AuthServer) RoleRevokePermission(ctx context.Context, r *pb....
    method RoleGrantPermission (line 96) | func (as *AuthServer) RoleGrantPermission(ctx context.Context, r *pb.A...
    method UserAdd (line 104) | func (as *AuthServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRe...
    method UserDelete (line 112) | func (as *AuthServer) UserDelete(ctx context.Context, r *pb.AuthUserDe...
    method UserGet (line 120) | func (as *AuthServer) UserGet(ctx context.Context, r *pb.AuthUserGetRe...
    method UserList (line 128) | func (as *AuthServer) UserList(ctx context.Context, r *pb.AuthUserList...
    method UserGrantRole (line 136) | func (as *AuthServer) UserGrantRole(ctx context.Context, r *pb.AuthUse...
    method UserRevokeRole (line 144) | func (as *AuthServer) UserRevokeRole(ctx context.Context, r *pb.AuthUs...
    method UserChangePassword (line 152) | func (as *AuthServer) UserChangePassword(ctx context.Context, r *pb.Au...
  function NewAuthServer (line 28) | func NewAuthServer(s *etcdserver.EtcdServer) *AuthServer {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/codec.go
  type codec (line 19) | type codec struct
    method Marshal (line 21) | func (c *codec) Marshal(v interface{}) ([]byte, error) {
    method Unmarshal (line 27) | func (c *codec) Unmarshal(data []byte, v interface{}) error {
    method String (line 32) | func (c *codec) String() string {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go
  constant grpcOverheadBytes (line 36) | grpcOverheadBytes = 512 * 1024
  constant maxStreams (line 37) | maxStreams        = math.MaxUint32
  constant maxSendBytes (line 38) | maxSendBytes      = math.MaxInt32
  function Server (line 44) | func Server(s *etcdserver.EtcdServer, tls *tls.Config, gopts ...grpc.Ser...

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go
  type header (line 22) | type header struct
    method fill (line 39) | func (h *header) fill(rh *pb.ResponseHeader) {
  function newHeader (line 29) | func newHeader(s *etcdserver.EtcdServer) header {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/interceptor.go
  constant maxNoLeaderCnt (line 34) | maxNoLeaderCnt = 3
  type streamsMap (line 37) | type streamsMap struct
  function newUnaryInterceptor (line 42) | func newUnaryInterceptor(s *etcdserver.EtcdServer) grpc.UnaryServerInter...
  function newStreamInterceptor (line 61) | func newStreamInterceptor(s *etcdserver.EtcdServer) grpc.StreamServerInt...
  type serverStreamWithCtx (line 97) | type serverStreamWithCtx struct
    method Context (line 103) | func (ssc serverStreamWithCtx) Context() context.Context { return ssc....
  function monitorLeader (line 105) | func monitorLeader(s *etcdserver.EtcdServer) *streamsMap {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go
  type kvServer (line 33) | type kvServer struct
    method Range (line 47) | func (s *kvServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb...
    method Put (line 61) | func (s *kvServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.Put...
    method DeleteRange (line 75) | func (s *kvServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeR...
    method Txn (line 89) | func (s *kvServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.Txn...
    method Compact (line 110) | func (s *kvServer) Compact(ctx context.Context, r *pb.CompactionReques...
  function NewKVServer (line 43) | func NewKVServer(s *etcdserver.EtcdServer) pb.KVServer {
  function checkRangeRequest (line 120) | func checkRangeRequest(r *pb.RangeRequest) error {
  function checkPutRequest (line 127) | func checkPutRequest(r *pb.PutRequest) error {
  function checkDeleteRequest (line 140) | func checkDeleteRequest(r *pb.DeleteRangeRequest) error {
  function checkTxnRequest (line 147) | func checkTxnRequest(r *pb.TxnRequest, maxTxnOps int) error {
  function checkIntervals (line 181) | func checkIntervals(reqs []*pb.RequestOp) (map[string]struct{}, adt.Inte...
  function checkRequestOp (line 262) | func checkRequestOp(u *pb.RequestOp, maxTxnOps int) error {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go
  type LeaseServer (line 29) | type LeaseServer struct
    method LeaseGrant (line 39) | func (ls *LeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGra...
    method LeaseRevoke (line 49) | func (ls *LeaseServer) LeaseRevoke(ctx context.Context, rr *pb.LeaseRe...
    method LeaseTimeToLive (line 58) | func (ls *LeaseServer) LeaseTimeToLive(ctx context.Context, rr *pb.Lea...
    method LeaseLeases (line 74) | func (ls *LeaseServer) LeaseLeases(ctx context.Context, rr *pb.LeaseLe...
    method LeaseKeepAlive (line 89) | func (ls *LeaseServer) LeaseKeepAlive(stream pb.Lease_LeaseKeepAliveSe...
    method leaseKeepAlive (line 106) | func (ls *LeaseServer) leaseKeepAlive(stream pb.Lease_LeaseKeepAliveSe...
  function NewLeaseServer (line 35) | func NewLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go
  type KVGetter (line 34) | type KVGetter interface
  type BackendGetter (line 38) | type BackendGetter interface
  type Alarmer (line 42) | type Alarmer interface
  type LeaderTransferrer (line 49) | type LeaderTransferrer interface
  type AuthGetter (line 53) | type AuthGetter interface
  type maintenanceServer (line 58) | type maintenanceServer struct
    method Defragment (line 73) | func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.De...
    method Snapshot (line 96) | func (ms *maintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.M...
    method Hash (line 145) | func (ms *maintenanceServer) Hash(ctx context.Context, r *pb.HashReque...
    method HashKV (line 155) | func (ms *maintenanceServer) HashKV(ctx context.Context, r *pb.HashKVR...
    method Alarm (line 166) | func (ms *maintenanceServer) Alarm(ctx context.Context, ar *pb.AlarmRe...
    method Status (line 170) | func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.Status...
    method MoveLeader (line 192) | func (ms *maintenanceServer) MoveLeader(ctx context.Context, tr *pb.Mo...
  function NewMaintenanceServer (line 68) | func NewMaintenanceServer(s *etcdserver.EtcdServer) pb.MaintenanceServer {
  type authMaintenanceServer (line 203) | type authMaintenanceServer struct
    method isAuthenticated (line 208) | func (ams *authMaintenanceServer) isAuthenticated(ctx context.Context)...
    method Defragment (line 217) | func (ams *authMaintenanceServer) Defragment(ctx context.Context, sr *...
    method Snapshot (line 225) | func (ams *authMaintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv...
    method Hash (line 233) | func (ams *authMaintenanceServer) Hash(ctx context.Context, r *pb.Hash...
    method HashKV (line 241) | func (ams *authMaintenanceServer) HashKV(ctx context.Context, r *pb.Ha...
    method Status (line 248) | func (ams *authMaintenanceServer) Status(ctx context.Context, ar *pb.S...
    method MoveLeader (line 252) | func (ams *authMaintenanceServer) MoveLeader(ctx context.Context, tr *...

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go
  type ClusterServer (line 29) | type ClusterServer struct
    method MemberAdd (line 41) | func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAd...
    method MemberRemove (line 61) | func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.Membe...
    method MemberUpdate (line 69) | func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.Membe...
    method MemberList (line 81) | func (cs *ClusterServer) MemberList(ctx context.Context, r *pb.MemberL...
    method header (line 86) | func (cs *ClusterServer) header() *pb.ResponseHeader {
  function NewClusterServer (line 34) | func NewClusterServer(s etcdserver.ServerV3) *ClusterServer {
  function membersToProtoMembers (line 90) | func membersToProtoMembers(membs []*membership.Member) []*pb.Member {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/metrics.go
  function init (line 44) | func init() {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go
  type quotaKVServer (line 26) | type quotaKVServer struct
    method Put (line 59) | func (s *quotaKVServer) Put(ctx context.Context, r *pb.PutRequest) (*p...
    method Txn (line 66) | func (s *quotaKVServer) Txn(ctx context.Context, r *pb.TxnRequest) (*p...
  type quotaAlarmer (line 31) | type quotaAlarmer struct
    method check (line 39) | func (qa *quotaAlarmer) check(ctx context.Context, r interface{}) error {
  function NewQuotaKVServer (line 52) | func NewQuotaKVServer(s *etcdserver.EtcdServer) pb.KVServer {
  type quotaLeaseServer (line 73) | type quotaLeaseServer struct
    method LeaseGrant (line 78) | func (s *quotaLeaseServer) LeaseGrant(ctx context.Context, cr *pb.Leas...
  function NewQuotaLeaseServer (line 85) | func NewQuotaLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go
  type EtcdError (line 177) | type EtcdError struct
    method Code (line 184) | func (e EtcdError) Code() codes.Code {
    method Error (line 188) | func (e EtcdError) Error() string {
  function Error (line 192) | func Error(err error) error {
  function ErrorDesc (line 210) | func ErrorDesc(err error) string {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go
  function togRPCError (line 75) | func togRPCError(err error) error {
  function isClientCtxErr (line 87) | func isClientCtxErr(ctxErr error, err error) bool {

FILE: vendor/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go
  type watchServer (line 34) | type watchServer struct
    method Watch (line 136) | func (ws *watchServer) Watch(stream pb.Watch_WatchServer) (err error) {
  function NewWatchServer (line 48) | func NewWatchServer(s *etcdserver.EtcdServer) pb.WatchServer {
  function GetProgressReportInterval (line 72) | func GetProgressReportInterval() time.Duration {
  function SetProgressReportInterval (line 86) | func SetProgressReportInterval(newTimeout time.Duration) {
  constant ctrlStreamBufLen (line 97) | ctrlStreamBufLen = 16
  type serverWatchStream (line 103) | type serverWatchStream struct
    method isWatchPermitted (line 208) | func (sws *serverWatchStream) isWatchPermitted(wcr *pb.WatchCreateRequ...
    method recvLoop (line 220) | func (sws *serverWatchStream) recvLoop() error {
    method sendLoop (line 330) | func (sws *serverWatchStream) sendLoop() {
    method close (line 542) | func (sws *serverWatchStream) close() {
    method newResponseHeader (line 548) | func (sws *serverWatchStream) newResponseHeader(rev int64) *pb.Respons...
  function sendFragments (line 503) | func sendFragments(
  function filterNoDelete (line 557) | func filterNoDelete(e mvccpb.Event) bool {
  function filterNoPut (line 561) | func filterNoPut(e mvccpb.Event) bool {
  function FiltersFromRequest (line 566) | func FiltersFromRequest(creq *pb.WatchCreateRequest) []mvcc.FilterFunc {

FILE: vendor/github.com/coreos/etcd/etcdserver/apply.go
  constant warnApplyDuration (line 36) | warnApplyDuration = 100 * time.Millisecond
  type applyResult (line 39) | type applyResult struct
  type applierV3 (line 49) | type applierV3 interface
  type checkReqFunc (line 83) | type checkReqFunc
  type applierV3backend (line 85) | type applierV3backend struct
    method Apply (line 111) | func (a *applierV3backend) Apply(r *pb.InternalRaftRequest) *applyResu...
    method Put (line 173) | func (a *applierV3backend) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (r...
    method DeleteRange (line 217) | func (a *applierV3backend) DeleteRange(txn mvcc.TxnWrite, dr *pb.Delet...
    method Range (line 244) | func (a *applierV3backend) Range(txn mvcc.TxnRead, r *pb.RangeRequest)...
    method Txn (line 339) | func (a *applierV3backend) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, er...
    method applyTxn (line 504) | func (a *applierV3backend) applyTxn(txn mvcc.TxnWrite, rt *pb.TxnReque...
    method Compaction (line 556) | func (a *applierV3backend) Compaction(compaction *pb.CompactionRequest...
    method LeaseGrant (line 569) | func (a *applierV3backend) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.L...
    method LeaseRevoke (line 580) | func (a *applierV3backend) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb...
    method Alarm (line 585) | func (a *applierV3backend) Alarm(ar *pb.AlarmRequest) (*pb.AlarmRespon...
    method AuthEnable (line 678) | func (a *applierV3backend) AuthEnable() (*pb.AuthEnableResponse, error) {
    method AuthDisable (line 686) | func (a *applierV3backend) AuthDisable() (*pb.AuthDisableResponse, err...
    method Authenticate (line 691) | func (a *applierV3backend) Authenticate(r *pb.InternalAuthenticateRequ...
    method UserAdd (line 700) | func (a *applierV3backend) UserAdd(r *pb.AuthUserAddRequest) (*pb.Auth...
    method UserDelete (line 708) | func (a *applierV3backend) UserDelete(r *pb.AuthUserDeleteRequest) (*p...
    method UserChangePassword (line 716) | func (a *applierV3backend) UserChangePassword(r *pb.AuthUserChangePass...
    method UserGrantRole (line 724) | func (a *applierV3backend) UserGrantRole(r *pb.AuthUserGrantRoleReques...
    method UserGet (line 732) | func (a *applierV3backend) UserGet(r *pb.AuthUserGetRequest) (*pb.Auth...
    method UserRevokeRole (line 740) | func (a *applierV3backend) UserRevokeRole(r *pb.AuthUserRevokeRoleRequ...
    method RoleAdd (line 748) | func (a *applierV3backend) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.Auth...
    method RoleGrantPermission (line 756) | func (a *applierV3backend) RoleGrantPermission(r *pb.AuthRoleGrantPerm...
    method RoleGet (line 764) | func (a *applierV3backend) RoleGet(r *pb.AuthRoleGetRequest) (*pb.Auth...
    method RoleRevokePermission (line 772) | func (a *applierV3backend) RoleRevokePermission(r *pb.AuthRoleRevokePe...
    method RoleDelete (line 780) | func (a *applierV3backend) RoleDelete(r *pb.AuthRoleDeleteRequest) (*p...
    method UserList (line 788) | func (a *applierV3backend) UserList(r *pb.AuthUserListRequest) (*pb.Au...
    method RoleList (line 796) | func (a *applierV3backend) RoleList(r *pb.AuthRoleListRequest) (*pb.Au...
    method checkRequestPut (line 902) | func (a *applierV3backend) checkRequestPut(rv mvcc.ReadView, reqOp *pb...
    method checkRequestRange (line 926) | func (a *applierV3backend) checkRequestRange(rv mvcc.ReadView, reqOp *...
  method newApplierV3Backend (line 92) | func (s *EtcdServer) newApplierV3Backend() applierV3 {
  method newApplierV3 (line 103) | func (s *EtcdServer) newApplierV3() applierV3 {
  function newTxnResp (line 377) | func newTxnResp(rt *pb.TxnRequest, txnPath []bool) (txnResp *pb.TxnRespo...
  function compareToPath (line 407) | func compareToPath(rv mvcc.ReadView, rt *pb.TxnRequest) []bool {
  function applyCompares (line 423) | func applyCompares(rv mvcc.ReadView, cmps []*pb.Compare) bool {
  function applyCompare (line 434) | func applyCompare(rv mvcc.ReadView, c *pb.Compare) bool {
  function compareKV (line 460) | func compareKV(c *pb.Compare, ckv mvccpb.KeyValue) bool {
  type applierV3Capped (line 654) | type applierV3Capped struct
    method Put (line 663) | func (a *applierV3Capped) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*p...
    method Txn (line 667) | func (a *applierV3Capped) Txn(r *pb.TxnRequest) (*pb.TxnResponse, erro...
    method LeaseGrant (line 674) | func (a *applierV3Capped) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.Le...
  function newApplierV3Capped (line 661) | func newApplierV3Capped(base applierV3) applierV3 { return &applierV3Cap...
  type quotaApplierV3 (line 804) | type quotaApplierV3 struct
    method Put (line 813) | func (a *quotaApplierV3) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*pb...
    method Txn (line 822) | func (a *quotaApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, erro...
    method LeaseGrant (line 831) | func (a *quotaApplierV3) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.Lea...
  function newQuotaApplierV3 (line 809) | func newQuotaApplierV3(s *EtcdServer, app applierV3) applierV3 {
  type kvSort (line 840) | type kvSort struct
    method Swap (line 842) | func (s *kvSort) Swap(i, j int) {
    method Len (line 847) | func (s *kvSort) Len() int { return len(s.kvs) }
  type kvSortByKey (line 849) | type kvSortByKey struct
    method Less (line 851) | func (s *kvSortByKey) Less(i, j int) bool {
  type kvSortByVersion (line 855) | type kvSortByVersion struct
    method Less (line 857) | func (s *kvSortByVersion) Less(i, j int) bool {
  type kvSortByCreate (line 861) | type kvSortByCreate struct
    method Less (line 863) | func (s *kvSortByCreate) Less(i, j int) bool {
  type kvSortByMod (line 867) | type kvSortByMod struct
    method Less (line 869) | func (s *kvSortByMod) Less(i, j int) bool {
  type kvSortByValue (line 873) | type kvSortByValue struct
    method Less (line 875) | func (s *kvSortByValue) Less(i, j int) bool {
  function checkRequests (line 879) | func checkRequests(rv mvcc.ReadView, rt *pb.TxnRequest, txnPath []bool, ...
  function compareInt64 (line 943) | func compareInt64(a, b int64) int {
  function mkGteRange (line 958) | func mkGteRange(rangeEnd []byte) []byte {
  function noSideEffect (line 965) | func noSideEffect(r *pb.InternalRaftRequest) bool {
  function removeNeedlessRangeReqs (line 969) | func removeNeedlessRangeReqs(txn *pb.TxnRequest) {
  function pruneKVs (line 987) | func pruneKVs(rr *mvcc.RangeResult, isPrunable func(*mvccpb.KeyValue) bo...
  function newHeader (line 998) | func newHeader(s *EtcdServer) *pb.ResponseHeader {

FILE: vendor/github.com/coreos/etcd/etcdserver/apply_auth.go
  type authApplierV3 (line 26) | type authApplierV3 struct
    method Apply (line 42) | func (aa *authApplierV3) Apply(r *pb.InternalRaftRequest) *applyResult {
    method Put (line 64) | func (aa *authApplierV3) Put(txn mvcc.TxnWrite, r *pb.PutRequest) (*pb...
    method Range (line 86) | func (aa *authApplierV3) Range(txn mvcc.TxnRead, r *pb.RangeRequest) (...
    method DeleteRange (line 93) | func (aa *authApplierV3) DeleteRange(txn mvcc.TxnWrite, r *pb.DeleteRa...
    method Txn (line 165) | func (aa *authApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, erro...
    method LeaseRevoke (line 172) | func (aa *authApplierV3) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.L...
    method checkLeasePuts (line 179) | func (aa *authApplierV3) checkLeasePuts(leaseID lease.LeaseID) error {
    method UserGet (line 192) | func (aa *authApplierV3) UserGet(r *pb.AuthUserGetRequest) (*pb.AuthUs...
    method RoleGet (line 203) | func (aa *authApplierV3) RoleGet(r *pb.AuthRoleGetRequest) (*pb.AuthRo...
  function newAuthApplierV3 (line 38) | func newAuthApplierV3(as auth.AuthStore, base applierV3, lessor lease.Le...
  function checkTxnReqsPermission (line 107) | func checkTxnReqsPermission(as auth.AuthStore, ai *auth.AuthInfo, reqs [...
  function checkTxnAuth (line 150) | func checkTxnAuth(as auth.AuthStore, ai *auth.AuthInfo, rt *pb.TxnReques...
  function needAdminPermission (line 214) | func needAdminPermission(r *pb.InternalRaftRequest) bool {

FILE: vendor/github.com/coreos/etcd/etcdserver/apply_v2.go
  type ApplierV2 (line 32) | type ApplierV2 interface
  function NewApplierV2 (line 40) | func NewApplierV2(lg *zap.Logger, s v2store.Store, c *membership.RaftClu...
  type applierV2store (line 44) | type applierV2store struct
    method Delete (line 50) | func (a *applierV2store) Delete(r *RequestV2) Response {
    method Post (line 59) | func (a *applierV2store) Post(r *RequestV2) Response {
    method Put (line 63) | func (a *applierV2store) Put(r *RequestV2) Response {
    method QGet (line 105) | func (a *applierV2store) QGet(r *RequestV2) Response {
    method Sync (line 109) | func (a *applierV2store) Sync(r *RequestV2) Response {
  method applyV2Request (line 116) | func (s *EtcdServer) applyV2Request(r *RequestV2) Response {
  method TTLOptions (line 136) | func (r *RequestV2) TTLOptions() v2store.TTLOptionSet {
  function toResponse (line 145) | func toResponse(ev *v2store.Event, err error) Response {

FILE: vendor/github.com/coreos/etcd/etcdserver/backend.go
  function newBackend (line 31) | func newBackend(cfg ServerConfig) backend.Backend {
  function openSnapshotBackend (line 43) | func openSnapshotBackend(cfg ServerConfig, ss *snap.Snapshotter, snapsho...
  function openBackend (line 55) | func openBackend(cfg ServerConfig) backend.Backend {
  function recoverSnapshotBackend (line 90) | func recoverSnapshotBackend(cfg ServerConfig, oldbe backend.Backend, sna...

FILE: vendor/github.com/coreos/etcd/etcdserver/cluster_util.go
  function isMemberBootstrapped (line 35) | func isMemberBootstrapped(lg *zap.Logger, cl *membership.RaftCluster, me...
  function GetClusterFromRemotePeers (line 58) | func GetClusterFromRemotePeers(lg *zap.Logger, urls []string, rt http.Ro...
  function getClusterFromRemotePeers (line 63) | func getClusterFromRemotePeers(lg *zap.Logger, urls []string, timeout ti...
  function getRemotePeerURLs (line 135) | func getRemotePeerURLs(cl *membership.RaftCluster, local string) []string {
  function getVersions (line 151) | func getVersions(lg *zap.Logger, cl *membership.RaftCluster, local types...
  function decideClusterVersion (line 181) | func decideClusterVersion(lg *zap.Logger, vers map[string]*version.Versi...
  function isCompatibleWithCluster (line 231) | func isCompatibleWithCluster(lg *zap.Logger, cl *membership.RaftCluster,...
  function isCompatibleWithVers (line 242) | func isCompatibleWithVers(lg *zap.Logger, vers map[string]*version.Versi...
  function getVersion (line 299) | func getVersion(lg *zap.Logger, m *membership.Member, rt http.RoundTripp...

FILE: vendor/github.com/coreos/etcd/etcdserver/config.go
  type ServerConfig (line 34) | type ServerConfig struct
    method VerifyBootstrap (line 147) | func (c *ServerConfig) VerifyBootstrap() error {
    method VerifyJoinExisting (line 165) | func (c *ServerConfig) VerifyJoinExisting() error {
    method hasLocalMember (line 181) | func (c *ServerConfig) hasLocalMember() error {
    method advertiseMatchesCluster (line 189) | func (c *ServerConfig) advertiseMatchesCluster() error {
    method MemberDir (line 240) | func (c *ServerConfig) MemberDir() string { return filepath.Join(c.Dat...
    method WALDir (line 242) | func (c *ServerConfig) WALDir() string {
    method SnapDir (line 249) | func (c *ServerConfig) SnapDir() string { return filepath.Join(c.Membe...
    method ShouldDiscover (line 251) | func (c *ServerConfig) ShouldDiscover() bool { return c.DiscoveryURL !...
    method ReqTimeout (line 254) | func (c *ServerConfig) ReqTimeout() time.Duration {
    method electionTimeout (line 260) | func (c *ServerConfig) electionTimeout() time.Duration {
    method peerDialTimeout (line 264) | func (c *ServerConfig) peerDialTimeout() time.Duration {
    method PrintWithInitial (line 269) | func (c *ServerConfig) PrintWithInitial() { c.print(true) }
    method Print (line 271) | func (c *ServerConfig) Print() { c.print(false) }
    method print (line 273) | func (c *ServerConfig) print(initial bool) {
    method bootstrapTimeout (line 348) | func (c *ServerConfig) bootstrapTimeout() time.Duration {
    method backendPath (line 355) | func (c *ServerConfig) backendPath() string { return filepath.Join(c.S...
    method getAPURLs (line 357) | func (c *ServerConfig) getAPURLs() (ss []string) {
    method getACURLs (line 365) | func (c *ServerConfig) getACURLs() (ss []string) {
  function checkDuplicateURL (line 334) | func checkDuplicateURL(urlsmap types.URLsMap) bool {

FILE: vendor/github.com/coreos/etcd/etcdserver/consistent_index.go
  type consistentIndex (line 25) | type consistentIndex
    method setConsistentIndex (line 27) | func (i *consistentIndex) setConsistentIndex(v uint64) {
    method ConsistentIndex (line 31) | func (i *consistentIndex) ConsistentIndex() uint64 {

FILE: vendor/github.com/coreos/etcd/etcdserver/corrupt.go
  method CheckInitialHashKV (line 34) | func (s *EtcdServer) CheckInitialHashKV() error {
  method monitorKVHash (line 142) | func (s *EtcdServer) monitorKVHash() {
  method checkHashKV (line 178) | func (s *EtcdServer) checkHashKV() error {
  type peerHashKVResp (line 303) | type peerHashKVResp struct
  method getPeerHashKVs (line 311) | func (s *EtcdServer) getPeerHashKVs(rev int64) (resps []*peerHashKVResp) {
  type applierV3Corrupt (line 379) | type applierV3Corrupt struct
    method Put (line 385) | func (a *applierV3Corrupt) Put(txn mvcc.TxnWrite, p *pb.PutRequest) (*...
    method Range (line 389) | func (a *applierV3Corrupt) Range(txn mvcc.TxnRead, p *pb.RangeRequest)...
    method DeleteRange (line 393) | func (a *applierV3Corrupt) DeleteRange(txn mvcc.TxnWrite, p *pb.Delete...
    method Txn (line 397) | func (a *applierV3Corrupt) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, er...
    method Compaction (line 401) | func (a *applierV3Corrupt) Compaction(compaction *pb.CompactionRequest...
    method LeaseGrant (line 405) | func (a *applierV3Corrupt) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.L...
    method LeaseRevoke (line 409) | func (a *applierV3Corrupt) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb...
  function newApplierV3Corrupt (line 383) | func newApplierV3Corrupt(a applierV3) *applierV3Corrupt { return &applie...

FILE: vendor/github.com/coreos/etcd/etcdserver/errors.go
  type DiscoveryError (line 41) | type DiscoveryError struct
    method Error (line 46) | func (e DiscoveryError) Error() string {

FILE: vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go
  constant _ (line 128) | _ = proto.ProtoPackageIsVersion2
  type Request (line 130) | type Request struct
    method Reset (line 151) | func (m *Request) Reset()                    { *m = Request{} }
    method String (line 152) | func (m *Request) String() string            { return proto.CompactTex...
    method ProtoMessage (line 153) | func (*Request) ProtoMessage()               {}
    method Descriptor (line 154) | func (*Request) Descriptor() ([]byte, []int) { return fileDescriptorEt...
    method Marshal (line 171) | func (m *Request) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 181) | func (m *Request) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 331) | func (m *Request) Size() (n int) {
    method Unmarshal (line 389) | func (m *Request) Unmarshal(dAtA []byte) error {
  type Metadata (line 156) | type Metadata struct
    method Reset (line 162) | func (m *Metadata) Reset()                    { *m = Metadata{} }
    method String (line 163) | func (m *Metadata) String() string            { return proto.CompactTe...
    method ProtoMessage (line 164) | func (*Metadata) ProtoMessage()               {}
    method Descriptor (line 165) | func (*Metadata) Descriptor() ([]byte, []int) { return fileDescriptorE...
    method Marshal (line 295) | func (m *Metadata) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 305) | func (m *Metadata) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 365) | func (m *Metadata) Size() (n int) {
    method Unmarshal (line 813) | func (m *Metadata) Unmarshal(dAtA []byte) error {
  function init (line 167) | func init() {
  function encodeVarintEtcdserver (line 322) | func encodeVarintEtcdserver(dAtA []byte, offset int, v uint64) int {
  function sovEtcdserver (line 376) | func sovEtcdserver(x uint64) (n int) {
  function sozEtcdserver (line 386) | func sozEtcdserver(x uint64) (n int) {
  function skipEtcdserver (line 902) | func skipEtcdserver(dAtA []byte) (n int, err error) {
  function init (line 1007) | func init() { proto.RegisterFile("etcdserver.proto", fileDescriptorEtcds...

FILE: vendor/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go
  type RequestHeader (line 23) | type RequestHeader struct
    method Reset (line 31) | func (m *RequestHeader) Reset()                    { *m = RequestHeade...
    method String (line 32) | func (m *RequestHeader) String() string            { return proto.Comp...
    method ProtoMessage (line 33) | func (*RequestHeader) ProtoMessage()               {}
    method Descriptor (line 34) | func (*RequestHeader) Descriptor() ([]byte, []int) { return fileDescri...
    method Marshal (line 104) | func (m *RequestHeader) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 114) | func (m *RequestHeader) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 518) | func (m *RequestHeader) Size() (n int) {
    method Unmarshal (line 684) | func (m *RequestHeader) Unmarshal(dAtA []byte) error {
  type InternalRaftRequest (line 38) | type InternalRaftRequest struct
    method Reset (line 68) | func (m *InternalRaftRequest) Reset()                    { *m = Intern...
    method String (line 69) | func (m *InternalRaftRequest) String() string            { return prot...
    method ProtoMessage (line 70) | func (*InternalRaftRequest) ProtoMessage()               {}
    method Descriptor (line 71) | func (*InternalRaftRequest) Descriptor() ([]byte, []int) { return file...
    method Marshal (line 138) | func (m *InternalRaftRequest) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 148) | func (m *InternalRaftRequest) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 534) | func (m *InternalRaftRequest) Size() (n int) {
    method Unmarshal (line 801) | func (m *InternalRaftRequest) Unmarshal(dAtA []byte) error {
  type EmptyResponse (line 73) | type EmptyResponse struct
    method Reset (line 76) | func (m *EmptyResponse) Reset()                    { *m = EmptyRespons...
    method String (line 77) | func (m *EmptyResponse) String() string            { return proto.Comp...
    method ProtoMessage (line 78) | func (*EmptyResponse) ProtoMessage()               {}
    method Descriptor (line 79) | func (*EmptyResponse) Descriptor() ([]byte, []int) { return fileDescri...
    method Marshal (line 455) | func (m *EmptyResponse) Marshal() (dAtA []byte, err error) {
    method MarshalTo (line 465) | func (m *EmptyResponse) MarshalTo(dAtA []byte) (int, error) {
    method Size (line 647) | func (m *EmptyResponse) Size() (n int) {
    method Unmarshal (line 1728) | func (m *EmptyResponse) Unmarshal(dAtA []byte) error {
  type InternalAuthenticateRequest (line 84) | type InternalAuthenticateRequest struct
    method Reset (line 91) | func (m *InternalAuthenticateRequest) Reset()         { *m = InternalA...
    method String (line 92) | func (m *InternalAuthenticateRequest) String() string { return proto.C...
    method ProtoMessage (line 
Copy disabled (too large) Download .json
Condensed preview — 1452 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (33,672K chars).
[
  {
    "path": ".gitignore",
    "chars": 489,
    "preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# IDEs and editors\n/.idea\n*.iml\n/.vscode\n\n#Sy"
  },
  {
    "path": ".travis.yml",
    "chars": 70,
    "preview": "language: go\n\nsudo: false\n\ngo:\n- 1.10.3\n\nscript:\n- ./scripts/tests.sh\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2714,
    "preview": "# How to Contribute\n\nCoreOS projects are [Apache 2.0 licensed](LICENSE) and accept contributions via\nGitHub pull request"
  },
  {
    "path": "DCO",
    "chars": 1422,
    "preview": "Developer Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n660 Yor"
  },
  {
    "path": "Gopkg.toml",
    "chars": 3921,
    "preview": "################################\n# Direct dependencies\n\n\n# master\n[[constraint]]\n  name = \"github.com/coreos/etcd\"\n  sou"
  },
  {
    "path": "LICENSE",
    "chars": 11325,
    "preview": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licens"
  },
  {
    "path": "NOTICE",
    "chars": 126,
    "preview": "CoreOS Project\nCopyright 2015 CoreOS, Inc\n\nThis product includes software developed at CoreOS, Inc.\n(http://www.coreos.c"
  },
  {
    "path": "README.md",
    "chars": 17168,
    "preview": "# dbtester\n\n[![Build Status](https://img.shields.io/travis/etcd-io/dbtester.svg?style=flat-square)](https://travis-ci.co"
  },
  {
    "path": "agent/agent_cetcd.go",
    "chars": 2000,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/agent_consul.go",
    "chars": 2184,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/agent_etcd.go",
    "chars": 4760,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/agent_zetcd.go",
    "chars": 1984,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/agent_zookeeper.go",
    "chars": 6103,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/command.go",
    "chars": 5662,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/doc.go",
    "chars": 660,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/server.go",
    "chars": 9714,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/server_system_metrics.go",
    "chars": 2760,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/upload_log.go",
    "chars": 6065,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "agent/util.go",
    "chars": 1749,
    "preview": "// Copyright 2016 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "analyze/01_read_raw_data_to_test_data.go",
    "chars": 2811,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "analyze/02_read_all_metrics_to_analyze_data.go",
    "chars": 4042,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "analyze/03_read_benchmark_metrics_to_analyze_data.go",
    "chars": 7556,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "analyze/04_aggregate_all_analyze_data.go",
    "chars": 20866,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "analyze/05_plot.go",
    "chars": 5949,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "analyze/command.go",
    "chars": 37852,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "analyze/doc.go",
    "chars": 686,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "analyze/logger.go",
    "chars": 748,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "analyze/util.go",
    "chars": 1440,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "broadcast_request.go",
    "chars": 2670,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "cmd/dbtester/main.go",
    "chars": 1498,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "code-of-conduct.md",
    "chars": 3037,
    "preview": "## CoreOS Community Code of Conduct\n\n### Contributor Code of Conduct\n\nAs contributors and maintainers of this project, a"
  },
  {
    "path": "config-dbtester-gcloud-key.json",
    "chars": 8,
    "preview": "test-key"
  },
  {
    "path": "config_dbtester.go",
    "chars": 18314,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "config_dbtester_test.go",
    "chars": 31321,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "config_dbtester_test.yaml",
    "chars": 16384,
    "preview": "test_title: Write 1M keys, 256-byte key, 1KB value value, clients 1 to 1,000\ntest_description: |\n  - Google Cloud Comput"
  },
  {
    "path": "control/command.go",
    "chars": 7611,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "control/logger.go",
    "chars": 748,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "dbtesterpb/config_analyze_machine.pb.go",
    "chars": 55037,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: dbtesterpb/config_analyze_machine.proto\n\n/*\n\tPackage dbtes"
  },
  {
    "path": "dbtesterpb/config_analyze_machine.proto",
    "chars": 3338,
    "preview": "syntax = \"proto3\";\npackage dbtesterpb;\n\nimport \"github.com/gogo/protobuf/gogoproto/gogo.proto\";\n\noption (gogoproto.marsh"
  },
  {
    "path": "dbtesterpb/config_client_machine.pb.go",
    "chars": 78498,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: dbtesterpb/config_client_machine.proto\n\npackage dbtesterpb"
  },
  {
    "path": "dbtesterpb/config_client_machine.proto",
    "chars": 5509,
    "preview": "syntax = \"proto3\";\npackage dbtesterpb;\n\nimport \"github.com/gogo/protobuf/gogoproto/gogo.proto\";\n\nimport \"dbtesterpb/flag"
  },
  {
    "path": "dbtesterpb/database_id.pb.go",
    "chars": 3581,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: dbtesterpb/database_id.proto\n\npackage dbtesterpb\n\nimport p"
  },
  {
    "path": "dbtesterpb/database_id.proto",
    "chars": 893,
    "preview": "syntax = \"proto3\";\npackage dbtesterpb;\n\nimport \"github.com/gogo/protobuf/gogoproto/gogo.proto\";\n\noption (gogoproto.marsh"
  },
  {
    "path": "dbtesterpb/flag_cetcd.pb.go",
    "chars": 5823,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: dbtesterpb/flag_cetcd.proto\n\npackage dbtesterpb\n\nimport pr"
  },
  {
    "path": "dbtesterpb/flag_cetcd.proto",
    "chars": 378,
    "preview": "syntax = \"proto3\";\npackage dbtesterpb;\n\nimport \"github.com/gogo/protobuf/gogoproto/gogo.proto\";\n\noption (gogoproto.marsh"
  },
  {
    "path": "dbtesterpb/flag_consul.pb.go",
    "chars": 5876,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: dbtesterpb/flag_consul.proto\n\npackage dbtesterpb\n\nimport p"
  },
  {
    "path": "dbtesterpb/flag_consul.proto",
    "chars": 353,
    "preview": "syntax = \"proto3\";\npackage dbtesterpb;\n\nimport \"github.com/gogo/protobuf/gogoproto/gogo.proto\";\n\noption (gogoproto.marsh"
  },
  {
    "path": "dbtesterpb/flag_etcd.pb.go",
    "chars": 18343,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: dbtesterpb/flag_etcd.proto\n\npackage dbtesterpb\n\nimport pro"
  },
  {
    "path": "dbtesterpb/flag_etcd.proto",
    "chars": 1330,
    "preview": "syntax = \"proto3\";\npackage dbtesterpb;\n\nimport \"github.com/gogo/protobuf/gogoproto/gogo.proto\";\n\noption (gogoproto.marsh"
  },
  {
    "path": "dbtesterpb/flag_zetcd.pb.go",
    "chars": 5823,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: dbtesterpb/flag_zetcd.proto\n\npackage dbtesterpb\n\nimport pr"
  },
  {
    "path": "dbtesterpb/flag_zetcd.proto",
    "chars": 378,
    "preview": "syntax = \"proto3\";\npackage dbtesterpb;\n\nimport \"github.com/gogo/protobuf/gogoproto/gogo.proto\";\n\noption (gogoproto.marsh"
  },
  {
    "path": "dbtesterpb/flag_zookeeper.pb.go",
    "chars": 16946,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: dbtesterpb/flag_zookeeper.proto\n\npackage dbtesterpb\n\nimpor"
  },
  {
    "path": "dbtesterpb/flag_zookeeper.proto",
    "chars": 2089,
    "preview": "syntax = \"proto3\";\npackage dbtesterpb;\n\nimport \"github.com/gogo/protobuf/gogoproto/gogo.proto\";\n\noption (gogoproto.marsh"
  },
  {
    "path": "dbtesterpb/message.pb.go",
    "chars": 32813,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: dbtesterpb/message.proto\n\npackage dbtesterpb\n\nimport proto"
  },
  {
    "path": "dbtesterpb/message.proto",
    "chars": 1762,
    "preview": "syntax = \"proto3\";\npackage dbtesterpb;\n\nimport \"github.com/gogo/protobuf/gogoproto/gogo.proto\";\n\nimport \"dbtesterpb/data"
  },
  {
    "path": "dbtesterpb/util.go",
    "chars": 3107,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "find_ranges.go",
    "chars": 6839,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "find_ranges_test.go",
    "chars": 4257,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "pkg/fileinspect/fileinspect.go",
    "chars": 2988,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "pkg/fileinspect/fileinspect_test.go",
    "chars": 2052,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "pkg/ntp/ntp.go",
    "chars": 2625,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "pkg/ntp/ntp_test.go",
    "chars": 739,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "pkg/remotestorage/doc.go",
    "chars": 662,
    "preview": "// Copyright 2016 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "pkg/remotestorage/example/agent.log",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "pkg/remotestorage/example/key.json",
    "chars": 2,
    "preview": "a\n"
  },
  {
    "path": "pkg/remotestorage/example/main.go",
    "chars": 1414,
    "preview": "// Copyright 2018 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "pkg/remotestorage/op.go",
    "chars": 856,
    "preview": "// Copyright 2016 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "pkg/remotestorage/uploader.go",
    "chars": 4560,
    "preview": "// Copyright 2016 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "pkg/remotestorage/util.go",
    "chars": 1188,
    "preview": "// Copyright 2016 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "readme.go",
    "chars": 1581,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "report.go",
    "chars": 3835,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "report_save_upload.go",
    "chars": 10279,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "scripts/dbtester-google-cloud.sh",
    "chars": 14564,
    "preview": "#!/usr/bin/env bash\nset -e\n\n##################################################\n# create compute instances\n\ngcloud comput"
  },
  {
    "path": "scripts/genproto.sh",
    "chars": 803,
    "preview": "#!/usr/bin/env bash\nset -e\n\nif ! [[ \"$0\" =~ \"scripts/genproto.sh\" ]]; then\n  echo \"must be run from repository root\"\n  e"
  },
  {
    "path": "scripts/install-cetcd.sh",
    "chars": 81,
    "preview": "#!/usr/bin/env bash\nset -e\n\ngo get -v github.com/coreos/cetcd/cmd/cetcd\ncetcd -h\n"
  },
  {
    "path": "scripts/install-consul.sh",
    "chars": 320,
    "preview": "#!/usr/bin/env bash\nset -e\n\nrm -f /tmp/consul.zip\ncurl -sf -o /tmp/consul.zip https://releases.hashicorp.com/consul/1.0."
  },
  {
    "path": "scripts/install-etcd.sh",
    "chars": 943,
    "preview": "#!/usr/bin/env bash\nset -e\n\nGIT_PATH=github.com/coreos/etcd\n\nUSER_NAME=coreos\nBRANCH_NAME=release-3.2\nBRANCH_NAME=releas"
  },
  {
    "path": "scripts/install-go.sh",
    "chars": 748,
    "preview": "#!/usr/bin/env bash\nset -e\n\nGO_VERSION=1.8.7\n\nsudo rm -f /usr/local/go/bin/go && sudo rm -rf /usr/local/go && sudo rm -f"
  },
  {
    "path": "scripts/install-zetcd.sh",
    "chars": 81,
    "preview": "#!/usr/bin/env bash\nset -e\n\ngo get -v github.com/coreos/zetcd/cmd/zetcd\nzetcd -h\n"
  },
  {
    "path": "scripts/install-zookeeper-ubuntu.sh",
    "chars": 2205,
    "preview": "#!/usr/bin/env bash\nset -e\n\nsudo apt install -y ansible\n\ncat > /tmp/install-java.yml <<EOF\n---\n- name: a play that runs "
  },
  {
    "path": "scripts/tests.sh",
    "chars": 581,
    "preview": "#!/usr/bin/env bash\nset -e\n\nif ! [[ \"$0\" =~ \"scripts/tests.sh\" ]]; then\n    echo \"must be run from repository root\"\n    "
  },
  {
    "path": "scripts/updatedep.sh",
    "chars": 202,
    "preview": "#!/usr/bin/env bash\nset -e\n\nif ! [[ \"$0\" =~ \"./scripts/updatedep.sh\" ]]; then\n  echo \"must be run from repository root\"\n"
  },
  {
    "path": "stress.go",
    "chars": 19064,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "stress_client.go",
    "chars": 863,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "stress_client_consul.go",
    "chars": 1997,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "stress_client_etcdv3.go",
    "chars": 3037,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "stress_client_zookeeper.go",
    "chars": 2467,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "test-configs/read-3M-same-keys-1K-client.yaml",
    "chars": 17740,
    "preview": "test_title: Read 3M same keys, 256-byte key, 1KB value, 1,000 clients\ntest_description: |\n  - Google Cloud Compute Engin"
  },
  {
    "path": "test-configs/read-3M-same-keys-best-throughput-etcd.yaml",
    "chars": 12333,
    "preview": "test_title: Read 3M same keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns)\ntest_descriptio"
  },
  {
    "path": "test-configs/read-3M-same-keys-best-throughput.yaml",
    "chars": 18068,
    "preview": "test_title: Read 3M same keys, 256-byte key, 1KB value, Best Throughput (etcd 1,000, Zookeeper 700, Consul 500 clients)\n"
  },
  {
    "path": "test-configs/write-100K-keys-1-client.yaml",
    "chars": 13623,
    "preview": "test_title: Write 100K keys, 256-byte key, 1KB value, 1 client\ntest_description: |\n  - Google Cloud Compute Engine\n  - 4"
  },
  {
    "path": "test-configs/write-1M-keys-1000QPS.yaml",
    "chars": 17304,
    "preview": "test_title: Write 1M keys, 256-byte key, 1KB value, 100 clients, 1000 QPS Limit\ntest_description: |\n  - Google Cloud Com"
  },
  {
    "path": "test-configs/write-1M-keys-best-throughput.yaml",
    "chars": 16511,
    "preview": "test_title: Write 1M keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns, Zookeeper 700, Cons"
  },
  {
    "path": "test-configs/write-1M-keys-client-variable.yaml",
    "chars": 17789,
    "preview": "test_title: Write 1M keys, 256-byte key, 1KB value value, clients 1 to 1,000\ntest_description: |\n  - Google Cloud Comput"
  },
  {
    "path": "test-configs/write-too-many-keys.yaml",
    "chars": 11692,
    "preview": "test_title: Write 3-million keys, 256-byte key, 1KB value, Best Throughput (etcd 1,000)\ntest_description: |\n  - Google C"
  },
  {
    "path": "test-results/2017Q1-00-etcd-zookeeper-consul/README.md",
    "chars": 38416,
    "preview": "\n\n\n<br><br><hr>\n##### Noticeable Warnings: Zookeeper\n\nSnapshot, when writing 1-million entries (256-byte key, 1KB value "
  },
  {
    "path": "test-results/2017Q1-01-etcd-zookeeper-consul/README.md",
    "chars": 36974,
    "preview": "\n\n<br><br><hr>\n##### Write 1M keys, 256-byte key, 1KB value value, clients 1 to 1,000\n\n- Google Cloud Compute Engine\n- 4"
  },
  {
    "path": "test-results/2017Q2-01-etcd-zookeeper-consul/README.md",
    "chars": 47895,
    "preview": "\n<img src=\"https://storage.googleapis.com/dbtester-results/2017Q2-01-etcd-zookeeper-consul/2017Q2-01-write-1M-cpu-client"
  },
  {
    "path": "test-results/2017Q2-02-etcd-zookeeper-consul/README.md",
    "chars": 10090,
    "preview": "\n<img src=\"https://storage.googleapis.com/dbtester-results/2017Q2-02-etcd-zookeeper-consul/2017Q2-01-write-1M-cpu-client"
  },
  {
    "path": "test-results/2018Q1-01-etcd/README.md",
    "chars": 21963,
    "preview": "\n<img src=\"https://storage.googleapis.com/dbtester-results/2018Q1-01-etcd/write-3m-avg-latency.png\" alt=\"write-3m-avg-la"
  },
  {
    "path": "test-results/2018Q1-02-etcd-zookeeper-consul/README.md",
    "chars": 9380,
    "preview": "\n\n<br><br><hr>\n##### Write 1M keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns, Zookeeper "
  },
  {
    "path": "test-results/2018Q1-03-etcd-kubemark/README.md",
    "chars": 125,
    "preview": "\n\n![v3.2.0-kubemark-500-node](./v3.2.0-kubemark-500-node.png)\n\n![v3.3.0-kubemark-500-node](./v3.3.0-kubemark-500-node.pn"
  },
  {
    "path": "test-results/2018Q1-04-etcd-zookeeper/README.md",
    "chars": 7889,
    "preview": "\n\n<br><br><hr>\n##### Write 100K keys, 256-byte key, 1KB value, 1 client\n\n- Google Cloud Compute Engine\n- 4 machines of 1"
  },
  {
    "path": "test-results/2018Q2-01-etcd-client-balancer/README.md",
    "chars": 20496,
    "preview": "\n\n<br><br><hr>\n##### Read 3M same keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns)\n\n- Goo"
  },
  {
    "path": "test-results/2018Q2-01-etcd-client-balancer/read-3M-same-keys-best-throughput.yaml",
    "chars": 17615,
    "preview": "test_title: Read 3M same keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns)\ntest_descriptio"
  },
  {
    "path": "test-results/2018Q2-01-etcd-client-balancer/write-1M-keys-best-throughput.yaml",
    "chars": 17431,
    "preview": "test_title: Write 1M keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns)\ntest_description: |"
  },
  {
    "path": "test-results/2018Q2-02-etcd-client-balancer/README.md",
    "chars": 17264,
    "preview": "\n\n<br><br><hr>\n##### Write 1M keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns)\n\n- Google "
  },
  {
    "path": "test-results/2018Q2-02-etcd-client-balancer/read-3M-same-keys-best-throughput.yaml",
    "chars": 13113,
    "preview": "test_title: Read 3M same keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns)\ntest_descriptio"
  },
  {
    "path": "test-results/2018Q2-02-etcd-client-balancer/write-1M-keys-best-throughput.yaml",
    "chars": 12933,
    "preview": "test_title: Write 1M keys, 256-byte key, 1KB value, Best Throughput (etcd 1K clients with 100 conns)\ntest_description: |"
  },
  {
    "path": "util.go",
    "chars": 3182,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "util_test.go",
    "chars": 1111,
    "preview": "// Copyright 2017 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use "
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/LICENSE",
    "chars": 1310,
    "preview": "Copyright (c) 2011, The gopdf Authors\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or w"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/canvas.go",
    "chars": 7429,
    "preview": "// Copyright (C) 2011, Ross Light\n\npackage pdf\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"image\"\n\t\"io\"\n\t\"math\"\n)\n\n// writeCommand write"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/doc.go",
    "chars": 742,
    "preview": "// Copyright (C) 2011, Ross Light\n\n/*\n\tPackage pdf implements a Portable Document Format writer, as defined in ISO 32000"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/encode.go",
    "chars": 3566,
    "preview": "// Copyright (C) 2011, Ross Light\n\npackage pdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// encoder writes the PDF file format structure"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/image.go",
    "chars": 3065,
    "preview": "// Copyright (C) 2011, Ross Light\n\npackage pdf\n\nimport (\n\t\"image\"\n\t\"image/color\"\n\t\"io\"\n)\n\nconst (\n\tdeviceRGBColorSpace n"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/marshal.go",
    "chars": 4598,
    "preview": "// Copyright (C) 2011, Ross Light\n\npackage pdf\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// A marshaler ca"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/metrics.go",
    "chars": 25749,
    "preview": "package pdf\n\n// Courier\nvar courierWidths = []uint16{\n\t32:  600, // space\n\t33:  600, // exclam\n\t34:  600, // quotedbl\n\t3"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/objects.go",
    "chars": 1161,
    "preview": "// Copyright (C) 2011, Ross Light\n\npackage pdf\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// name is a PDF name object, which is use"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/pdf.go",
    "chars": 4841,
    "preview": "// Copyright (C) 2011, Ross Light\n\npackage pdf\n\nimport (\n\t\"image\"\n\t\"io\"\n\t\"strconv\"\n)\n\n// Unit is a device-independent di"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/stream.go",
    "chars": 1906,
    "preview": "package pdf\n\nimport (\n\t\"bytes\"\n\t\"compress/lzw\"\n\t\"compress/zlib\"\n\t\"io\"\n)\n\nconst (\n\tstreamNoFilter    name = \"\"\n\tstreamLZW"
  },
  {
    "path": "vendor/bitbucket.org/zombiezen/gopdf/pdf/text.go",
    "chars": 3285,
    "preview": "// Copyright (C) 2011, Ross Light\n\npackage pdf\n\nimport (\n\t\"bytes\"\n)\n\n// Text is a PDF text object.  The zero value is an"
  },
  {
    "path": "vendor/cloud.google.com/go/LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "vendor/cloud.google.com/go/cloud.go",
    "chars": 902,
    "preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/compute/metadata/metadata.go",
    "chars": 12832,
    "preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/iam/iam.go",
    "chars": 7491,
    "preview": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/internal/annotate.go",
    "chars": 1682,
    "preview": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/internal/optional/optional.go",
    "chars": 2526,
    "preview": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/internal/retry.go",
    "chars": 1765,
    "preview": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/internal/version/version.go",
    "chars": 1779,
    "preview": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/acl.go",
    "chars": 6409,
    "preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/bucket.go",
    "chars": 23190,
    "preview": "// Copyright 2014 Google Inc. LiveAndArchived Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/copy.go",
    "chars": 7001,
    "preview": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/doc.go",
    "chars": 5533,
    "preview": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/go110.go",
    "chars": 965,
    "preview": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/go17.go",
    "chars": 780,
    "preview": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/iam.go",
    "chars": 3187,
    "preview": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/invoke.go",
    "chars": 1117,
    "preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/not_go110.go",
    "chars": 1184,
    "preview": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/not_go17.go",
    "chars": 792,
    "preview": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/notifications.go",
    "chars": 5587,
    "preview": "// Copyright 2017 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/reader.go",
    "chars": 2857,
    "preview": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/storage.go",
    "chars": 38016,
    "preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/cloud.google.com/go/storage/writer.go",
    "chars": 6174,
    "preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "vendor/github.com/ajstarks/svgo/LICENSE",
    "chars": 160,
    "preview": "The contents of this repository are Licensed under \nthe Creative Commons Attribution 3.0 license as described in\nhttp://"
  },
  {
    "path": "vendor/github.com/ajstarks/svgo/doc.go",
    "chars": 3000,
    "preview": "/*\nPackage svg generates SVG as defined by the Scalable Vector Graphics 1.1 Specification (<http://www.w3.org/TR/SVG11/>"
  },
  {
    "path": "vendor/github.com/ajstarks/svgo/svg.go",
    "chars": 36173,
    "preview": "// Package svg provides an API for generating Scalable Vector Graphics (SVG)\npackage svg\n\n// package main\n//\n// \timport "
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/LICENSE",
    "chars": 1479,
    "preview": "Copyright (c) 2012-2015, Sergey Cherepanov\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/format.go",
    "chars": 2361,
    "preview": "package pb\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\ntype Units int\n\nconst (\n\t// U_NO are default units, they represent a simple value"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/pb.go",
    "chars": 10911,
    "preview": "// Simple console progress bars\npackage pb\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\t\"un"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/pb_appengine.go",
    "chars": 274,
    "preview": "// +build appengine\n\npackage pb\n\nimport \"errors\"\n\n// terminalWidth returns width of the terminal, which is not supported"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/pb_win.go",
    "chars": 4168,
    "preview": "// +build windows\n\npackage pb\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nvar tty = os.Stdin\n\nvar ("
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/pb_x.go",
    "chars": 2150,
    "preview": "// +build linux darwin freebsd netbsd openbsd solaris dragonfly\n// +build !appengine\n\npackage pb\n\nimport (\n\t\"errors\"\n\t\"f"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/pool.go",
    "chars": 1435,
    "preview": "// +build linux darwin freebsd netbsd openbsd solaris dragonfly windows\n\npackage pb\n\nimport (\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n)\n\n/"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/pool_win.go",
    "chars": 691,
    "preview": "// +build windows\n\npackage pb\n\nimport (\n\t\"fmt\"\n\t\"log\"\n)\n\nfunc (p *Pool) print(first bool) bool {\n\tp.m.Lock()\n\tdefer p.m."
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/pool_x.go",
    "chars": 540,
    "preview": "// +build linux darwin freebsd netbsd openbsd solaris dragonfly\n\npackage pb\n\nimport \"fmt\"\n\nfunc (p *Pool) print(first bo"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/reader.go",
    "chars": 400,
    "preview": "package pb\n\nimport (\n\t\"io\"\n)\n\n// It's proxy reader, implement io.Reader\ntype Reader struct {\n\tio.Reader\n\tbar *ProgressBa"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/runecount.go",
    "chars": 364,
    "preview": "package pb\n\nimport (\n\t\"github.com/mattn/go-runewidth\"\n\t\"regexp\"\n)\n\n// Finds the control character sequences (like colors"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/termios_bsd.go",
    "chars": 187,
    "preview": "// +build darwin freebsd netbsd openbsd dragonfly\n// +build !appengine\n\npackage pb\n\nimport \"syscall\"\n\nconst ioctlReadTer"
  },
  {
    "path": "vendor/github.com/cheggaaa/pb/termios_sysv.go",
    "chars": 325,
    "preview": "// Copyright 2013 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/coreos/etcd/LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "vendor/github.com/coreos/etcd/NOTICE",
    "chars": 126,
    "preview": "CoreOS Project\nCopyright 2014 CoreOS, Inc\n\nThis product includes software developed at CoreOS, Inc.\n(http://www.coreos.c"
  },
  {
    "path": "vendor/github.com/coreos/etcd/auth/authpb/auth.pb.go",
    "chars": 19024,
    "preview": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: auth.proto\n\n/*\n\tPackage authpb is a generated protocol buf"
  },
  {
    "path": "vendor/github.com/coreos/etcd/auth/doc.go",
    "chars": 687,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/auth/jwt.go",
    "chars": 5720,
    "preview": "// Copyright 2017 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/auth/nop.go",
    "chars": 1205,
    "preview": "// Copyright 2018 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/auth/range_perm_cache.go",
    "chars": 3945,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/auth/simple_token.go",
    "chars": 5913,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/auth/store.go",
    "chars": 34403,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/auth_role.go",
    "chars": 5865,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/auth_user.go",
    "chars": 7743,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/cancelreq.go",
    "chars": 405,
    "preview": "// Copyright 2015 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/client.go",
    "chars": 18192,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/cluster_error.go",
    "chars": 981,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/curl.go",
    "chars": 1504,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/discover.go",
    "chars": 1210,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/doc.go",
    "chars": 1846,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/keys.generated.go",
    "chars": 83958,
    "preview": "// Code generated by codecgen - DO NOT EDIT.\n\npackage client\n\nimport (\n\t\"errors\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"time\"\n\n\tcodec19"
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/keys.go",
    "chars": 19469,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/members.go",
    "chars": 7275,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/client/util.go",
    "chars": 1526,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/auth.go",
    "chars": 9553,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/balancer/doc.go",
    "chars": 659,
    "preview": "// Copyright 2018 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/balancer/grpc1.7-health.go",
    "chars": 16529,
    "preview": "// Copyright 2018 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/client.go",
    "chars": 14701,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/cluster.go",
    "chars": 3407,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/compact_op.go",
    "chars": 1517,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/compare.go",
    "chars": 3723,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/config.go",
    "chars": 2845,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/doc.go",
    "chars": 3334,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/kv.go",
    "chars": 5720,
    "preview": "// Copyright 2015 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/lease.go",
    "chars": 15384,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/logger.go",
    "chars": 3354,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/maintenance.go",
    "chars": 6773,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/op.go",
    "chars": 17131,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/options.go",
    "chars": 1974,
    "preview": "// Copyright 2017 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/ready_wait.go",
    "chars": 955,
    "preview": "// Copyright 2017 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/retry.go",
    "chars": 17697,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/sort.go",
    "chars": 888,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  },
  {
    "path": "vendor/github.com/coreos/etcd/clientv3/txn.go",
    "chars": 3115,
    "preview": "// Copyright 2016 The etcd Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
  }
]

// ... and 1252 more files (download for full content)

About this extraction

This page contains the full source code of the etcd-io/dbtester GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1452 files (28.6 MB), approximately 7.6M tokens, and a symbol index with 85654 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!