Copy disabled (too large)
Download .txt
Showing preview only (25,557K chars total). Download the full file to get everything.
Repository: kaydxh/golang
Branch: main
Commit: 1e54c62fa5c0
Files: 1959
Total size: 124.4 MB
Directory structure:
gitextract_tcizrmu1/
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── doc/
│ ├── health_check_design.md
│ ├── opentelemetry_design.md
│ └── rate_limit_design.md
├── doc.go
├── go/
│ ├── archive/
│ │ ├── archive.go
│ │ ├── option/
│ │ │ └── file_info.go
│ │ └── zip/
│ │ ├── zip.go
│ │ └── zip_test.go
│ ├── bytes/
│ │ ├── bytes.go
│ │ └── bytes_test.go
│ ├── client/
│ │ ├── client.go
│ │ ├── client.options.go
│ │ ├── client_options.go
│ │ └── client_test.go
│ ├── container/
│ │ ├── heap/
│ │ │ ├── heap.go
│ │ │ └── heap_test.go
│ │ ├── set/
│ │ │ ├── set.go
│ │ │ ├── set.interface.go
│ │ │ ├── set_interface_test.go
│ │ │ ├── set_string.go
│ │ │ ├── set_string_test.go
│ │ │ └── set_test.go
│ │ └── workqueue/
│ │ ├── queue.go
│ │ └── queue_test.go
│ ├── context/
│ │ ├── context.go
│ │ └── context_test.go
│ ├── crypto/
│ │ ├── aes/
│ │ │ ├── aes_cbc.go
│ │ │ ├── aes_cbc_test.go
│ │ │ └── error.go
│ │ ├── md5/
│ │ │ ├── md5.go
│ │ │ └── md5_test.go
│ │ └── sha256/
│ │ ├── sha256.go
│ │ └── sha256_test.go
│ ├── doc.go
│ ├── encoding/
│ │ ├── base64/
│ │ │ ├── base64.go
│ │ │ └── base64_test.go
│ │ ├── hash/
│ │ │ ├── hash.go
│ │ │ └── hash_test.go
│ │ ├── jwt/
│ │ │ ├── jwt.go
│ │ │ └── jwt_test.go
│ │ └── protojson/
│ │ ├── decode.go
│ │ ├── decode.option.go
│ │ ├── decode_option.go
│ │ ├── encode.go
│ │ ├── encode.option.go
│ │ ├── encode_option.go
│ │ ├── protojson_test.go
│ │ └── testdata/
│ │ ├── date.pb.go
│ │ └── date.proto
│ ├── errors/
│ │ ├── error.code.go
│ │ ├── error.grpc.go
│ │ ├── errors.go
│ │ ├── errors_test.go
│ │ └── handler.go
│ ├── filesystem/
│ │ ├── filesystem.go
│ │ └── mountpoint.go
│ ├── flag/
│ │ └── flag.go
│ ├── go.mod
│ ├── go.sum
│ ├── idgen/
│ │ ├── id_gen.go
│ │ ├── id_gen_test.go
│ │ ├── wk_id_gen.go
│ │ └── wk_id_gen_test.go
│ ├── io/
│ │ ├── copy.go
│ │ ├── copy_darwin.go
│ │ ├── copy_linux.go
│ │ ├── copy_test.go
│ │ ├── io.go
│ │ ├── io_test.go
│ │ └── testdata/
│ │ ├── dir/
│ │ │ ├── file/
│ │ │ │ └── 1.txt
│ │ │ └── hello.text
│ │ └── file/
│ │ └── 1.txt
│ ├── math/
│ │ ├── exp/
│ │ │ ├── exp.go
│ │ │ └── exp_test.go
│ │ ├── math.go
│ │ ├── math_test.go
│ │ └── rand/
│ │ ├── rand.go
│ │ └── rand_test.go
│ ├── net/
│ │ ├── grpc/
│ │ │ ├── example/
│ │ │ │ ├── data.pb.go
│ │ │ │ ├── data.proto
│ │ │ │ ├── data.repository.go
│ │ │ │ ├── data.repository_test.go
│ │ │ │ └── data_grpc.pb.go
│ │ │ ├── grpc_client.go
│ │ │ ├── grpc_client.option.go
│ │ │ ├── grpc_client.repository.factory.go
│ │ │ ├── grpc_client.repository.go
│ │ │ ├── grpc_client_option.go
│ │ │ ├── grpc_client_test.go
│ │ │ ├── grpc_stats.handler.go
│ │ │ └── ip.go
│ │ ├── http/
│ │ │ ├── clone.go
│ │ │ ├── example/
│ │ │ │ ├── data.pb.go
│ │ │ │ ├── data.proto
│ │ │ │ └── http_client.repository_test.go
│ │ │ ├── http_client.do.go
│ │ │ ├── http_client.go
│ │ │ ├── http_client.option.go
│ │ │ ├── http_client.repository.factory.go
│ │ │ ├── http_client.repository.go
│ │ │ ├── http_client_option.go
│ │ │ ├── http_client_proxy.go
│ │ │ ├── http_client_test.go
│ │ │ ├── http_error.go
│ │ │ ├── http_handler_chain.option.go
│ │ │ ├── http_handler_interceptor.go
│ │ │ ├── http_handler_interceptor.option.go
│ │ │ ├── http_host_context.go
│ │ │ ├── http_proxy_context.go
│ │ │ ├── http_request_id.go
│ │ │ ├── http_round_trip.go
│ │ │ ├── http_transport.go
│ │ │ ├── http_transport.host.go
│ │ │ ├── http_transport.proxy.go
│ │ │ ├── ip.go
│ │ │ └── response_writer.go
│ │ ├── ip.go
│ │ ├── ip_test.go
│ │ ├── mac.go
│ │ ├── mac_test.go
│ │ ├── parse.go
│ │ ├── resolver/
│ │ │ ├── build.go
│ │ │ ├── build.option.go
│ │ │ ├── build_option.go
│ │ │ ├── dns/
│ │ │ │ ├── dns_resolver.go
│ │ │ │ ├── dns_resolver_builder.option.go
│ │ │ │ └── dns_resolver_builder_option.go
│ │ │ ├── passthrough/
│ │ │ │ └── passthrough.go
│ │ │ ├── register.reslover.go
│ │ │ ├── resolve/
│ │ │ │ └── resolve.go
│ │ │ ├── resolve.all.option.go
│ │ │ ├── resolve.all_option.go
│ │ │ ├── resolve.now_option.go
│ │ │ ├── resolve.one.option.go
│ │ │ ├── resolve.one_option.go
│ │ │ ├── resolver.go
│ │ │ ├── resolver_test.go
│ │ │ ├── target.go
│ │ │ └── unix/
│ │ │ └── unix.go
│ │ └── url/
│ │ ├── url.go
│ │ ├── url.resolve.go
│ │ ├── url_codec.go
│ │ ├── url_option.go
│ │ ├── url_test.go
│ │ └── value.go
│ ├── os/
│ │ ├── env.go
│ │ ├── env_test.go
│ │ ├── exec/
│ │ │ ├── exec.go
│ │ │ ├── exec.options.go
│ │ │ ├── exec_options.go
│ │ │ └── exec_test.go
│ │ ├── file.go
│ │ ├── file_test.go
│ │ ├── getwd.go
│ │ ├── getwd_test.go
│ │ ├── proc.go
│ │ ├── proc_darwin.go
│ │ ├── proc_linux.go
│ │ ├── proc_test.go
│ │ ├── remove_file.go
│ │ ├── signal_posix.go
│ │ ├── term/
│ │ │ └── term.go
│ │ ├── value.go
│ │ └── value_test.go
│ ├── path/
│ │ └── filepath/
│ │ ├── match.go
│ │ ├── path.go
│ │ └── path_test.go
│ ├── reflect/
│ │ ├── array.go
│ │ ├── array_test.go
│ │ ├── error.go
│ │ ├── id.go
│ │ ├── struct.go
│ │ ├── struct_test.go
│ │ ├── truncate.go
│ │ ├── truncate_test.go
│ │ ├── value.go
│ │ └── value_test.go
│ ├── runtime/
│ │ ├── extern.go
│ │ ├── extern_test.go
│ │ ├── function.go
│ │ ├── function_test.go
│ │ ├── goroutine.go
│ │ ├── marshaler/
│ │ │ ├── jsonpb.marshaler.go
│ │ │ ├── jsonpb.marshaler.option.go
│ │ │ ├── jsonpb.marshaler_option.go
│ │ │ └── proto.marshaler.go
│ │ ├── meta.data.go
│ │ ├── panic.go
│ │ ├── panic_test.go
│ │ └── stack.go
│ ├── slices/
│ │ ├── slices.go
│ │ └── slices_test.go
│ ├── strconv/
│ │ ├── atoi.go
│ │ ├── atoi_test.go
│ │ ├── atonum.go
│ │ ├── atonum_test.go
│ │ └── itoa.go
│ ├── strings/
│ │ ├── string_slice.go
│ │ ├── string_slice_test.go
│ │ ├── strings.go
│ │ └── strings_test.go
│ ├── sync/
│ │ ├── atomic/
│ │ │ ├── file_lock.go
│ │ │ └── file_lock_test.go
│ │ ├── cond.go
│ │ └── cond_test.go
│ ├── syscall/
│ │ ├── disk.go
│ │ ├── disk_test.go
│ │ ├── memory_darwin.go
│ │ ├── memory_linux.go
│ │ ├── memory_linux_test.go
│ │ ├── rlimit.go
│ │ ├── rlimit_test.go
│ │ └── syscall.go
│ ├── time/
│ │ ├── backoff.go
│ │ ├── exponential_backoff.go
│ │ ├── exponential_backoff.options.go
│ │ ├── exponential_backoff_options.go
│ │ ├── exponential_backoff_test.go
│ │ ├── exponentialbackeoff_syncmap.go
│ │ ├── rate/
│ │ │ ├── rate.go
│ │ │ ├── rate_method.go
│ │ │ ├── rate_qps.go
│ │ │ ├── rate_qps_method.go
│ │ │ ├── rate_qps_test.go
│ │ │ └── rate_test.go
│ │ ├── time.go
│ │ ├── time_counter.go
│ │ ├── time_counter_test.go
│ │ ├── time_test.go
│ │ ├── wait.go
│ │ └── wait_test.go
│ ├── unsafe/
│ │ └── unsafe.go
│ └── utils/
│ ├── compare.go
│ ├── generics_get.go
│ └── generics_get_test.go
├── go.mod
├── go.sum
├── pkg/
│ ├── binlog/
│ │ ├── binlog.archive.go
│ │ ├── binlog.go
│ │ ├── binlog.option.go
│ │ ├── binlog.pb.go
│ │ ├── binlog.proto
│ │ ├── binlog.yaml
│ │ ├── binlog_option.go
│ │ ├── binlog_test.go
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── datastore/
│ │ │ ├── data.store.go
│ │ │ ├── dbstore/
│ │ │ │ └── db.store.go
│ │ │ ├── filestore/
│ │ │ │ └── file.store.go
│ │ │ └── message.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── config/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── container/
│ │ ├── docker/
│ │ │ └── docker.proto
│ │ ├── go.mod
│ │ └── go.sum
│ ├── crontab/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── crontab.go
│ │ ├── crontab.pb.go
│ │ ├── crontab.proto
│ │ ├── crontab.yaml
│ │ ├── crontab_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── testdata/
│ │ ├── 1.txt
│ │ ├── 2.txt
│ │ └── 3.txt
│ ├── database/
│ │ ├── db.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── mysql/
│ │ │ ├── config.go
│ │ │ ├── config.option.go
│ │ │ ├── config_option.go
│ │ │ ├── migrate/
│ │ │ │ └── rename_db.sql
│ │ │ ├── mysql.go
│ │ │ ├── mysql.option.go
│ │ │ ├── mysql.pb.go
│ │ │ ├── mysql.proto
│ │ │ ├── mysql.yaml
│ │ │ ├── mysql_operate_test.go
│ │ │ ├── mysql_options.go
│ │ │ ├── mysql_test.go
│ │ │ ├── mysql_transaction.go
│ │ │ ├── sql.go
│ │ │ ├── sql_exec.go
│ │ │ ├── sql_test.go
│ │ │ └── sql_type.go
│ │ └── redis/
│ │ ├── command.get.values.go
│ │ ├── command.hset.go
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── redis.go
│ │ ├── redis.options.go
│ │ ├── redis.pb.go
│ │ ├── redis.proto
│ │ ├── redis.yaml
│ │ ├── redis_benchmark_test.go
│ │ ├── redis_hset_test.go
│ │ ├── redis_key_delete_test.go
│ │ ├── redis_key_test.go
│ │ ├── redis_list_test.go
│ │ ├── redis_options.go
│ │ ├── redis_set_test.go
│ │ ├── redis_string_test.go
│ │ ├── redis_transaction_test.go
│ │ ├── redis_type.go
│ │ └── redis_zset_test.go
│ ├── discovery/
│ │ ├── consul/
│ │ │ └── discovery.go
│ │ ├── etcd/
│ │ │ ├── config.go
│ │ │ ├── config.option.go
│ │ │ ├── config_option.go
│ │ │ ├── etcd.go
│ │ │ ├── etcd.option.go
│ │ │ ├── etcd.pb.go
│ │ │ ├── etcd.proto
│ │ │ ├── etcd.watch.go
│ │ │ ├── etcd.yaml
│ │ │ ├── etcd_options.go
│ │ │ ├── etcd_test.go
│ │ │ └── etcd_type.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── file-cleanup/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── disk/
│ │ │ ├── disk_cleaner.go
│ │ │ ├── disk_cleaner.option.go
│ │ │ ├── disk_cleaner.pb.go
│ │ │ ├── disk_cleaner.proto
│ │ │ └── disk_cleaner_option.go
│ │ ├── disk_cleaner_test.go
│ │ ├── diskcleaner.yaml
│ │ ├── file_cleaner.go
│ │ ├── file_cleaner.option.go
│ │ ├── file_cleaner_option.go
│ │ ├── file_cleaner_test.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── file-rotate/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── rotate_file.go
│ │ ├── rotate_file.option.go
│ │ ├── rotate_file_option.go
│ │ └── rotate_file_test.go
│ ├── file-transfer/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── file.transfer.go
│ │ ├── file.transfer.option.go
│ │ ├── file.transfer_option.go
│ │ ├── file.transfer_test.go
│ │ ├── ft.pb.go
│ │ ├── ft.proto
│ │ ├── ft.yaml
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── upload/
│ │ ├── upload.svr.go
│ │ └── upload.svr_test.go
│ ├── fsnotify/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── fsnotify.go
│ │ ├── fsnotify.option.go
│ │ ├── fsnotify.pb.go
│ │ ├── fsnotify.proto
│ │ ├── fsnotify.yaml
│ │ ├── fsnotify_option.go
│ │ ├── fsnotify_test.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── gocv/
│ │ ├── cgo/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── api/
│ │ │ │ └── openapi-spec/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── Makefile
│ │ │ │ ├── gocv/
│ │ │ │ │ ├── CMakeLists.txt
│ │ │ │ │ ├── gocv.magick.pb.go
│ │ │ │ │ ├── gocv.magick.pb.h
│ │ │ │ │ ├── gocv.magick.proto
│ │ │ │ │ └── libproto-gocv.a
│ │ │ │ ├── proto.gen.go
│ │ │ │ ├── scripts/
│ │ │ │ │ └── proto-gen.sh
│ │ │ │ ├── thirdparty.cmake
│ │ │ │ ├── thirdparty.srv.cmake
│ │ │ │ └── types/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── code/
│ │ │ │ │ ├── code.error.go
│ │ │ │ │ ├── sdk-go.code.pb.go
│ │ │ │ │ ├── sdk-go.code.pb.h
│ │ │ │ │ └── sdk-go.code.proto
│ │ │ │ ├── libproto-types.a
│ │ │ │ ├── sdk-go.types.pb.go
│ │ │ │ ├── sdk-go.types.pb.h
│ │ │ │ └── sdk-go.types.proto
│ │ │ ├── cmake/
│ │ │ │ └── FindProtobuf.cmake
│ │ │ ├── gocv/
│ │ │ │ ├── Makefile
│ │ │ │ ├── gocv.go
│ │ │ │ ├── gocv_test.go
│ │ │ │ ├── magick.h
│ │ │ │ ├── magick_linux_amd64.cpp
│ │ │ │ └── magick_linux_amd64.go
│ │ │ ├── pkgconfig/
│ │ │ │ ├── graphics-magick.pc
│ │ │ │ ├── opencv2.pc
│ │ │ │ ├── opencv4.pc
│ │ │ │ ├── protobuf.pc
│ │ │ │ ├── pybind11.pc
│ │ │ │ └── python3-embed.pc
│ │ │ ├── script/
│ │ │ │ └── version.sh
│ │ │ ├── swig/
│ │ │ │ ├── gocv/
│ │ │ │ │ ├── Makefile
│ │ │ │ │ ├── cgo.go
│ │ │ │ │ ├── gocv.go
│ │ │ │ │ ├── gocv.h
│ │ │ │ │ ├── gocv.swigcxx
│ │ │ │ │ ├── gocv_linux_amd64.cpp
│ │ │ │ │ ├── gocv_linux_amd64.go
│ │ │ │ │ ├── gocv_test.go
│ │ │ │ │ ├── gocv_wrap.cxx
│ │ │ │ │ └── gocv_wrap.h
│ │ │ │ ├── pycv/
│ │ │ │ │ ├── Makefile
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── cgo.go
│ │ │ │ │ ├── pycv.go
│ │ │ │ │ ├── pycv.h
│ │ │ │ │ ├── pycv.py
│ │ │ │ │ ├── pycv.swigcxx
│ │ │ │ │ ├── pycv_linux_amd64.cpp
│ │ │ │ │ ├── pycv_test.go
│ │ │ │ │ ├── pycv_wrap.cxx
│ │ │ │ │ └── pycv_wrap.h
│ │ │ │ └── types/
│ │ │ │ └── pybind11/
│ │ │ │ ├── pybind11.swigcxx
│ │ │ │ └── pybind11_mock.h
│ │ │ └── third_path/
│ │ │ ├── graphics-magick/
│ │ │ │ ├── bin/
│ │ │ │ │ ├── GraphicsMagick++-config
│ │ │ │ │ ├── GraphicsMagick-config
│ │ │ │ │ ├── GraphicsMagickWand-config
│ │ │ │ │ └── gm
│ │ │ │ ├── include/
│ │ │ │ │ ├── GraphicsMagick/
│ │ │ │ │ │ ├── Magick++/
│ │ │ │ │ │ │ ├── Blob.h
│ │ │ │ │ │ │ ├── CoderInfo.h
│ │ │ │ │ │ │ ├── Color.h
│ │ │ │ │ │ │ ├── Drawable.h
│ │ │ │ │ │ │ ├── Exception.h
│ │ │ │ │ │ │ ├── Geometry.h
│ │ │ │ │ │ │ ├── Image.h
│ │ │ │ │ │ │ ├── Include.h
│ │ │ │ │ │ │ ├── Montage.h
│ │ │ │ │ │ │ ├── Pixels.h
│ │ │ │ │ │ │ ├── STL.h
│ │ │ │ │ │ │ └── TypeMetric.h
│ │ │ │ │ │ ├── Magick++.h
│ │ │ │ │ │ ├── magick/
│ │ │ │ │ │ │ ├── analyze.h
│ │ │ │ │ │ │ ├── api.h
│ │ │ │ │ │ │ ├── attribute.h
│ │ │ │ │ │ │ ├── average.h
│ │ │ │ │ │ │ ├── blob.h
│ │ │ │ │ │ │ ├── cdl.h
│ │ │ │ │ │ │ ├── channel.h
│ │ │ │ │ │ │ ├── color.h
│ │ │ │ │ │ │ ├── color_lookup.h
│ │ │ │ │ │ │ ├── colormap.h
│ │ │ │ │ │ │ ├── colorspace.h
│ │ │ │ │ │ │ ├── command.h
│ │ │ │ │ │ │ ├── common.h
│ │ │ │ │ │ │ ├── compare.h
│ │ │ │ │ │ │ ├── composite.h
│ │ │ │ │ │ │ ├── compress.h
│ │ │ │ │ │ │ ├── confirm_access.h
│ │ │ │ │ │ │ ├── constitute.h
│ │ │ │ │ │ │ ├── decorate.h
│ │ │ │ │ │ │ ├── delegate.h
│ │ │ │ │ │ │ ├── deprecate.h
│ │ │ │ │ │ │ ├── describe.h
│ │ │ │ │ │ │ ├── draw.h
│ │ │ │ │ │ │ ├── effect.h
│ │ │ │ │ │ │ ├── enhance.h
│ │ │ │ │ │ │ ├── error.h
│ │ │ │ │ │ │ ├── forward.h
│ │ │ │ │ │ │ ├── fx.h
│ │ │ │ │ │ │ ├── gem.h
│ │ │ │ │ │ │ ├── gradient.h
│ │ │ │ │ │ │ ├── hclut.h
│ │ │ │ │ │ │ ├── image.h
│ │ │ │ │ │ │ ├── list.h
│ │ │ │ │ │ │ ├── log.h
│ │ │ │ │ │ │ ├── magic.h
│ │ │ │ │ │ │ ├── magick.h
│ │ │ │ │ │ │ ├── magick_config.h
│ │ │ │ │ │ │ ├── magick_types.h
│ │ │ │ │ │ │ ├── memory.h
│ │ │ │ │ │ │ ├── module.h
│ │ │ │ │ │ │ ├── monitor.h
│ │ │ │ │ │ │ ├── montage.h
│ │ │ │ │ │ │ ├── operator.h
│ │ │ │ │ │ │ ├── paint.h
│ │ │ │ │ │ │ ├── pixel_cache.h
│ │ │ │ │ │ │ ├── pixel_iterator.h
│ │ │ │ │ │ │ ├── plasma.h
│ │ │ │ │ │ │ ├── profile.h
│ │ │ │ │ │ │ ├── quantize.h
│ │ │ │ │ │ │ ├── random.h
│ │ │ │ │ │ │ ├── registry.h
│ │ │ │ │ │ │ ├── render.h
│ │ │ │ │ │ │ ├── resize.h
│ │ │ │ │ │ │ ├── resource.h
│ │ │ │ │ │ │ ├── shear.h
│ │ │ │ │ │ │ ├── signature.h
│ │ │ │ │ │ │ ├── statistics.h
│ │ │ │ │ │ │ ├── symbols.h
│ │ │ │ │ │ │ ├── texture.h
│ │ │ │ │ │ │ ├── timer.h
│ │ │ │ │ │ │ ├── transform.h
│ │ │ │ │ │ │ ├── type.h
│ │ │ │ │ │ │ ├── utility.h
│ │ │ │ │ │ │ └── version.h
│ │ │ │ │ │ └── wand/
│ │ │ │ │ │ ├── drawing_wand.h
│ │ │ │ │ │ ├── magick_wand.h
│ │ │ │ │ │ ├── pixel_wand.h
│ │ │ │ │ │ ├── wand_api.h
│ │ │ │ │ │ └── wand_symbols.h
│ │ │ │ │ ├── Magick++/
│ │ │ │ │ │ ├── Blob.h
│ │ │ │ │ │ ├── CoderInfo.h
│ │ │ │ │ │ ├── Color.h
│ │ │ │ │ │ ├── Drawable.h
│ │ │ │ │ │ ├── Exception.h
│ │ │ │ │ │ ├── Geometry.h
│ │ │ │ │ │ ├── Image.h
│ │ │ │ │ │ ├── Include.h
│ │ │ │ │ │ ├── Montage.h
│ │ │ │ │ │ ├── Pixels.h
│ │ │ │ │ │ ├── STL.h
│ │ │ │ │ │ └── TypeMetric.h
│ │ │ │ │ ├── Magick++.h
│ │ │ │ │ ├── magick/
│ │ │ │ │ │ ├── analyze.h
│ │ │ │ │ │ ├── api.h
│ │ │ │ │ │ ├── attribute.h
│ │ │ │ │ │ ├── average.h
│ │ │ │ │ │ ├── blob.h
│ │ │ │ │ │ ├── cdl.h
│ │ │ │ │ │ ├── channel.h
│ │ │ │ │ │ ├── color.h
│ │ │ │ │ │ ├── color_lookup.h
│ │ │ │ │ │ ├── colormap.h
│ │ │ │ │ │ ├── colorspace.h
│ │ │ │ │ │ ├── command.h
│ │ │ │ │ │ ├── common.h
│ │ │ │ │ │ ├── compare.h
│ │ │ │ │ │ ├── composite.h
│ │ │ │ │ │ ├── compress.h
│ │ │ │ │ │ ├── confirm_access.h
│ │ │ │ │ │ ├── constitute.h
│ │ │ │ │ │ ├── decorate.h
│ │ │ │ │ │ ├── delegate.h
│ │ │ │ │ │ ├── deprecate.h
│ │ │ │ │ │ ├── describe.h
│ │ │ │ │ │ ├── draw.h
│ │ │ │ │ │ ├── effect.h
│ │ │ │ │ │ ├── enhance.h
│ │ │ │ │ │ ├── error.h
│ │ │ │ │ │ ├── forward.h
│ │ │ │ │ │ ├── fx.h
│ │ │ │ │ │ ├── gem.h
│ │ │ │ │ │ ├── gradient.h
│ │ │ │ │ │ ├── hclut.h
│ │ │ │ │ │ ├── image.h
│ │ │ │ │ │ ├── list.h
│ │ │ │ │ │ ├── log.h
│ │ │ │ │ │ ├── magic.h
│ │ │ │ │ │ ├── magick.h
│ │ │ │ │ │ ├── magick_config.h
│ │ │ │ │ │ ├── magick_types.h
│ │ │ │ │ │ ├── memory.h
│ │ │ │ │ │ ├── module.h
│ │ │ │ │ │ ├── monitor.h
│ │ │ │ │ │ ├── montage.h
│ │ │ │ │ │ ├── operator.h
│ │ │ │ │ │ ├── paint.h
│ │ │ │ │ │ ├── pixel_cache.h
│ │ │ │ │ │ ├── pixel_iterator.h
│ │ │ │ │ │ ├── plasma.h
│ │ │ │ │ │ ├── profile.h
│ │ │ │ │ │ ├── quantize.h
│ │ │ │ │ │ ├── random.h
│ │ │ │ │ │ ├── registry.h
│ │ │ │ │ │ ├── render.h
│ │ │ │ │ │ ├── resize.h
│ │ │ │ │ │ ├── resource.h
│ │ │ │ │ │ ├── shear.h
│ │ │ │ │ │ ├── signature.h
│ │ │ │ │ │ ├── statistics.h
│ │ │ │ │ │ ├── symbols.h
│ │ │ │ │ │ ├── texture.h
│ │ │ │ │ │ ├── timer.h
│ │ │ │ │ │ ├── transform.h
│ │ │ │ │ │ ├── type.h
│ │ │ │ │ │ ├── utility.h
│ │ │ │ │ │ └── version.h
│ │ │ │ │ └── wand/
│ │ │ │ │ ├── drawing_wand.h
│ │ │ │ │ ├── magick_wand.h
│ │ │ │ │ ├── pixel_wand.h
│ │ │ │ │ ├── wand_api.h
│ │ │ │ │ └── wand_symbols.h
│ │ │ │ ├── lib/
│ │ │ │ │ ├── GraphicsMagick-1.3.35/
│ │ │ │ │ │ └── config/
│ │ │ │ │ │ ├── delegates.mgk
│ │ │ │ │ │ ├── type-ghostscript.mgk
│ │ │ │ │ │ ├── type-solaris.mgk
│ │ │ │ │ │ ├── type-windows.mgk
│ │ │ │ │ │ └── type.mgk
│ │ │ │ │ ├── libGraphicsMagick++.a
│ │ │ │ │ ├── libGraphicsMagick++.so.12.4.3
│ │ │ │ │ ├── libGraphicsMagick.a
│ │ │ │ │ ├── libGraphicsMagick.so.3.21.0
│ │ │ │ │ ├── libGraphicsMagickWand.a
│ │ │ │ │ ├── libGraphicsMagickWand.so.2.9.4
│ │ │ │ │ ├── libjbig.so.2.0
│ │ │ │ │ ├── libpng15.so.15
│ │ │ │ │ ├── libtiff.so.5
│ │ │ │ │ ├── libtiff.so.5.2.0
│ │ │ │ │ ├── libwebp.so.4
│ │ │ │ │ ├── libwebp.so.4.0.2
│ │ │ │ │ ├── libwebpmux.so.0
│ │ │ │ │ ├── libwebpmux.so.0.0.0
│ │ │ │ │ └── pkgconfig/
│ │ │ │ │ ├── GraphicsMagick++.pc
│ │ │ │ │ ├── GraphicsMagick.pc
│ │ │ │ │ └── GraphicsMagickWand.pc
│ │ │ │ └── share/
│ │ │ │ ├── GraphicsMagick-1.3.35/
│ │ │ │ │ └── config/
│ │ │ │ │ ├── colors.mgk
│ │ │ │ │ ├── log.mgk
│ │ │ │ │ └── modules.mgk
│ │ │ │ ├── doc/
│ │ │ │ │ └── GraphicsMagick/
│ │ │ │ │ ├── ChangeLog
│ │ │ │ │ ├── ChangeLog.2001
│ │ │ │ │ ├── ChangeLog.2002
│ │ │ │ │ ├── ChangeLog.2003
│ │ │ │ │ ├── ChangeLog.2004
│ │ │ │ │ ├── ChangeLog.2005
│ │ │ │ │ ├── ChangeLog.2006
│ │ │ │ │ ├── ChangeLog.2007
│ │ │ │ │ ├── ChangeLog.2008
│ │ │ │ │ ├── ChangeLog.2009
│ │ │ │ │ ├── ChangeLog.2010
│ │ │ │ │ ├── ChangeLog.2011
│ │ │ │ │ ├── ChangeLog.2012
│ │ │ │ │ ├── ChangeLog.2013
│ │ │ │ │ ├── ChangeLog.2014
│ │ │ │ │ ├── ChangeLog.2015
│ │ │ │ │ ├── ChangeLog.2016
│ │ │ │ │ ├── ChangeLog.2017
│ │ │ │ │ ├── ChangeLog.2018
│ │ │ │ │ ├── ChangeLog.2019
│ │ │ │ │ ├── Copyright.txt
│ │ │ │ │ ├── NEWS.txt
│ │ │ │ │ └── www/
│ │ │ │ │ ├── ChangeLog-2001.html
│ │ │ │ │ ├── ChangeLog-2002.html
│ │ │ │ │ ├── ChangeLog-2003.html
│ │ │ │ │ ├── ChangeLog-2004.html
│ │ │ │ │ ├── ChangeLog-2005.html
│ │ │ │ │ ├── ChangeLog-2006.html
│ │ │ │ │ ├── ChangeLog-2007.html
│ │ │ │ │ ├── ChangeLog-2008.html
│ │ │ │ │ ├── ChangeLog-2009.html
│ │ │ │ │ ├── ChangeLog-2010.html
│ │ │ │ │ ├── ChangeLog-2011.html
│ │ │ │ │ ├── ChangeLog-2012.html
│ │ │ │ │ ├── ChangeLog-2013.html
│ │ │ │ │ ├── ChangeLog-2014.html
│ │ │ │ │ ├── ChangeLog-2015.html
│ │ │ │ │ ├── ChangeLog-2016.html
│ │ │ │ │ ├── ChangeLog-2017.html
│ │ │ │ │ ├── ChangeLog-2018.html
│ │ │ │ │ ├── ChangeLog-2019.html
│ │ │ │ │ ├── Changelog.html
│ │ │ │ │ ├── Changes.html
│ │ │ │ │ ├── Copyright.html
│ │ │ │ │ ├── FAQ.html
│ │ │ │ │ ├── GraphicsMagick.html
│ │ │ │ │ ├── Hg.html
│ │ │ │ │ ├── INSTALL-unix.html
│ │ │ │ │ ├── INSTALL-windows.html
│ │ │ │ │ ├── ImageMagickObject.html
│ │ │ │ │ ├── Magick++/
│ │ │ │ │ │ ├── Blob.html
│ │ │ │ │ │ ├── ChangeLog.html
│ │ │ │ │ │ ├── CoderInfo.html
│ │ │ │ │ │ ├── Color.html
│ │ │ │ │ │ ├── Drawable.html
│ │ │ │ │ │ ├── Enumerations.html
│ │ │ │ │ │ ├── Exception.html
│ │ │ │ │ │ ├── FormatCharacters.html
│ │ │ │ │ │ ├── Geometry.html
│ │ │ │ │ │ ├── Image.html
│ │ │ │ │ │ ├── ImageDesign.html
│ │ │ │ │ │ ├── Montage.html
│ │ │ │ │ │ ├── PixelPacket.html
│ │ │ │ │ │ ├── Pixels.html
│ │ │ │ │ │ ├── STL.html
│ │ │ │ │ │ ├── TypeMetric.html
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── NEWS.html
│ │ │ │ │ ├── OpenMP.html
│ │ │ │ │ ├── README.html
│ │ │ │ │ ├── animate.html
│ │ │ │ │ ├── api/
│ │ │ │ │ │ ├── animate.html
│ │ │ │ │ │ ├── annotate.html
│ │ │ │ │ │ ├── api.html
│ │ │ │ │ │ ├── attribute.html
│ │ │ │ │ │ ├── average.html
│ │ │ │ │ │ ├── blob.html
│ │ │ │ │ │ ├── cdl.html
│ │ │ │ │ │ ├── channel.html
│ │ │ │ │ │ ├── color.html
│ │ │ │ │ │ ├── colormap.html
│ │ │ │ │ │ ├── compare.html
│ │ │ │ │ │ ├── composite.html
│ │ │ │ │ │ ├── confirm_access.html
│ │ │ │ │ │ ├── constitute.html
│ │ │ │ │ │ ├── decorate.html
│ │ │ │ │ │ ├── deprecate.html
│ │ │ │ │ │ ├── describe.html
│ │ │ │ │ │ ├── display.html
│ │ │ │ │ │ ├── draw.html
│ │ │ │ │ │ ├── effect.html
│ │ │ │ │ │ ├── enhance.html
│ │ │ │ │ │ ├── error.html
│ │ │ │ │ │ ├── export.html
│ │ │ │ │ │ ├── fx.html
│ │ │ │ │ │ ├── hclut.html
│ │ │ │ │ │ ├── image.html
│ │ │ │ │ │ ├── import.html
│ │ │ │ │ │ ├── list.html
│ │ │ │ │ │ ├── magick.html
│ │ │ │ │ │ ├── memory.html
│ │ │ │ │ │ ├── monitor.html
│ │ │ │ │ │ ├── montage.html
│ │ │ │ │ │ ├── operator.html
│ │ │ │ │ │ ├── paint.html
│ │ │ │ │ │ ├── pixel_cache.html
│ │ │ │ │ │ ├── pixel_iterator.html
│ │ │ │ │ │ ├── plasma.html
│ │ │ │ │ │ ├── profile.html
│ │ │ │ │ │ ├── quantize.html
│ │ │ │ │ │ ├── registry.html
│ │ │ │ │ │ ├── render.html
│ │ │ │ │ │ ├── resize.html
│ │ │ │ │ │ ├── resource.html
│ │ │ │ │ │ ├── segment.html
│ │ │ │ │ │ ├── shear.html
│ │ │ │ │ │ ├── signature.html
│ │ │ │ │ │ ├── statistics.html
│ │ │ │ │ │ ├── texture.html
│ │ │ │ │ │ ├── transform.html
│ │ │ │ │ │ ├── types.html
│ │ │ │ │ │ └── widget.html
│ │ │ │ │ ├── authors.html
│ │ │ │ │ ├── batch.html
│ │ │ │ │ ├── benchmark.html
│ │ │ │ │ ├── benchmarks.html
│ │ │ │ │ ├── bugs.html
│ │ │ │ │ ├── color.html
│ │ │ │ │ ├── compare.html
│ │ │ │ │ ├── composite.html
│ │ │ │ │ ├── conjure.html
│ │ │ │ │ ├── contribute.html
│ │ │ │ │ ├── convert.html
│ │ │ │ │ ├── display.html
│ │ │ │ │ ├── docutils-api.css
│ │ │ │ │ ├── docutils-articles.css
│ │ │ │ │ ├── download.html
│ │ │ │ │ ├── formats.html
│ │ │ │ │ ├── gm.html
│ │ │ │ │ ├── identify.html
│ │ │ │ │ ├── import.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── links.html
│ │ │ │ │ ├── magick.css
│ │ │ │ │ ├── miff.html
│ │ │ │ │ ├── mission.html
│ │ │ │ │ ├── mogrify.html
│ │ │ │ │ ├── montage.html
│ │ │ │ │ ├── motion-picture.html
│ │ │ │ │ ├── perl.html
│ │ │ │ │ ├── process.html
│ │ │ │ │ ├── programming.html
│ │ │ │ │ ├── project.html
│ │ │ │ │ ├── quantize.html
│ │ │ │ │ ├── reference.html
│ │ │ │ │ ├── security.html
│ │ │ │ │ ├── smile.c
│ │ │ │ │ ├── thanks.html
│ │ │ │ │ ├── time.html
│ │ │ │ │ ├── tools.html
│ │ │ │ │ ├── utilities.html
│ │ │ │ │ ├── version.html
│ │ │ │ │ └── wand/
│ │ │ │ │ ├── drawing_wand.html
│ │ │ │ │ ├── magick_wand.html
│ │ │ │ │ ├── pixel_wand.html
│ │ │ │ │ └── wand.html
│ │ │ │ └── man/
│ │ │ │ ├── man1/
│ │ │ │ │ ├── GraphicsMagick++-config.1
│ │ │ │ │ ├── GraphicsMagick-config.1
│ │ │ │ │ ├── GraphicsMagickWand-config.1
│ │ │ │ │ └── gm.1
│ │ │ │ ├── man4/
│ │ │ │ │ └── miff.4
│ │ │ │ └── man5/
│ │ │ │ └── quantize.5
│ │ │ ├── opencv2/
│ │ │ │ ├── include/
│ │ │ │ │ ├── opencv/
│ │ │ │ │ │ ├── cv.h
│ │ │ │ │ │ ├── cv.hpp
│ │ │ │ │ │ ├── cvaux.h
│ │ │ │ │ │ ├── cvaux.hpp
│ │ │ │ │ │ ├── cvwimage.h
│ │ │ │ │ │ ├── cxcore.h
│ │ │ │ │ │ ├── cxcore.hpp
│ │ │ │ │ │ ├── cxeigen.hpp
│ │ │ │ │ │ ├── cxmisc.h
│ │ │ │ │ │ ├── highgui.h
│ │ │ │ │ │ └── ml.h
│ │ │ │ │ └── opencv2/
│ │ │ │ │ ├── calib3d/
│ │ │ │ │ │ └── calib3d.hpp
│ │ │ │ │ ├── contrib/
│ │ │ │ │ │ ├── contrib.hpp
│ │ │ │ │ │ ├── detection_based_tracker.hpp
│ │ │ │ │ │ ├── hybridtracker.hpp
│ │ │ │ │ │ ├── openfabmap.hpp
│ │ │ │ │ │ └── retina.hpp
│ │ │ │ │ ├── features2d/
│ │ │ │ │ │ └── features2d.hpp
│ │ │ │ │ ├── flann/
│ │ │ │ │ │ ├── all_indices.h
│ │ │ │ │ │ ├── allocator.h
│ │ │ │ │ │ ├── any.h
│ │ │ │ │ │ ├── autotuned_index.h
│ │ │ │ │ │ ├── composite_index.h
│ │ │ │ │ │ ├── config.h
│ │ │ │ │ │ ├── defines.h
│ │ │ │ │ │ ├── dist.h
│ │ │ │ │ │ ├── dummy.h
│ │ │ │ │ │ ├── dynamic_bitset.h
│ │ │ │ │ │ ├── flann.hpp
│ │ │ │ │ │ ├── flann_base.hpp
│ │ │ │ │ │ ├── general.h
│ │ │ │ │ │ ├── ground_truth.h
│ │ │ │ │ │ ├── hdf5.h
│ │ │ │ │ │ ├── heap.h
│ │ │ │ │ │ ├── hierarchical_clustering_index.h
│ │ │ │ │ │ ├── index_testing.h
│ │ │ │ │ │ ├── kdtree_index.h
│ │ │ │ │ │ ├── kdtree_single_index.h
│ │ │ │ │ │ ├── kmeans_index.h
│ │ │ │ │ │ ├── linear_index.h
│ │ │ │ │ │ ├── logger.h
│ │ │ │ │ │ ├── lsh_index.h
│ │ │ │ │ │ ├── lsh_table.h
│ │ │ │ │ │ ├── matrix.h
│ │ │ │ │ │ ├── miniflann.hpp
│ │ │ │ │ │ ├── nn_index.h
│ │ │ │ │ │ ├── object_factory.h
│ │ │ │ │ │ ├── params.h
│ │ │ │ │ │ ├── random.h
│ │ │ │ │ │ ├── result_set.h
│ │ │ │ │ │ ├── sampling.h
│ │ │ │ │ │ ├── saving.h
│ │ │ │ │ │ ├── simplex_downhill.h
│ │ │ │ │ │ └── timer.h
│ │ │ │ │ ├── gpu/
│ │ │ │ │ │ ├── device/
│ │ │ │ │ │ │ ├── block.hpp
│ │ │ │ │ │ │ ├── border_interpolate.hpp
│ │ │ │ │ │ │ ├── color.hpp
│ │ │ │ │ │ │ ├── common.hpp
│ │ │ │ │ │ │ ├── datamov_utils.hpp
│ │ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ │ ├── color_detail.hpp
│ │ │ │ │ │ │ │ ├── reduce.hpp
│ │ │ │ │ │ │ │ ├── reduce_key_val.hpp
│ │ │ │ │ │ │ │ ├── transform_detail.hpp
│ │ │ │ │ │ │ │ ├── type_traits_detail.hpp
│ │ │ │ │ │ │ │ └── vec_distance_detail.hpp
│ │ │ │ │ │ │ ├── dynamic_smem.hpp
│ │ │ │ │ │ │ ├── emulation.hpp
│ │ │ │ │ │ │ ├── filters.hpp
│ │ │ │ │ │ │ ├── funcattrib.hpp
│ │ │ │ │ │ │ ├── functional.hpp
│ │ │ │ │ │ │ ├── limits.hpp
│ │ │ │ │ │ │ ├── reduce.hpp
│ │ │ │ │ │ │ ├── saturate_cast.hpp
│ │ │ │ │ │ │ ├── scan.hpp
│ │ │ │ │ │ │ ├── simd_functions.hpp
│ │ │ │ │ │ │ ├── static_check.hpp
│ │ │ │ │ │ │ ├── transform.hpp
│ │ │ │ │ │ │ ├── type_traits.hpp
│ │ │ │ │ │ │ ├── utility.hpp
│ │ │ │ │ │ │ ├── vec_distance.hpp
│ │ │ │ │ │ │ ├── vec_math.hpp
│ │ │ │ │ │ │ ├── vec_traits.hpp
│ │ │ │ │ │ │ ├── warp.hpp
│ │ │ │ │ │ │ ├── warp_reduce.hpp
│ │ │ │ │ │ │ └── warp_shuffle.hpp
│ │ │ │ │ │ ├── devmem2d.hpp
│ │ │ │ │ │ ├── gpu.hpp
│ │ │ │ │ │ ├── gpumat.hpp
│ │ │ │ │ │ └── stream_accessor.hpp
│ │ │ │ │ ├── highgui/
│ │ │ │ │ │ ├── cap_ios.h
│ │ │ │ │ │ ├── highgui.hpp
│ │ │ │ │ │ ├── highgui_c.h
│ │ │ │ │ │ └── ios.h
│ │ │ │ │ ├── imgproc/
│ │ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ │ ├── imgproc_c.h
│ │ │ │ │ │ └── types_c.h
│ │ │ │ │ ├── legacy/
│ │ │ │ │ │ ├── blobtrack.hpp
│ │ │ │ │ │ ├── compat.hpp
│ │ │ │ │ │ ├── legacy.hpp
│ │ │ │ │ │ └── streams.hpp
│ │ │ │ │ ├── ml/
│ │ │ │ │ │ └── ml.hpp
│ │ │ │ │ ├── nonfree/
│ │ │ │ │ │ ├── features2d.hpp
│ │ │ │ │ │ ├── gpu.hpp
│ │ │ │ │ │ ├── nonfree.hpp
│ │ │ │ │ │ └── ocl.hpp
│ │ │ │ │ ├── objdetect/
│ │ │ │ │ │ └── objdetect.hpp
│ │ │ │ │ ├── ocl/
│ │ │ │ │ │ ├── matrix_operations.hpp
│ │ │ │ │ │ └── ocl.hpp
│ │ │ │ │ ├── opencv.hpp
│ │ │ │ │ ├── opencv_modules.hpp
│ │ │ │ │ ├── photo/
│ │ │ │ │ │ ├── photo.hpp
│ │ │ │ │ │ └── photo_c.h
│ │ │ │ │ ├── stitching/
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ ├── autocalib.hpp
│ │ │ │ │ │ │ ├── blenders.hpp
│ │ │ │ │ │ │ ├── camera.hpp
│ │ │ │ │ │ │ ├── exposure_compensate.hpp
│ │ │ │ │ │ │ ├── matchers.hpp
│ │ │ │ │ │ │ ├── motion_estimators.hpp
│ │ │ │ │ │ │ ├── seam_finders.hpp
│ │ │ │ │ │ │ ├── util.hpp
│ │ │ │ │ │ │ ├── util_inl.hpp
│ │ │ │ │ │ │ ├── warpers.hpp
│ │ │ │ │ │ │ └── warpers_inl.hpp
│ │ │ │ │ │ ├── stitcher.hpp
│ │ │ │ │ │ └── warpers.hpp
│ │ │ │ │ ├── superres/
│ │ │ │ │ │ ├── optical_flow.hpp
│ │ │ │ │ │ └── superres.hpp
│ │ │ │ │ ├── ts/
│ │ │ │ │ │ ├── gpu_perf.hpp
│ │ │ │ │ │ ├── gpu_test.hpp
│ │ │ │ │ │ ├── ts.hpp
│ │ │ │ │ │ ├── ts_gtest.h
│ │ │ │ │ │ └── ts_perf.hpp
│ │ │ │ │ ├── video/
│ │ │ │ │ │ ├── background_segm.hpp
│ │ │ │ │ │ ├── tracking.hpp
│ │ │ │ │ │ └── video.hpp
│ │ │ │ │ └── videostab/
│ │ │ │ │ ├── deblurring.hpp
│ │ │ │ │ ├── fast_marching.hpp
│ │ │ │ │ ├── fast_marching_inl.hpp
│ │ │ │ │ ├── frame_source.hpp
│ │ │ │ │ ├── global_motion.hpp
│ │ │ │ │ ├── inpainting.hpp
│ │ │ │ │ ├── log.hpp
│ │ │ │ │ ├── motion_stabilizing.hpp
│ │ │ │ │ ├── optical_flow.hpp
│ │ │ │ │ ├── stabilizer.hpp
│ │ │ │ │ └── videostab.hpp
│ │ │ │ ├── lib/
│ │ │ │ │ ├── libIlmImf.a
│ │ │ │ │ ├── libjpeg.a
│ │ │ │ │ ├── libjpeg.so.62.3.0
│ │ │ │ │ ├── liblibjasper.a
│ │ │ │ │ ├── liblibpng.a
│ │ │ │ │ ├── liblibtiff.a
│ │ │ │ │ ├── libopencv_calib3d.so.2.4.12
│ │ │ │ │ ├── libopencv_contrib.so.2.4.12
│ │ │ │ │ ├── libopencv_core.so.2.4.12
│ │ │ │ │ ├── libopencv_features2d.so.2.4.12
│ │ │ │ │ ├── libopencv_flann.so.2.4.12
│ │ │ │ │ ├── libopencv_gpu.so.2.4.12
│ │ │ │ │ ├── libopencv_highgui.so.2.4.12
│ │ │ │ │ ├── libopencv_imgproc.so.2.4.12
│ │ │ │ │ ├── libopencv_legacy.so.2.4.12
│ │ │ │ │ ├── libopencv_ml.so.2.4.12
│ │ │ │ │ ├── libopencv_nonfree.so.2.4.12
│ │ │ │ │ ├── libopencv_objdetect.so.2.4.12
│ │ │ │ │ ├── libopencv_ocl.so.2.4.12
│ │ │ │ │ ├── libopencv_photo.so.2.4.12
│ │ │ │ │ ├── libopencv_stitching.so.2.4.12
│ │ │ │ │ ├── libopencv_superres.so.2.4.12
│ │ │ │ │ ├── libopencv_ts.a
│ │ │ │ │ ├── libopencv_video.so.2.4.12
│ │ │ │ │ ├── libopencv_videostab.so.2.4.12
│ │ │ │ │ ├── libturbojpeg.a
│ │ │ │ │ ├── libturbojpeg.so.0.2.0
│ │ │ │ │ └── pkgconfig/
│ │ │ │ │ └── opencv.pc
│ │ │ │ └── version.txt
│ │ │ ├── opencv4/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── include/
│ │ │ │ │ └── opencv2/
│ │ │ │ │ ├── calib3d/
│ │ │ │ │ │ ├── calib3d.hpp
│ │ │ │ │ │ └── calib3d_c.h
│ │ │ │ │ ├── calib3d.hpp
│ │ │ │ │ ├── core/
│ │ │ │ │ │ ├── affine.hpp
│ │ │ │ │ │ ├── async.hpp
│ │ │ │ │ │ ├── base.hpp
│ │ │ │ │ │ ├── bindings_utils.hpp
│ │ │ │ │ │ ├── bufferpool.hpp
│ │ │ │ │ │ ├── check.hpp
│ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ ├── core_c.h
│ │ │ │ │ │ ├── cuda/
│ │ │ │ │ │ │ ├── block.hpp
│ │ │ │ │ │ │ ├── border_interpolate.hpp
│ │ │ │ │ │ │ ├── color.hpp
│ │ │ │ │ │ │ ├── common.hpp
│ │ │ │ │ │ │ ├── datamov_utils.hpp
│ │ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ │ ├── color_detail.hpp
│ │ │ │ │ │ │ │ ├── reduce.hpp
│ │ │ │ │ │ │ │ ├── reduce_key_val.hpp
│ │ │ │ │ │ │ │ ├── transform_detail.hpp
│ │ │ │ │ │ │ │ ├── type_traits_detail.hpp
│ │ │ │ │ │ │ │ └── vec_distance_detail.hpp
│ │ │ │ │ │ │ ├── dynamic_smem.hpp
│ │ │ │ │ │ │ ├── emulation.hpp
│ │ │ │ │ │ │ ├── filters.hpp
│ │ │ │ │ │ │ ├── funcattrib.hpp
│ │ │ │ │ │ │ ├── functional.hpp
│ │ │ │ │ │ │ ├── limits.hpp
│ │ │ │ │ │ │ ├── reduce.hpp
│ │ │ │ │ │ │ ├── saturate_cast.hpp
│ │ │ │ │ │ │ ├── scan.hpp
│ │ │ │ │ │ │ ├── simd_functions.hpp
│ │ │ │ │ │ │ ├── transform.hpp
│ │ │ │ │ │ │ ├── type_traits.hpp
│ │ │ │ │ │ │ ├── utility.hpp
│ │ │ │ │ │ │ ├── vec_distance.hpp
│ │ │ │ │ │ │ ├── vec_math.hpp
│ │ │ │ │ │ │ ├── vec_traits.hpp
│ │ │ │ │ │ │ ├── warp.hpp
│ │ │ │ │ │ │ ├── warp_reduce.hpp
│ │ │ │ │ │ │ └── warp_shuffle.hpp
│ │ │ │ │ │ ├── cuda.hpp
│ │ │ │ │ │ ├── cuda.inl.hpp
│ │ │ │ │ │ ├── cuda_stream_accessor.hpp
│ │ │ │ │ │ ├── cuda_types.hpp
│ │ │ │ │ │ ├── cv_cpu_dispatch.h
│ │ │ │ │ │ ├── cv_cpu_helper.h
│ │ │ │ │ │ ├── cvdef.h
│ │ │ │ │ │ ├── cvstd.hpp
│ │ │ │ │ │ ├── cvstd.inl.hpp
│ │ │ │ │ │ ├── cvstd_wrapper.hpp
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ ├── async_promise.hpp
│ │ │ │ │ │ │ └── exception_ptr.hpp
│ │ │ │ │ │ ├── directx.hpp
│ │ │ │ │ │ ├── dualquaternion.hpp
│ │ │ │ │ │ ├── dualquaternion.inl.hpp
│ │ │ │ │ │ ├── eigen.hpp
│ │ │ │ │ │ ├── fast_math.hpp
│ │ │ │ │ │ ├── hal/
│ │ │ │ │ │ │ ├── hal.hpp
│ │ │ │ │ │ │ ├── interface.h
│ │ │ │ │ │ │ ├── intrin.hpp
│ │ │ │ │ │ │ ├── intrin_avx.hpp
│ │ │ │ │ │ │ ├── intrin_avx512.hpp
│ │ │ │ │ │ │ ├── intrin_cpp.hpp
│ │ │ │ │ │ │ ├── intrin_forward.hpp
│ │ │ │ │ │ │ ├── intrin_msa.hpp
│ │ │ │ │ │ │ ├── intrin_neon.hpp
│ │ │ │ │ │ │ ├── intrin_rvv.hpp
│ │ │ │ │ │ │ ├── intrin_rvv071.hpp
│ │ │ │ │ │ │ ├── intrin_sse.hpp
│ │ │ │ │ │ │ ├── intrin_sse_em.hpp
│ │ │ │ │ │ │ ├── intrin_vsx.hpp
│ │ │ │ │ │ │ ├── intrin_wasm.hpp
│ │ │ │ │ │ │ ├── msa_macros.h
│ │ │ │ │ │ │ └── simd_utils.impl.hpp
│ │ │ │ │ │ ├── mat.hpp
│ │ │ │ │ │ ├── mat.inl.hpp
│ │ │ │ │ │ ├── matx.hpp
│ │ │ │ │ │ ├── neon_utils.hpp
│ │ │ │ │ │ ├── ocl.hpp
│ │ │ │ │ │ ├── ocl_genbase.hpp
│ │ │ │ │ │ ├── opencl/
│ │ │ │ │ │ │ ├── ocl_defs.hpp
│ │ │ │ │ │ │ ├── opencl_info.hpp
│ │ │ │ │ │ │ ├── opencl_svm.hpp
│ │ │ │ │ │ │ └── runtime/
│ │ │ │ │ │ │ ├── autogenerated/
│ │ │ │ │ │ │ │ ├── opencl_clblas.hpp
│ │ │ │ │ │ │ │ ├── opencl_clfft.hpp
│ │ │ │ │ │ │ │ ├── opencl_core.hpp
│ │ │ │ │ │ │ │ ├── opencl_core_wrappers.hpp
│ │ │ │ │ │ │ │ ├── opencl_gl.hpp
│ │ │ │ │ │ │ │ └── opencl_gl_wrappers.hpp
│ │ │ │ │ │ │ ├── opencl_clblas.hpp
│ │ │ │ │ │ │ ├── opencl_clfft.hpp
│ │ │ │ │ │ │ ├── opencl_core.hpp
│ │ │ │ │ │ │ ├── opencl_core_wrappers.hpp
│ │ │ │ │ │ │ ├── opencl_gl.hpp
│ │ │ │ │ │ │ ├── opencl_gl_wrappers.hpp
│ │ │ │ │ │ │ ├── opencl_svm_20.hpp
│ │ │ │ │ │ │ ├── opencl_svm_definitions.hpp
│ │ │ │ │ │ │ └── opencl_svm_hsa_extension.hpp
│ │ │ │ │ │ ├── opengl.hpp
│ │ │ │ │ │ ├── operations.hpp
│ │ │ │ │ │ ├── optim.hpp
│ │ │ │ │ │ ├── ovx.hpp
│ │ │ │ │ │ ├── parallel/
│ │ │ │ │ │ │ ├── backend/
│ │ │ │ │ │ │ │ ├── parallel_for.openmp.hpp
│ │ │ │ │ │ │ │ └── parallel_for.tbb.hpp
│ │ │ │ │ │ │ └── parallel_backend.hpp
│ │ │ │ │ │ ├── persistence.hpp
│ │ │ │ │ │ ├── quaternion.hpp
│ │ │ │ │ │ ├── quaternion.inl.hpp
│ │ │ │ │ │ ├── saturate.hpp
│ │ │ │ │ │ ├── simd_intrinsics.hpp
│ │ │ │ │ │ ├── softfloat.hpp
│ │ │ │ │ │ ├── sse_utils.hpp
│ │ │ │ │ │ ├── traits.hpp
│ │ │ │ │ │ ├── types.hpp
│ │ │ │ │ │ ├── types_c.h
│ │ │ │ │ │ ├── utility.hpp
│ │ │ │ │ │ ├── utils/
│ │ │ │ │ │ │ ├── allocator_stats.hpp
│ │ │ │ │ │ │ ├── allocator_stats.impl.hpp
│ │ │ │ │ │ │ ├── filesystem.hpp
│ │ │ │ │ │ │ ├── instrumentation.hpp
│ │ │ │ │ │ │ ├── logger.defines.hpp
│ │ │ │ │ │ │ ├── logger.hpp
│ │ │ │ │ │ │ ├── logtag.hpp
│ │ │ │ │ │ │ ├── tls.hpp
│ │ │ │ │ │ │ └── trace.hpp
│ │ │ │ │ │ ├── va_intel.hpp
│ │ │ │ │ │ ├── version.hpp
│ │ │ │ │ │ └── vsx_utils.hpp
│ │ │ │ │ ├── core.hpp
│ │ │ │ │ ├── cvconfig.h
│ │ │ │ │ ├── dnn/
│ │ │ │ │ │ ├── all_layers.hpp
│ │ │ │ │ │ ├── dict.hpp
│ │ │ │ │ │ ├── dnn.hpp
│ │ │ │ │ │ ├── dnn.inl.hpp
│ │ │ │ │ │ ├── layer.details.hpp
│ │ │ │ │ │ ├── layer.hpp
│ │ │ │ │ │ ├── shape_utils.hpp
│ │ │ │ │ │ ├── utils/
│ │ │ │ │ │ │ └── inference_engine.hpp
│ │ │ │ │ │ └── version.hpp
│ │ │ │ │ ├── dnn.hpp
│ │ │ │ │ ├── features2d/
│ │ │ │ │ │ ├── features2d.hpp
│ │ │ │ │ │ └── hal/
│ │ │ │ │ │ └── interface.h
│ │ │ │ │ ├── features2d.hpp
│ │ │ │ │ ├── flann/
│ │ │ │ │ │ ├── all_indices.h
│ │ │ │ │ │ ├── allocator.h
│ │ │ │ │ │ ├── any.h
│ │ │ │ │ │ ├── autotuned_index.h
│ │ │ │ │ │ ├── composite_index.h
│ │ │ │ │ │ ├── config.h
│ │ │ │ │ │ ├── defines.h
│ │ │ │ │ │ ├── dist.h
│ │ │ │ │ │ ├── dummy.h
│ │ │ │ │ │ ├── dynamic_bitset.h
│ │ │ │ │ │ ├── flann.hpp
│ │ │ │ │ │ ├── flann_base.hpp
│ │ │ │ │ │ ├── general.h
│ │ │ │ │ │ ├── ground_truth.h
│ │ │ │ │ │ ├── hdf5.h
│ │ │ │ │ │ ├── heap.h
│ │ │ │ │ │ ├── hierarchical_clustering_index.h
│ │ │ │ │ │ ├── index_testing.h
│ │ │ │ │ │ ├── kdtree_index.h
│ │ │ │ │ │ ├── kdtree_single_index.h
│ │ │ │ │ │ ├── kmeans_index.h
│ │ │ │ │ │ ├── linear_index.h
│ │ │ │ │ │ ├── logger.h
│ │ │ │ │ │ ├── lsh_index.h
│ │ │ │ │ │ ├── lsh_table.h
│ │ │ │ │ │ ├── matrix.h
│ │ │ │ │ │ ├── miniflann.hpp
│ │ │ │ │ │ ├── nn_index.h
│ │ │ │ │ │ ├── object_factory.h
│ │ │ │ │ │ ├── params.h
│ │ │ │ │ │ ├── random.h
│ │ │ │ │ │ ├── result_set.h
│ │ │ │ │ │ ├── sampling.h
│ │ │ │ │ │ ├── saving.h
│ │ │ │ │ │ ├── simplex_downhill.h
│ │ │ │ │ │ └── timer.h
│ │ │ │ │ ├── flann.hpp
│ │ │ │ │ ├── gapi/
│ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ ├── cpu/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── gcpukernel.hpp
│ │ │ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ │ │ ├── stereo.hpp
│ │ │ │ │ │ │ └── video.hpp
│ │ │ │ │ │ ├── fluid/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── gfluidbuffer.hpp
│ │ │ │ │ │ │ ├── gfluidkernel.hpp
│ │ │ │ │ │ │ └── imgproc.hpp
│ │ │ │ │ │ ├── garg.hpp
│ │ │ │ │ │ ├── garray.hpp
│ │ │ │ │ │ ├── gasync_context.hpp
│ │ │ │ │ │ ├── gcall.hpp
│ │ │ │ │ │ ├── gcommon.hpp
│ │ │ │ │ │ ├── gcompiled.hpp
│ │ │ │ │ │ ├── gcompiled_async.hpp
│ │ │ │ │ │ ├── gcompoundkernel.hpp
│ │ │ │ │ │ ├── gcomputation.hpp
│ │ │ │ │ │ ├── gcomputation_async.hpp
│ │ │ │ │ │ ├── gframe.hpp
│ │ │ │ │ │ ├── gkernel.hpp
│ │ │ │ │ │ ├── gmat.hpp
│ │ │ │ │ │ ├── gmetaarg.hpp
│ │ │ │ │ │ ├── gopaque.hpp
│ │ │ │ │ │ ├── gproto.hpp
│ │ │ │ │ │ ├── gpu/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── ggpukernel.hpp
│ │ │ │ │ │ │ └── imgproc.hpp
│ │ │ │ │ │ ├── gscalar.hpp
│ │ │ │ │ │ ├── gstreaming.hpp
│ │ │ │ │ │ ├── gtransform.hpp
│ │ │ │ │ │ ├── gtype_traits.hpp
│ │ │ │ │ │ ├── gtyped.hpp
│ │ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ │ ├── infer/
│ │ │ │ │ │ │ ├── bindings_ie.hpp
│ │ │ │ │ │ │ ├── ie.hpp
│ │ │ │ │ │ │ ├── onnx.hpp
│ │ │ │ │ │ │ └── parsers.hpp
│ │ │ │ │ │ ├── infer.hpp
│ │ │ │ │ │ ├── media.hpp
│ │ │ │ │ │ ├── ocl/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── goclkernel.hpp
│ │ │ │ │ │ │ └── imgproc.hpp
│ │ │ │ │ │ ├── opencv_includes.hpp
│ │ │ │ │ │ ├── operators.hpp
│ │ │ │ │ │ ├── own/
│ │ │ │ │ │ │ ├── assert.hpp
│ │ │ │ │ │ │ ├── convert.hpp
│ │ │ │ │ │ │ ├── cvdefs.hpp
│ │ │ │ │ │ │ ├── exports.hpp
│ │ │ │ │ │ │ ├── mat.hpp
│ │ │ │ │ │ │ ├── saturate.hpp
│ │ │ │ │ │ │ ├── scalar.hpp
│ │ │ │ │ │ │ └── types.hpp
│ │ │ │ │ │ ├── plaidml/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── gplaidmlkernel.hpp
│ │ │ │ │ │ │ └── plaidml.hpp
│ │ │ │ │ │ ├── python/
│ │ │ │ │ │ │ └── python.hpp
│ │ │ │ │ │ ├── render/
│ │ │ │ │ │ │ ├── render.hpp
│ │ │ │ │ │ │ └── render_types.hpp
│ │ │ │ │ │ ├── render.hpp
│ │ │ │ │ │ ├── rmat.hpp
│ │ │ │ │ │ ├── s11n/
│ │ │ │ │ │ │ └── base.hpp
│ │ │ │ │ │ ├── s11n.hpp
│ │ │ │ │ │ ├── stereo.hpp
│ │ │ │ │ │ ├── streaming/
│ │ │ │ │ │ │ ├── cap.hpp
│ │ │ │ │ │ │ ├── desync.hpp
│ │ │ │ │ │ │ ├── format.hpp
│ │ │ │ │ │ │ ├── meta.hpp
│ │ │ │ │ │ │ ├── source.hpp
│ │ │ │ │ │ │ └── sync.hpp
│ │ │ │ │ │ ├── util/
│ │ │ │ │ │ │ ├── any.hpp
│ │ │ │ │ │ │ ├── compiler_hints.hpp
│ │ │ │ │ │ │ ├── copy_through_move.hpp
│ │ │ │ │ │ │ ├── optional.hpp
│ │ │ │ │ │ │ ├── throw.hpp
│ │ │ │ │ │ │ ├── type_traits.hpp
│ │ │ │ │ │ │ ├── util.hpp
│ │ │ │ │ │ │ └── variant.hpp
│ │ │ │ │ │ └── video.hpp
│ │ │ │ │ ├── gapi.hpp
│ │ │ │ │ ├── highgui/
│ │ │ │ │ │ ├── highgui.hpp
│ │ │ │ │ │ └── highgui_c.h
│ │ │ │ │ ├── highgui.hpp
│ │ │ │ │ ├── imgcodecs/
│ │ │ │ │ │ ├── imgcodecs.hpp
│ │ │ │ │ │ ├── imgcodecs_c.h
│ │ │ │ │ │ ├── ios.h
│ │ │ │ │ │ ├── legacy/
│ │ │ │ │ │ │ └── constants_c.h
│ │ │ │ │ │ └── macosx.h
│ │ │ │ │ ├── imgcodecs.hpp
│ │ │ │ │ ├── imgproc/
│ │ │ │ │ │ ├── bindings.hpp
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ └── gcgraph.hpp
│ │ │ │ │ │ ├── hal/
│ │ │ │ │ │ │ ├── hal.hpp
│ │ │ │ │ │ │ └── interface.h
│ │ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ │ ├── imgproc_c.h
│ │ │ │ │ │ ├── segmentation.hpp
│ │ │ │ │ │ └── types_c.h
│ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ ├── ml/
│ │ │ │ │ │ ├── ml.hpp
│ │ │ │ │ │ └── ml.inl.hpp
│ │ │ │ │ ├── ml.hpp
│ │ │ │ │ ├── objdetect/
│ │ │ │ │ │ ├── detection_based_tracker.hpp
│ │ │ │ │ │ └── objdetect.hpp
│ │ │ │ │ ├── objdetect.hpp
│ │ │ │ │ ├── opencv.hpp
│ │ │ │ │ ├── opencv_modules.hpp
│ │ │ │ │ ├── photo/
│ │ │ │ │ │ ├── cuda.hpp
│ │ │ │ │ │ ├── legacy/
│ │ │ │ │ │ │ └── constants_c.h
│ │ │ │ │ │ └── photo.hpp
│ │ │ │ │ ├── photo.hpp
│ │ │ │ │ ├── stitching/
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ ├── autocalib.hpp
│ │ │ │ │ │ │ ├── blenders.hpp
│ │ │ │ │ │ │ ├── camera.hpp
│ │ │ │ │ │ │ ├── exposure_compensate.hpp
│ │ │ │ │ │ │ ├── matchers.hpp
│ │ │ │ │ │ │ ├── motion_estimators.hpp
│ │ │ │ │ │ │ ├── seam_finders.hpp
│ │ │ │ │ │ │ ├── timelapsers.hpp
│ │ │ │ │ │ │ ├── util.hpp
│ │ │ │ │ │ │ ├── util_inl.hpp
│ │ │ │ │ │ │ ├── warpers.hpp
│ │ │ │ │ │ │ └── warpers_inl.hpp
│ │ │ │ │ │ └── warpers.hpp
│ │ │ │ │ ├── stitching.hpp
│ │ │ │ │ ├── video/
│ │ │ │ │ │ ├── background_segm.hpp
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ └── tracking.detail.hpp
│ │ │ │ │ │ ├── legacy/
│ │ │ │ │ │ │ └── constants_c.h
│ │ │ │ │ │ ├── tracking.hpp
│ │ │ │ │ │ └── video.hpp
│ │ │ │ │ ├── video.hpp
│ │ │ │ │ ├── videoio/
│ │ │ │ │ │ ├── cap_ios.h
│ │ │ │ │ │ ├── legacy/
│ │ │ │ │ │ │ └── constants_c.h
│ │ │ │ │ │ ├── registry.hpp
│ │ │ │ │ │ ├── videoio.hpp
│ │ │ │ │ │ └── videoio_c.h
│ │ │ │ │ └── videoio.hpp
│ │ │ │ └── lib64/
│ │ │ │ ├── cmake/
│ │ │ │ │ └── opencv4/
│ │ │ │ │ ├── OpenCVConfig-version.cmake
│ │ │ │ │ ├── OpenCVConfig.cmake
│ │ │ │ │ ├── OpenCVModules-release.cmake
│ │ │ │ │ └── OpenCVModules.cmake
│ │ │ │ ├── libopencv_calib3d.so.4.5.3
│ │ │ │ ├── libopencv_core.so.4.5.3
│ │ │ │ ├── libopencv_dnn.so.4.5.3
│ │ │ │ ├── libopencv_features2d.so.4.5.3
│ │ │ │ ├── libopencv_flann.so.4.5.3
│ │ │ │ ├── libopencv_gapi.so.4.5.3
│ │ │ │ ├── libopencv_highgui.so.4.5.3
│ │ │ │ ├── libopencv_imgcodecs.so.4.5.3
│ │ │ │ ├── libopencv_imgproc.so.4.5.3
│ │ │ │ ├── libopencv_ml.so.4.5.3
│ │ │ │ ├── libopencv_objdetect.so.4.5.3
│ │ │ │ ├── libopencv_photo.so.4.5.3
│ │ │ │ ├── libopencv_stitching.so.4.5.3
│ │ │ │ ├── libopencv_video.so.4.5.3
│ │ │ │ ├── libopencv_videoio.so.4.5.3
│ │ │ │ └── pkgconfig/
│ │ │ │ └── opencv4.pc
│ │ │ ├── protobuf/
│ │ │ │ ├── bin/
│ │ │ │ │ └── protoc
│ │ │ │ ├── include/
│ │ │ │ │ └── google/
│ │ │ │ │ └── protobuf/
│ │ │ │ │ ├── any.h
│ │ │ │ │ ├── any.pb.h
│ │ │ │ │ ├── any.proto
│ │ │ │ │ ├── api.pb.h
│ │ │ │ │ ├── api.proto
│ │ │ │ │ ├── arena.h
│ │ │ │ │ ├── arena_impl.h
│ │ │ │ │ ├── arenastring.h
│ │ │ │ │ ├── compiler/
│ │ │ │ │ │ ├── code_generator.h
│ │ │ │ │ │ ├── command_line_interface.h
│ │ │ │ │ │ ├── cpp/
│ │ │ │ │ │ │ └── cpp_generator.h
│ │ │ │ │ │ ├── csharp/
│ │ │ │ │ │ │ ├── csharp_generator.h
│ │ │ │ │ │ │ └── csharp_names.h
│ │ │ │ │ │ ├── importer.h
│ │ │ │ │ │ ├── java/
│ │ │ │ │ │ │ ├── java_generator.h
│ │ │ │ │ │ │ └── java_names.h
│ │ │ │ │ │ ├── js/
│ │ │ │ │ │ │ ├── js_generator.h
│ │ │ │ │ │ │ └── well_known_types_embed.h
│ │ │ │ │ │ ├── objectivec/
│ │ │ │ │ │ │ ├── objectivec_generator.h
│ │ │ │ │ │ │ └── objectivec_helpers.h
│ │ │ │ │ │ ├── parser.h
│ │ │ │ │ │ ├── php/
│ │ │ │ │ │ │ └── php_generator.h
│ │ │ │ │ │ ├── plugin.h
│ │ │ │ │ │ ├── plugin.pb.h
│ │ │ │ │ │ ├── plugin.proto
│ │ │ │ │ │ ├── python/
│ │ │ │ │ │ │ └── python_generator.h
│ │ │ │ │ │ └── ruby/
│ │ │ │ │ │ └── ruby_generator.h
│ │ │ │ │ ├── descriptor.h
│ │ │ │ │ ├── descriptor.pb.h
│ │ │ │ │ ├── descriptor.proto
│ │ │ │ │ ├── descriptor_database.h
│ │ │ │ │ ├── duration.pb.h
│ │ │ │ │ ├── duration.proto
│ │ │ │ │ ├── dynamic_message.h
│ │ │ │ │ ├── empty.pb.h
│ │ │ │ │ ├── empty.proto
│ │ │ │ │ ├── extension_set.h
│ │ │ │ │ ├── field_mask.pb.h
│ │ │ │ │ ├── field_mask.proto
│ │ │ │ │ ├── generated_enum_reflection.h
│ │ │ │ │ ├── generated_enum_util.h
│ │ │ │ │ ├── generated_message_reflection.h
│ │ │ │ │ ├── generated_message_table_driven.h
│ │ │ │ │ ├── generated_message_util.h
│ │ │ │ │ ├── has_bits.h
│ │ │ │ │ ├── implicit_weak_message.h
│ │ │ │ │ ├── inlined_string_field.h
│ │ │ │ │ ├── io/
│ │ │ │ │ │ ├── coded_stream.h
│ │ │ │ │ │ ├── gzip_stream.h
│ │ │ │ │ │ ├── printer.h
│ │ │ │ │ │ ├── strtod.h
│ │ │ │ │ │ ├── tokenizer.h
│ │ │ │ │ │ ├── zero_copy_stream.h
│ │ │ │ │ │ ├── zero_copy_stream_impl.h
│ │ │ │ │ │ └── zero_copy_stream_impl_lite.h
│ │ │ │ │ ├── map.h
│ │ │ │ │ ├── map_entry.h
│ │ │ │ │ ├── map_entry_lite.h
│ │ │ │ │ ├── map_field.h
│ │ │ │ │ ├── map_field_inl.h
│ │ │ │ │ ├── map_field_lite.h
│ │ │ │ │ ├── map_type_handler.h
│ │ │ │ │ ├── message.h
│ │ │ │ │ ├── message_lite.h
│ │ │ │ │ ├── metadata.h
│ │ │ │ │ ├── metadata_lite.h
│ │ │ │ │ ├── reflection.h
│ │ │ │ │ ├── reflection_ops.h
│ │ │ │ │ ├── repeated_field.h
│ │ │ │ │ ├── service.h
│ │ │ │ │ ├── source_context.pb.h
│ │ │ │ │ ├── source_context.proto
│ │ │ │ │ ├── struct.pb.h
│ │ │ │ │ ├── struct.proto
│ │ │ │ │ ├── stubs/
│ │ │ │ │ │ ├── bytestream.h
│ │ │ │ │ │ ├── callback.h
│ │ │ │ │ │ ├── casts.h
│ │ │ │ │ │ ├── common.h
│ │ │ │ │ │ ├── fastmem.h
│ │ │ │ │ │ ├── hash.h
│ │ │ │ │ │ ├── logging.h
│ │ │ │ │ │ ├── macros.h
│ │ │ │ │ │ ├── mutex.h
│ │ │ │ │ │ ├── once.h
│ │ │ │ │ │ ├── platform_macros.h
│ │ │ │ │ │ ├── port.h
│ │ │ │ │ │ ├── singleton.h
│ │ │ │ │ │ ├── status.h
│ │ │ │ │ │ ├── stl_util.h
│ │ │ │ │ │ ├── stringpiece.h
│ │ │ │ │ │ └── template_util.h
│ │ │ │ │ ├── text_format.h
│ │ │ │ │ ├── timestamp.pb.h
│ │ │ │ │ ├── timestamp.proto
│ │ │ │ │ ├── type.pb.h
│ │ │ │ │ ├── type.proto
│ │ │ │ │ ├── unknown_field_set.h
│ │ │ │ │ ├── util/
│ │ │ │ │ │ ├── delimited_message_util.h
│ │ │ │ │ │ ├── field_comparator.h
│ │ │ │ │ │ ├── field_mask_util.h
│ │ │ │ │ │ ├── json_util.h
│ │ │ │ │ │ ├── message_differencer.h
│ │ │ │ │ │ ├── time_util.h
│ │ │ │ │ │ ├── type_resolver.h
│ │ │ │ │ │ └── type_resolver_util.h
│ │ │ │ │ ├── wire_format.h
│ │ │ │ │ ├── wire_format_lite.h
│ │ │ │ │ ├── wire_format_lite_inl.h
│ │ │ │ │ ├── wrappers.pb.h
│ │ │ │ │ └── wrappers.proto
│ │ │ │ └── lib/
│ │ │ │ ├── libprotobuf-lite.a
│ │ │ │ ├── libprotobuf.a
│ │ │ │ ├── libprotoc.a
│ │ │ │ └── pkgconfig/
│ │ │ │ ├── protobuf-lite.pc
│ │ │ │ └── protobuf.pc
│ │ │ └── pybind11/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── LICENSE
│ │ │ ├── MANIFEST.in
│ │ │ ├── README.rst
│ │ │ ├── docs/
│ │ │ │ ├── Doxyfile
│ │ │ │ ├── Makefile
│ │ │ │ ├── _static/
│ │ │ │ │ └── css/
│ │ │ │ │ └── custom.css
│ │ │ │ ├── advanced/
│ │ │ │ │ ├── cast/
│ │ │ │ │ │ ├── chrono.rst
│ │ │ │ │ │ ├── custom.rst
│ │ │ │ │ │ ├── eigen.rst
│ │ │ │ │ │ ├── functional.rst
│ │ │ │ │ │ ├── index.rst
│ │ │ │ │ │ ├── overview.rst
│ │ │ │ │ │ ├── stl.rst
│ │ │ │ │ │ └── strings.rst
│ │ │ │ │ ├── classes.rst
│ │ │ │ │ ├── embedding.rst
│ │ │ │ │ ├── exceptions.rst
│ │ │ │ │ ├── functions.rst
│ │ │ │ │ ├── misc.rst
│ │ │ │ │ ├── pycpp/
│ │ │ │ │ │ ├── index.rst
│ │ │ │ │ │ ├── numpy.rst
│ │ │ │ │ │ ├── object.rst
│ │ │ │ │ │ └── utilities.rst
│ │ │ │ │ └── smart_ptrs.rst
│ │ │ │ ├── basics.rst
│ │ │ │ ├── benchmark.py
│ │ │ │ ├── benchmark.rst
│ │ │ │ ├── changelog.rst
│ │ │ │ ├── classes.rst
│ │ │ │ ├── cmake/
│ │ │ │ │ └── index.rst
│ │ │ │ ├── compiling.rst
│ │ │ │ ├── conf.py
│ │ │ │ ├── faq.rst
│ │ │ │ ├── index.rst
│ │ │ │ ├── installing.rst
│ │ │ │ ├── limitations.rst
│ │ │ │ ├── reference.rst
│ │ │ │ ├── release.rst
│ │ │ │ ├── requirements.txt
│ │ │ │ └── upgrade.rst
│ │ │ ├── include/
│ │ │ │ └── pybind11/
│ │ │ │ ├── attr.h
│ │ │ │ ├── buffer_info.h
│ │ │ │ ├── cast.h
│ │ │ │ ├── chrono.h
│ │ │ │ ├── common.h
│ │ │ │ ├── complex.h
│ │ │ │ ├── detail/
│ │ │ │ │ ├── class.h
│ │ │ │ │ ├── common.h
│ │ │ │ │ ├── descr.h
│ │ │ │ │ ├── init.h
│ │ │ │ │ ├── internals.h
│ │ │ │ │ ├── type_caster_base.h
│ │ │ │ │ └── typeid.h
│ │ │ │ ├── eigen/
│ │ │ │ │ ├── matrix.h
│ │ │ │ │ └── tensor.h
│ │ │ │ ├── eigen.h
│ │ │ │ ├── embed.h
│ │ │ │ ├── eval.h
│ │ │ │ ├── functional.h
│ │ │ │ ├── gil.h
│ │ │ │ ├── iostream.h
│ │ │ │ ├── numpy.h
│ │ │ │ ├── operators.h
│ │ │ │ ├── options.h
│ │ │ │ ├── pybind11.h
│ │ │ │ ├── pytypes.h
│ │ │ │ ├── stl/
│ │ │ │ │ └── filesystem.h
│ │ │ │ ├── stl.h
│ │ │ │ └── stl_bind.h
│ │ │ ├── noxfile.py
│ │ │ ├── pybind11/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ ├── _version.py
│ │ │ │ ├── commands.py
│ │ │ │ ├── py.typed
│ │ │ │ └── setup_helpers.py
│ │ │ ├── pyproject.toml
│ │ │ ├── setup.cfg
│ │ │ ├── setup.py
│ │ │ ├── tests/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── conftest.py
│ │ │ │ ├── constructor_stats.h
│ │ │ │ ├── cross_module_gil_utils.cpp
│ │ │ │ ├── cross_module_interleaved_error_already_set.cpp
│ │ │ │ ├── eigen_tensor_avoid_stl_array.cpp
│ │ │ │ ├── env.py
│ │ │ │ ├── extra_python_package/
│ │ │ │ │ ├── pytest.ini
│ │ │ │ │ └── test_files.py
│ │ │ │ ├── extra_setuptools/
│ │ │ │ │ ├── pytest.ini
│ │ │ │ │ └── test_setuphelper.py
│ │ │ │ ├── local_bindings.h
│ │ │ │ ├── object.h
│ │ │ │ ├── pybind11_cross_module_tests.cpp
│ │ │ │ ├── pybind11_tests.cpp
│ │ │ │ ├── pybind11_tests.h
│ │ │ │ ├── pytest.ini
│ │ │ │ ├── requirements.txt
│ │ │ │ ├── test_async.cpp
│ │ │ │ ├── test_async.py
│ │ │ │ ├── test_buffers.cpp
│ │ │ │ ├── test_buffers.py
│ │ │ │ ├── test_builtin_casters.cpp
│ │ │ │ ├── test_builtin_casters.py
│ │ │ │ ├── test_call_policies.cpp
│ │ │ │ ├── test_call_policies.py
│ │ │ │ ├── test_callbacks.cpp
│ │ │ │ ├── test_callbacks.py
│ │ │ │ ├── test_chrono.cpp
│ │ │ │ ├── test_chrono.py
│ │ │ │ ├── test_class.cpp
│ │ │ │ ├── test_class.py
│ │ │ │ ├── test_cmake_build/
│ │ │ │ │ ├── CMakeLists.txt
│ │ │ │ │ ├── embed.cpp
│ │ │ │ │ ├── installed_embed/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── installed_function/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── installed_target/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── main.cpp
│ │ │ │ │ ├── subdirectory_embed/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── subdirectory_function/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── subdirectory_target/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ └── test.py
│ │ │ │ ├── test_const_name.cpp
│ │ │ │ ├── test_const_name.py
│ │ │ │ ├── test_constants_and_functions.cpp
│ │ │ │ ├── test_constants_and_functions.py
│ │ │ │ ├── test_copy_move.cpp
│ │ │ │ ├── test_copy_move.py
│ │ │ │ ├── test_custom_type_casters.cpp
│ │ │ │ ├── test_custom_type_casters.py
│ │ │ │ ├── test_custom_type_setup.cpp
│ │ │ │ ├── test_custom_type_setup.py
│ │ │ │ ├── test_docstring_options.cpp
│ │ │ │ ├── test_docstring_options.py
│ │ │ │ ├── test_eigen_matrix.cpp
│ │ │ │ ├── test_eigen_matrix.py
│ │ │ │ ├── test_eigen_tensor.cpp
│ │ │ │ ├── test_eigen_tensor.inl
│ │ │ │ ├── test_eigen_tensor.py
│ │ │ │ ├── test_embed/
│ │ │ │ │ ├── CMakeLists.txt
│ │ │ │ │ ├── catch.cpp
│ │ │ │ │ ├── external_module.cpp
│ │ │ │ │ ├── test_interpreter.cpp
│ │ │ │ │ ├── test_interpreter.py
│ │ │ │ │ └── test_trampoline.py
│ │ │ │ ├── test_enum.cpp
│ │ │ │ ├── test_enum.py
│ │ │ │ ├── test_eval.cpp
│ │ │ │ ├── test_eval.py
│ │ │ │ ├── test_eval_call.py
│ │ │ │ ├── test_exceptions.cpp
│ │ │ │ ├── test_exceptions.h
│ │ │ │ ├── test_exceptions.py
│ │ │ │ ├── test_factory_constructors.cpp
│ │ │ │ ├── test_factory_constructors.py
│ │ │ │ ├── test_gil_scoped.cpp
│ │ │ │ ├── test_gil_scoped.py
│ │ │ │ ├── test_iostream.cpp
│ │ │ │ ├── test_iostream.py
│ │ │ │ ├── test_kwargs_and_defaults.cpp
│ │ │ │ ├── test_kwargs_and_defaults.py
│ │ │ │ ├── test_local_bindings.cpp
│ │ │ │ ├── test_local_bindings.py
│ │ │ │ ├── test_methods_and_attributes.cpp
│ │ │ │ ├── test_methods_and_attributes.py
│ │ │ │ ├── test_modules.cpp
│ │ │ │ ├── test_modules.py
│ │ │ │ ├── test_multiple_inheritance.cpp
│ │ │ │ ├── test_multiple_inheritance.py
│ │ │ │ ├── test_numpy_array.cpp
│ │ │ │ ├── test_numpy_array.py
│ │ │ │ ├── test_numpy_dtypes.cpp
│ │ │ │ ├── test_numpy_dtypes.py
│ │ │ │ ├── test_numpy_vectorize.cpp
│ │ │ │ ├── test_numpy_vectorize.py
│ │ │ │ ├── test_opaque_types.cpp
│ │ │ │ ├── test_opaque_types.py
│ │ │ │ ├── test_operator_overloading.cpp
│ │ │ │ ├── test_operator_overloading.py
│ │ │ │ ├── test_pickling.cpp
│ │ │ │ ├── test_pickling.py
│ │ │ │ ├── test_pytypes.cpp
│ │ │ │ ├── test_pytypes.py
│ │ │ │ ├── test_sequences_and_iterators.cpp
│ │ │ │ ├── test_sequences_and_iterators.py
│ │ │ │ ├── test_smart_ptr.cpp
│ │ │ │ ├── test_smart_ptr.py
│ │ │ │ ├── test_stl.cpp
│ │ │ │ ├── test_stl.py
│ │ │ │ ├── test_stl_binders.cpp
│ │ │ │ ├── test_stl_binders.py
│ │ │ │ ├── test_tagbased_polymorphic.cpp
│ │ │ │ ├── test_tagbased_polymorphic.py
│ │ │ │ ├── test_thread.cpp
│ │ │ │ ├── test_thread.py
│ │ │ │ ├── test_union.cpp
│ │ │ │ ├── test_union.py
│ │ │ │ ├── test_virtual_functions.cpp
│ │ │ │ ├── test_virtual_functions.py
│ │ │ │ ├── valgrind-numpy-scipy.supp
│ │ │ │ └── valgrind-python.supp
│ │ │ └── tools/
│ │ │ ├── FindCatch.cmake
│ │ │ ├── FindEigen3.cmake
│ │ │ ├── FindPythonLibsNew.cmake
│ │ │ ├── JoinPaths.cmake
│ │ │ ├── check-style.sh
│ │ │ ├── cmake_uninstall.cmake.in
│ │ │ ├── codespell_ignore_lines_from_errors.py
│ │ │ ├── libsize.py
│ │ │ ├── make_changelog.py
│ │ │ ├── pybind11.pc.in
│ │ │ ├── pybind11Common.cmake
│ │ │ ├── pybind11Config.cmake.in
│ │ │ ├── pybind11NewTools.cmake
│ │ │ ├── pybind11Tools.cmake
│ │ │ ├── pyproject.toml
│ │ │ ├── setup_global.py.in
│ │ │ └── setup_main.py.in
│ │ ├── cvtable/
│ │ │ ├── cvtable.go
│ │ │ ├── cvtable_test.go
│ │ │ └── testdata/
│ │ │ └── cvtable.conf
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── point.go
│ │ ├── rect.go
│ │ ├── rect_test.go
│ │ └── vector/
│ │ ├── vector.go
│ │ └── vector_test.go
│ ├── grpc-gateway/
│ │ ├── date/
│ │ │ ├── date.pb.go
│ │ │ ├── date.pb.gw.go
│ │ │ ├── date.proto
│ │ │ ├── date.yaml
│ │ │ └── date_grpc.pb.go
│ │ ├── gateway_handler.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── grpc_gateway.go
│ │ ├── grpc_gateway_grpc.option.go
│ │ ├── grpc_gateway_http.option.go
│ │ ├── grpc_gateway_option.go
│ │ └── grpc_gateway_test.go
│ ├── logs/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── hook.go
│ │ ├── log.go
│ │ ├── log.option.go
│ │ ├── log.pb.go
│ │ ├── log.proto
│ │ ├── log.yaml
│ │ ├── log_option.go
│ │ ├── log_test.go
│ │ ├── logrus/
│ │ │ ├── formatter.go
│ │ │ ├── glog_formatter.go
│ │ │ ├── glog_formatter_test.go
│ │ │ ├── terminal_check_bsd.go
│ │ │ ├── terminal_check_js.go
│ │ │ ├── terminal_check_notappengine.go
│ │ │ ├── terminal_check_solaris.go
│ │ │ ├── terminal_check_unix.go
│ │ │ └── terminal_check_windows.go
│ │ └── slog_test.go
│ ├── middleware/
│ │ ├── api/
│ │ │ ├── tcloud/
│ │ │ │ └── v3.0/
│ │ │ │ ├── http.interceptor.error.go
│ │ │ │ ├── interceptor.error.go
│ │ │ │ ├── jsonpb.marshaler.go
│ │ │ │ ├── tcloud.pb.go
│ │ │ │ └── tcloud.proto
│ │ │ └── trivial/
│ │ │ ├── v1/
│ │ │ │ ├── api.pb.go
│ │ │ │ ├── api.proto
│ │ │ │ ├── http.interceptor.error.go
│ │ │ │ └── interceptor.error.go
│ │ │ └── v2/
│ │ │ ├── api.pb.go
│ │ │ ├── api.proto
│ │ │ ├── http.interceptor.error.go
│ │ │ └── interceptor.error.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── grpc-middleware/
│ │ │ ├── debug/
│ │ │ │ ├── in_output_printer_client.interceptor.go
│ │ │ │ ├── in_output_printer_server.interceptor.go
│ │ │ │ └── request_id_server.interceptor.go
│ │ │ ├── opentelemetry/
│ │ │ │ ├── metric_server.interceptor.go
│ │ │ │ ├── modular_client.interceptor.go
│ │ │ │ ├── modular_server.interceptor.go
│ │ │ │ ├── trace_client.interceptor.go
│ │ │ │ └── trace_server.interceptor.go
│ │ │ ├── ratelimit/
│ │ │ │ ├── ratelimit_qps_server.interceptor.go
│ │ │ │ └── ratelimit_server.interceptor.go
│ │ │ └── timer/
│ │ │ ├── timer_client.interceptor.go
│ │ │ └── timer_server.interceptor.go
│ │ ├── http-middleware/
│ │ │ ├── cors/
│ │ │ │ ├── cors.go
│ │ │ │ └── cors_test.go
│ │ │ ├── debug/
│ │ │ │ ├── in.output_printer.go
│ │ │ │ ├── in.output_printer_truncate.go
│ │ │ │ ├── recoverer.go
│ │ │ │ └── request_id.go
│ │ │ ├── http/
│ │ │ │ ├── clean_path.go
│ │ │ │ ├── strip_prefix.go
│ │ │ │ ├── strip_prefix_test.go
│ │ │ │ └── timeout.go
│ │ │ ├── opentelemetry/
│ │ │ │ ├── metric.interceptor.go
│ │ │ │ └── trace.interceptor.go
│ │ │ ├── ratelimiter/
│ │ │ │ ├── ratelimiter.go
│ │ │ │ └── ratelimiter_qps.go
│ │ │ └── timer/
│ │ │ └── timer_server.interceptor.go
│ │ ├── local.middleware.wrap.go
│ │ └── resource/
│ │ ├── middleware.handler.go
│ │ ├── monitor.metrics.go
│ │ └── monitor.resource.go
│ ├── mq/
│ │ ├── consumer.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── kafka/
│ │ │ ├── config.go
│ │ │ ├── config.option.go
│ │ │ ├── config_option.go
│ │ │ ├── kafka.go
│ │ │ ├── kafka.option.go
│ │ │ ├── kafka.pb.go
│ │ │ ├── kafka.proto
│ │ │ ├── kafka.yaml
│ │ │ ├── kafka_consumer.go
│ │ │ ├── kafka_message.go
│ │ │ ├── kafka_option.go
│ │ │ ├── kafka_producer.go
│ │ │ └── kafka_test.go
│ │ ├── message.go
│ │ └── producer.go
│ ├── opentelemetry/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── metric/
│ │ │ ├── api/
│ │ │ │ ├── api.go
│ │ │ │ ├── example_test.go
│ │ │ │ └── instrument.go
│ │ │ ├── meter.go
│ │ │ ├── meter.logging_exporter.go
│ │ │ ├── meter.option.go
│ │ │ ├── meter.pull.exporter.go
│ │ │ ├── meter.push.exporter.go
│ │ │ ├── meter_option.go
│ │ │ ├── otlp/
│ │ │ │ ├── otlp.metric.go
│ │ │ │ ├── otlp.metric.option.go
│ │ │ │ └── otlp.metric_option.go
│ │ │ ├── prometheus/
│ │ │ │ ├── prometheus.metric.go
│ │ │ │ ├── prometheus.metric.option.go
│ │ │ │ └── prometheus.metric_option.go
│ │ │ ├── report/
│ │ │ │ ├── dimension.go
│ │ │ │ └── report.go
│ │ │ └── stdout/
│ │ │ ├── stdout.metric.go
│ │ │ ├── stdout.metric.option.go
│ │ │ └── stdout.metric_option.go
│ │ ├── opentelemetry.go
│ │ ├── opentelemetry.option.go
│ │ ├── opentelemetry.pb.go
│ │ ├── opentelemetry.proto
│ │ ├── opentelemetry.yaml
│ │ ├── opentelemetry_option.go
│ │ ├── opentelemetry_test.go
│ │ ├── resource/
│ │ │ ├── resource.go
│ │ │ ├── resource.memory.go
│ │ │ ├── resource.stats.go
│ │ │ ├── resource_stats.option.go
│ │ │ └── resource_stats_option.go
│ │ └── tracer/
│ │ ├── otlp/
│ │ │ ├── otlp.trace.go
│ │ │ └── otlp.trace.option.go
│ │ ├── stdout/
│ │ │ ├── stdout.trace.go
│ │ │ ├── stdout.trace.option.go
│ │ │ └── stdout.trace_option.go
│ │ ├── tracer.exporter.go
│ │ ├── tracer.go
│ │ ├── tracer.logging_exporter.go
│ │ ├── tracer.option.go
│ │ └── tracer_option.go
│ ├── pool/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── instance/
│ │ │ ├── call.go
│ │ │ ├── error.go
│ │ │ ├── instance.go
│ │ │ ├── pool.instance.go
│ │ │ ├── pool.instance.option.go
│ │ │ ├── pool.instance_option.go
│ │ │ ├── pool.instance_test.go
│ │ │ └── thread.go
│ │ ├── task/
│ │ │ ├── batch_process.go
│ │ │ ├── batch_process_test.go
│ │ │ ├── pool.go
│ │ │ ├── pool.option.go
│ │ │ ├── pool_options.go
│ │ │ ├── pool_test.go
│ │ │ ├── worker.go
│ │ │ └── worker_test.go
│ │ └── taskqueue/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── pool.go
│ │ ├── pool.option.go
│ │ ├── pool_option.go
│ │ ├── pool_test.go
│ │ ├── queue/
│ │ │ ├── message.go
│ │ │ ├── queue.go
│ │ │ └── redis/
│ │ │ └── queue.redis.go
│ │ ├── redis.yaml
│ │ ├── registry.go
│ │ ├── task.go
│ │ ├── tasker_syncmap.go
│ │ ├── taskq.yaml
│ │ ├── taskqueue.pb.go
│ │ └── taskqueue.proto
│ ├── profile/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── profile.go
│ │ └── profile_test.go
│ ├── protobuf/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── jsonpb/
│ │ │ ├── jsonpb_marshal.go
│ │ │ └── jsonpb_unmarshal.go
│ │ └── prototext/
│ │ └── encode.go
│ ├── proxy/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── proxy.go
│ │ ├── proxy.option.go
│ │ ├── proxy_option.go
│ │ └── proxy_test.go
│ ├── resolver/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── dns/
│ │ │ ├── dns_resolver.go
│ │ │ ├── k8s-resolver/
│ │ │ │ ├── k8s_dns_resolver.go
│ │ │ │ ├── k8s_dns_resolver_test.go
│ │ │ │ ├── k8s_resolver.option.go
│ │ │ │ └── k8s_resolver_option.go
│ │ │ └── net-resolver/
│ │ │ └── net_dns_resolver.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── resolver.go
│ │ ├── resolver.pb.go
│ │ ├── resolver.proto
│ │ ├── resolver.yaml
│ │ ├── resolver_query.option.go
│ │ ├── resolver_query_option.go
│ │ ├── resolver_test.go
│ │ └── resolverquerymap_syncmap.go
│ ├── scheduler/
│ │ ├── backend/
│ │ │ └── backend.go
│ │ ├── broker/
│ │ │ ├── broker.go
│ │ │ └── memory/
│ │ │ └── memory.go
│ │ ├── dispatcher.go
│ │ ├── dispatcher_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── server.go
│ │ ├── server_test.go
│ │ ├── task/
│ │ │ ├── result.go
│ │ │ ├── task.go
│ │ │ └── validate.go
│ │ ├── types/
│ │ │ ├── task.pb.go
│ │ │ └── task.proto
│ │ └── worker.go
│ ├── storage/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── mount/
│ │ │ ├── mount.go
│ │ │ └── mount_test.go
│ │ └── s3/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── s3.go
│ │ ├── s3.option.go
│ │ ├── s3.pb.go
│ │ ├── s3.proto
│ │ ├── s3.yaml
│ │ ├── s3_option.go
│ │ └── s3_test.go
│ ├── viper/
│ │ ├── code/
│ │ │ ├── error.template.pb.go
│ │ │ └── error.template.proto
│ │ ├── error.yaml
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── unmarshaler.go
│ │ ├── viper.go
│ │ └── viper_test.go
│ └── webserver/
│ ├── app/
│ │ ├── cmd.go
│ │ ├── flags.go
│ │ └── version.go
│ ├── config.go
│ ├── config.option.go
│ ├── config_option.go
│ ├── controller/
│ │ ├── healthz/
│ │ │ ├── checker.go
│ │ │ ├── healthz.go
│ │ │ └── healthz_test.go
│ │ ├── profiler/
│ │ │ └── profiler.go
│ │ └── static/
│ │ ├── static.go
│ │ └── static_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── hooks.go
│ ├── symbolizer.go
│ ├── webserver.go
│ ├── webserver.pb.go
│ ├── webserver.proto
│ ├── webserver.proto.go
│ ├── webserver.yaml
│ ├── webserver_qps_limit.go
│ └── webserver_test.go
├── script/
│ ├── copyright.sh
│ ├── copyright.txt
│ ├── go_proto_gen.sh
│ └── tools/
│ ├── cat.sh
│ └── dmesg.sh
├── third_party/
│ ├── README.md
│ └── github.com/
│ └── grpc-ecosystem/
│ └── grpc-gateway/
│ └── google/
│ └── api/
│ ├── annotations.proto
│ └── http.proto
└── tutorial/
└── programming_paradigm/
├── control.inverse_test.go
├── decorator_test.go
├── error.handle_test.go
├── factory_test.go
├── function.options_test.go
├── interface.check_test.go
├── interface.program_test.go
├── map.reduce_test.go
├── pipeline_test.go
└── visitor_test.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
pkg/gocv/cgo/third_path/** linguist-vendored
================================================
FILE: .gitignore
================================================
#
# NOTE! Please use 'git ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
#
# Temp files (e.g. editors).
*~
*.sw[op]
# Compiled objects.
#*.a
*.o
*.l[ao]
#*.so
*.exe
*.d
!**/tmpfiles.d
!crosh/dev.d
*.depends
.deps
.libs
*.gch
*.gcda
*.gcno
# Common output files.
*.dump
*.out
*.test
# Protobuf files.
# *.pb.cc
# *.pb.h
# Python files.
*.pyc
# Debug (e.g. gdb).
.gdb_history
.gdbinit
# xxx.core file
*.core
cscope.*
tags
tags_sorted_by_file
# Patch files.
*.diff
*.patch
*.orig
*.rej
# Nested git repos.
/glbench/images/
# Cargo lock file.
Cargo.lock
# Cargo build directories.
target/
# VSCode source dirs
.vscode/
# Intellij project dirs
.idea
# clangd cache dir
.clangd
.cache
# Other
.DS_Store
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 kay
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# golang
Golang lib is a comprehensive programming toolkit for building microservices in Go. It provides a rich set of interfaces and services to accelerate your development.
## Overview
This library offers a complete set of tools and utilities for developing Go microservices, including web servers, database connections, message queues, service discovery, monitoring, logging, and much more. It's designed to speed up development by providing production-ready components with sensible defaults.
## Features
### Core Components
- **Web Server** (`pkg/webserver`): High-performance web server built on Gin and gRPC-Gateway
- HTTP and gRPC support
- Graceful shutdown
- Health checks and profiling endpoints
- Service registry integration (Consul)
- Request/response middleware
- **Configuration** (`pkg/viper`, `pkg/config`): Flexible configuration management
- Viper integration for YAML/JSON/TOML configs
- Environment variable support
- Configuration validation
- **Logging** (`pkg/logs`): Advanced logging capabilities
- Logrus-based logging
- Log rotation (size/time-based)
- Context-aware logging with request IDs
- Multiple output formats (JSON, text)
- **Database** (`pkg/database`): Database connectivity
- MySQL support with connection pooling
- Redis client with advanced features
- Transaction management
- **Message Queue** (`pkg/mq`): Message queue integration
- Kafka producer and consumer
- Batch processing
- Error handling and retry mechanisms
- **Service Discovery** (`pkg/discovery`): Service registration and discovery
- Consul integration
- Etcd support
- Health check integration
- **Monitoring** (`pkg/monitor`): Observability tools
- OpenTelemetry integration
- Prometheus metrics
- Distributed tracing
- **Middleware** (`pkg/middleware`): HTTP and gRPC middleware
- Authentication/Authorization
- Rate limiting
- Request logging
- Error handling
- **Storage** (`pkg/storage`): Object storage support
- S3-compatible storage
- File mount utilities
- **Task Management** (`pkg/scheduler`, `pkg/crontab`, `pkg/pool`):
- Task scheduler
- Cron job support
- Connection and task pools
- Work queues
- **File Operations**:
- File rotation (`pkg/file-rotate`)
- File transfer (`pkg/file-transfer`)
- File cleanup (`pkg/file-cleanup`)
- File system monitoring (`pkg/fsnotify`)
- **gRPC Gateway** (`pkg/grpc-gateway`): RESTful API gateway for gRPC services
- **DNS Resolver** (`pkg/resolver`): Advanced DNS resolution with caching
- **Binary Log** (`pkg/binlog`): Binary log management for data replication
- **Other Utilities**:
- Proxy support (`pkg/proxy`)
- Performance profiling (`pkg/profile`)
- Protobuf utilities (`pkg/protobuf`)
- OpenCV bindings (`pkg/gocv`)
### Standard Library Enhancements (`go/`)
The `go/` directory contains enhanced versions of standard library packages with additional functionality:
- **Context**: Request ID extraction and propagation
- **Errors**: Structured error handling with codes
- **Time**: Exponential backoff, rate limiting, time utilities
- **Net**: gRPC/HTTP clients, DNS resolver, IP/MAC utilities
- **Crypto**: AES, MD5, SHA256 utilities
- **IO**: File operations, copy utilities
- **Reflect**: Advanced reflection utilities
- **Container**: Heap, Set, WorkQueue data structures
- **And more...**
### Tutorials (`tutorial/`)
Programming paradigm examples including:
- Function options pattern
- Decorator pattern
- Factory pattern
- Error handling patterns
- Pipeline pattern
- Visitor pattern
- And more...
## Quick Start
### Installation
```bash
go get github.com/kaydxh/golang
```
### Basic Web Server Example
```go
package main
import (
"context"
"testing"
viper_ "github.com/kaydxh/golang/pkg/viper"
webserver_ "github.com/kaydxh/golang/pkg/webserver"
)
func main() {
cfgFile := "./webserver.yaml"
config := webserver_.NewConfig(webserver_.WithViper(viper_.GetViper(cfgFile, "web")))
s, err := config.Complete().New(context.Background())
if err != nil {
panic(err)
}
// Install your web handlers
s.InstallWebHandlers(/* your handlers */)
prepared, err := s.PrepareRun()
if err != nil {
panic(err)
}
prepared.Run(context.Background())
}
```
### Configuration Example
Create a `webserver.yaml` file:
```yaml
web:
bind_address:
host: 0.0.0.0
port: 10000
grpc:
max_concurrency_unary: 0
max_concurrency_stream: 0
max_receive_message_size: 0
max_send_message_size: 0
timeout: 0s
http:
max_concurrency: 0
timeout: 0s
debug:
enable_profiling: true
monitor:
open_telemetry:
enabled: true
metric_collect_duration: 60s
otel_trace_exporter_type: trace_stdout
otel_metric_exporter_type: metric_stdout
```
## Package Structure
```
golang/
├── go/ # Standard library enhancements
├── pkg/ # Main packages
│ ├── webserver/ # Web server framework
│ ├── logs/ # Logging
│ ├── database/ # Database clients
│ ├── mq/ # Message queues
│ ├── discovery/ # Service discovery
│ ├── monitor/ # Monitoring
│ └── ... # Other packages
├── tutorial/ # Programming examples
└── script/ # Utility scripts
```
## Requirements
- Go 1.24.0 or higher
- See `go.mod` for specific dependency versions
## Documentation
- Each package contains detailed documentation
- Check `tutorial/` directory for usage examples
- Review package-level comments for API documentation
## Contributing
If you need support, start with your branch, and create a pull request for us. We appreciate your help!
### Development Guidelines
1. Follow Go coding standards
2. Add tests for new features
3. Update documentation
4. Ensure backward compatibility when possible
## License
See [LICENSE](LICENSE) file for details.
## Evolution
Golang started in Oct 8, 2020.
## Related Projects
This library is designed to work seamlessly with:
- Gin web framework
- gRPC
- Consul
- Etcd
- Kafka
- Prometheus
- OpenTelemetry
## Support
For issues, questions, or contributions, please open an issue or pull request on GitHub.
================================================
FILE: doc/health_check_design.md
================================================
# 健康检查增强功能设计文档
## 1. 概述
本文档描述了 golang 库中健康检查(Health Check)功能的设计思路和实现细节。该功能提供了 Kubernetes 兼容的健康检查端点,支持存活探针(Liveness)和就绪探针(Readiness),并具备良好的可扩展性。
## 2. 设计目标
- **Kubernetes 兼容**:支持标准的 `/healthz`、`/livez`、`/readyz` 端点
- **可扩展性**:通过接口抽象支持自定义健康检查器
- **组合能力**:支持聚合多个检查器,统一管理
- **优雅关闭**:关闭时先标记不就绪,允许负载均衡器排空连接
- **可观测性**:提供详细模式,返回每个检查器的状态和延迟
## 3. 架构设计
### 3.1 整体架构
```
┌─────────────────────────────────────────────────────────────┐
│ WebServer │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ HealthzController │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ livezCheckers │ │ readyzCheckers │ │ │
│ │ │ (Composite) │ │ (Composite) │ │ │
│ │ │ ┌───────────┐ │ │ ┌───────────┐ │ │ │
│ │ │ │ Ping │ │ │ │ HTTP │ │ │ │
│ │ │ ├───────────┤ │ │ ├───────────┤ │ │ │
│ │ │ │ TCP │ │ │ │ TCP │ │ │ │
│ │ │ ├───────────┤ │ │ ├───────────┤ │ │ │
│ │ │ │ Custom │ │ │ │ Custom │ │ │ │
│ │ │ └───────────┘ │ │ └───────────┘ │ │ │
│ │ └─────────────────┘ └─────────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ HTTP Endpoints: │
│ - GET /healthz 综合健康检查 │
│ - GET /livez 存活探针 │
│ - GET /readyz 就绪探针 │
│ - GET /healthz/verbose 详细健康检查结果 │
│ - GET /livez/verbose 详细存活检查结果 │
│ - GET /readyz/verbose 详细就绪检查结果 │
└─────────────────────────────────────────────────────────────┘
```
### 3.2 核心组件
| 组件 | 职责 |
|------|------|
| `HealthChecker` | 健康检查器接口,定义检查行为 |
| `CompositeHealthChecker` | 组合检查器,聚合多个检查器 |
| `Controller` | 健康检查控制器,管理端点和检查逻辑 |
| `WebServer` | 集成健康检查控制器,处理生命周期 |
## 4. 核心接口设计
### 4.1 HealthChecker 接口
```go
// HealthChecker 是健康检查的核心接口
type HealthChecker interface {
// Name 返回检查器名称,用于日志和详细结果展示
Name() string
// Check 执行健康检查,返回 nil 表示健康,返回 error 表示不健康
Check(ctx context.Context) error
}
```
### 4.2 内置检查器实现
| 检查器类型 | 用途 | 实现要点 |
|-----------|------|---------|
| `PingHealthChecker` | 基础检查,始终返回健康 | 用于默认存活检查 |
| `HTTPHealthChecker` | HTTP 端点健康检查 | 检查状态码 200-299 |
| `TCPHealthChecker` | TCP 端口连通性检查 | 使用 `net.Dialer` |
| `FuncHealthChecker` | 函数包装器 | 支持自定义检查逻辑 |
| `CompositeHealthChecker` | 组合检查器 | 聚合多个检查器 |
## 5. 关键实现
### 5.1 HTTP 健康检查器
```go
type HTTPHealthChecker struct {
name string
url string
timeout time.Duration
client *http.Client
}
func (h *HTTPHealthChecker) Check(ctx context.Context) error {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, h.url, nil)
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
resp, err := h.client.Do(req)
if err != nil {
return fmt.Errorf("failed to connect: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("unhealthy status code: %d", resp.StatusCode)
}
return nil
}
```
### 5.2 TCP 健康检查器
```go
type TCPHealthChecker struct {
name string
addr string
timeout time.Duration
}
func (t *TCPHealthChecker) Check(ctx context.Context) error {
dialer := &net.Dialer{Timeout: t.timeout}
conn, err := dialer.DialContext(ctx, "tcp", t.addr)
if err != nil {
return fmt.Errorf("failed to connect to %s: %w", t.addr, err)
}
conn.Close()
return nil
}
```
### 5.3 组合健康检查器
```go
type CompositeHealthChecker struct {
name string
mu sync.RWMutex
checkers []HealthChecker
}
func (c *CompositeHealthChecker) Check(ctx context.Context) error {
c.mu.RLock()
defer c.mu.RUnlock()
for _, checker := range c.checkers {
if err := checker.Check(ctx); err != nil {
return fmt.Errorf("%s: %w", checker.Name(), err)
}
}
return nil
}
// AddChecker 线程安全地添加检查器
func (c *CompositeHealthChecker) AddChecker(checker HealthChecker) {
c.mu.Lock()
defer c.mu.Unlock()
c.checkers = append(c.checkers, checker)
}
```
### 5.4 健康检查控制器
```go
type Controller struct {
livezCheckers *CompositeHealthChecker // 存活检查器
readyzCheckers *CompositeHealthChecker // 就绪检查器
ready atomic.Bool // 就绪状态
checkTimeout time.Duration // 检查超时(默认 10s)
}
// Healthz 综合健康检查端点
func (c *Controller) Healthz() gin.HandlerFunc {
return func(ctx *gin.Context) {
checkCtx, cancel := context.WithTimeout(ctx.Request.Context(), c.checkTimeout)
defer cancel()
// 检查存活状态
if err := c.livezCheckers.Check(checkCtx); err != nil {
ctx.JSON(http.StatusServiceUnavailable, gin.H{
"status": "unhealthy", "type": "livez", "error": err.Error(),
})
return
}
// 检查就绪状态
if !c.ready.Load() {
ctx.JSON(http.StatusServiceUnavailable, gin.H{
"status": "not ready", "type": "readyz", "error": "server is shutting down",
})
return
}
if err := c.readyzCheckers.Check(checkCtx); err != nil {
ctx.JSON(http.StatusServiceUnavailable, gin.H{
"status": "not ready", "type": "readyz", "error": err.Error(),
})
return
}
ctx.String(http.StatusOK, "ok")
}
}
```
## 6. 优雅关闭设计
### 6.1 关闭流程
```
收到关闭信号 (ctx.Done())
│
▼
标记服务为不就绪 (SetReady(false))
│
▼
/readyz 开始返回 503
│
▼
等待 ShutdownDelayDuration (允许 LB 排空连接)
│
▼
关闭 HTTP/gRPC 服务器
```
### 6.2 实现代码
```go
func (s preparedGenericWebServer) Run(ctx context.Context) error {
// ... 启动代码 ...
<-ctx.Done() // 等待关闭信号
// 1. 标记服务器为不就绪
if s.HealthzController != nil {
s.HealthzController.SetReady(false)
}
// 2. 等待关闭延迟,允许负载均衡器排空连接
if s.ShutdownDelayDuration > 0 {
time.Sleep(s.ShutdownDelayDuration)
}
// 3. 关闭服务器
// ...
}
```
## 7. 与 Consul 服务发现集成
```go
func (srv *ServiceRegistryServer) Register() error {
checkUrl := fmt.Sprintf("http://%v:%v/api/%v/v1/health",
srv.Ip, srv.Port, srv.ServiceName)
reg := &api.AgentServiceRegistration{
ID: srv.ServiceId,
Name: srv.ServiceName,
Check: &api.AgentServiceCheck{
Interval: srv.CheckInterval.String(),
HTTP: checkUrl,
DeregisterCriticalServiceAfter: srv.TTL.String(),
},
}
return agent.ServiceRegister(reg)
}
```
## 8. 使用示例
### 8.1 添加自定义检查器
```go
// 添加数据库健康检查
dbChecker := healthz.NewTCPHealthChecker("mysql", "localhost:3306", 5*time.Second)
server.HealthzController.AddReadyzChecker(dbChecker)
// 添加 Redis 健康检查
redisChecker := healthz.NewTCPHealthChecker("redis", "localhost:6379", 5*time.Second)
server.HealthzController.AddReadyzChecker(redisChecker)
// 添加自定义检查逻辑
customChecker := healthz.NewFuncHealthChecker("custom", func(ctx context.Context) error {
// 自定义检查逻辑
if someCondition {
return errors.New("unhealthy")
}
return nil
})
server.HealthzController.AddLivezChecker(customChecker)
```
### 8.2 Kubernetes 部署配置
```yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
livenessProbe:
httpGet:
path: /livez
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
```
## 9. API 响应格式
### 9.1 健康状态正常
```
GET /healthz
Response: 200 OK
Body: ok
```
### 9.2 健康状态异常
```
GET /healthz
Response: 503 Service Unavailable
Body: {"status": "unhealthy", "type": "livez", "error": "mysql: connection refused"}
```
### 9.3 详细检查结果
```
GET /healthz/verbose
Response: 200 OK
Body:
{
"status": "ok",
"livez": {
"status": "ok",
"checks": [
{"name": "ping", "status": "ok", "latency": "0.1ms"}
]
},
"readyz": {
"status": "ok",
"checks": [
{"name": "mysql", "status": "ok", "latency": "2.3ms"},
{"name": "redis", "status": "ok", "latency": "1.1ms"}
]
}
}
```
## 10. 设计特点总结
| 特点 | 说明 |
|------|------|
| Kubernetes 兼容 | 支持标准的存活/就绪探针端点 |
| 可扩展性 | 通过接口支持自定义检查器 |
| 组合模式 | 支持聚合多个检查器 |
| 详细模式 | 提供每个检查器的详细结果和延迟 |
| 优雅关闭 | 关闭时先标记不就绪 |
| 超时控制 | 默认 10 秒检查超时,可配置 |
| 线程安全 | 使用互斥锁和原子操作保证并发安全 |
| 服务发现集成 | 支持 Consul HTTP 健康检查 |
## 11. 文件结构
```
pkg/webserver/controller/healthz/
├── checker.go # 健康检查器接口和实现
├── healthz.go # 健康检查控制器
└── healthz_test.go # 单元测试
pkg/webserver/
├── webserver.go # WebServer 集成健康检查
└── config.go # 配置和初始化
pkg/discovery/consul/
└── discovery.go # Consul 服务注册健康检查
```
================================================
FILE: doc/opentelemetry_design.md
================================================
# OpenTelemetry 监控设计文档
## 1. 概述
本文档描述了 golang 库中 OpenTelemetry 监控功能的设计思路和实现细节。该功能提供统一的可观测性能力,支持 **Metrics(指标)**、**Traces(链路追踪)** 和 **Logs(日志)**,并支持多种后端导出器(Prometheus、Jaeger、OTLP 等)。
## 2. 设计目标
- **统一的可观测性**:通过 OpenTelemetry 标准实现 Metrics、Traces、Logs 的统一采集
- **多后端支持**:支持 Prometheus、Jaeger、OTLP、Stdout 等多种导出器
- **腾讯云兼容**:支持腾讯云 Prometheus Remote Write 接入
- **配置驱动**:通过 YAML 配置文件灵活配置各种导出器
- **低侵入性**:通过中间件自动采集 gRPC/HTTP 请求指标和链路追踪
## 3. 架构设计
### 3.1 整体架构
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 应用层 │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ gRPC/HTTP Server │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌───────────────┐ │ │
│ │ │ Metric 中间件 │ │ Trace 中间件 │ │ 业务代码 │ │ │
│ │ └────────┬────────┘ └────────┬────────┘ └───────────────┘ │ │
│ └───────────│──────────────────────│────────────────────────────────┘ │
└──────────────│──────────────────────│──────────────────────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ OpenTelemetry SDK 层 │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ OpenTelemetryService │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ MeterProvider │ │ TracerProvider │ │ │
│ │ │ ┌───────────┐ │ │ ┌───────────┐ │ │ │
│ │ │ │ Reader │ │ │ │ Exporter │ │ │ │
│ │ │ └───────────┘ │ │ └───────────┘ │ │ │
│ │ └─────────────────┘ └─────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 导出器层 (Exporter) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Prometheus │ │ OTLP │ │ Jaeger │ │ Stdout │ │
│ │ (Pull) │ │ (Push) │ │ (Push) │ │ (Push) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
└─────────│────────────────│────────────────│────────────────│──────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 后端存储层 │
│ ┌─────────────┐ ┌─────────────────────┐ ┌─────────────┐ │
│ │ Prometheus │ │ 腾讯云 Prometheus │ │ Jaeger │ │
│ │ Server │ │ Remote Write │ │ Server │ │
│ └─────────────┘ └─────────────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
```
### 3.2 核心组件
| 组件 | 职责 |
|------|------|
| `OpenTelemetryService` | 统一管理 Meter 和 Tracer 的生命周期 |
| `MeterProvider` | 管理指标的采集和导出 |
| `TracerProvider` | 管理链路追踪的采集和导出 |
| `PullExporter` | Pull 模式导出器(如 Prometheus) |
| `PushExporter` | Push 模式导出器(如 OTLP、Jaeger、Stdout) |
| `ResourceStatsService` | 资源统计服务(CPU、内存等) |
## 4. 指标采集模式
### 4.1 Pull 模式 vs Push 模式
```
┌─────────────────────────────────────────────────────────────────────────┐
│ Pull 模式 (Prometheus) │
│ │
│ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 服务 │ ──────── /metrics ───────→ │ Prometheus │ │
│ │ (暴露端口) │ ←─────── 主动抓取 ────────│ Server │ │
│ └─────────────┘ └─────────────────────┘ │
│ │
│ 特点:服务暴露端口,Prometheus 主动拉取 │
│ 适用:同 VPC、K8s 内部、ServiceMonitor │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ Push 模式 (OTLP) │
│ │
│ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 服务 │ ──────── 主动推送 ───────→ │ 腾讯云 Prometheus │ │
│ │ (定时推送) │ │ Remote Write │ │
│ └─────────────┘ └─────────────────────┘ │
│ │
│ 特点:服务主动推送,无需暴露端口 │
│ 适用:跨 VPC、公网、防火墙限制场景 │
└─────────────────────────────────────────────────────────────────────────┘
```
### 4.2 模式对比
| 特性 | Pull 模式 (Prometheus) | Push 模式 (OTLP) |
|------|------------------------|------------------|
| **数据流向** | 后端主动拉取服务 | 服务主动推送到后端 |
| **端口暴露** | 需要暴露 `/metrics` 端点 | 无需暴露端口 |
| **网络要求** | Prometheus 需能访问服务 | 服务需能访问采集端 |
| **适用场景** | 同 VPC、K8s ServiceMonitor | 跨 VPC、无法暴露端口 |
| **配置类型** | `metric_prometheus` | `metric_otlp` |
| **Exporter** | `WithMeterPullExporter` | `WithMeterPushExporter` |
### 4.3 选择建议
| 场景 | 推荐模式 | 原因 |
|------|---------|------|
| K8s 集群内部 | Pull (Prometheus) | Prometheus Operator 原生支持 ServiceMonitor |
| 同 VPC 部署 | Pull (Prometheus) | 网络直连,配置简单 |
| 跨 VPC / 公网 | Push (OTLP) | 无需暴露端口,穿透防火墙 |
| 边缘节点 | Push (OTLP) | 边缘网络不稳定,主动推送更可靠 |
| 腾讯云托管 Prometheus | 两者皆可 | 根据网络拓扑选择 |
## 5. 配置设计
### 5.1 配置结构 (Proto 定义)
```protobuf
message OpenTelemetry {
bool enabled = 1;
google.protobuf.Duration metric_collect_duration = 2; // 指标采集周期
OtelTraceExporterType otel_trace_exporter_type = 3; // 链路导出器类型
OtelMetricExporterType otel_metric_exporter_type = 4; // 指标导出器类型
OtelLogExporterType otel_log_exporter_type = 5; // 日志导出器类型
OtelMetricExporter otel_metric_exporter = 6; // 指标导出器配置
OtelTraceExporter otel_trace_exporter = 7; // 链路导出器配置
Resource resource = 8; // 资源标识
}
// 指标导出器配置
message OtelMetricExporter {
Prometheus prometheus = 1; // Prometheus Pull 模式
Stdout stdout = 2; // 标准输出
OTLP otlp = 3; // OTLP Push 模式
}
// OTLP 导出器配置
message OTLP {
string endpoint = 1; // 目标地址
string token = 2; // 认证 Token
string protocol = 3; // 协议:http 或 grpc
bool insecure = 4; // 是否禁用 TLS
map<string, string> headers = 5; // 自定义请求头
string url_path = 6; // HTTP URL 路径
}
```
### 5.2 导出器类型枚举
```protobuf
enum OtelMetricExporterType {
metric_none = 0; // 不启用
metric_prometheus = 1; // Prometheus Pull 模式
metric_stdout = 2; // 标准输出
metric_otlp = 3; // OTLP Push 模式
}
enum OtelTraceExporterType {
trace_none = 0; // 不启用
trace_jaeger = 1; // Jaeger
trace_stdout = 2; // 标准输出
trace_otlp = 3; // OTLP Push 模式
}
```
### 5.3 配置示例
#### Prometheus Pull 模式(同 VPC)
```yaml
open_telemetry:
enabled: true
metric_collect_duration: 60s
otel_metric_exporter_type: metric_prometheus
otel_trace_exporter_type: trace_jaeger
otel_metric_exporter:
prometheus:
url: /metrics # 暴露的端点路径
otel_trace_exporter:
jaeger:
url: http://jaeger:14268/api/traces
resource:
service_name: "my-service"
attrs:
env: "production"
```
#### OTLP Push 模式(腾讯云 Prometheus)
```yaml
open_telemetry:
enabled: true
metric_collect_duration: 60s
otel_metric_exporter_type: metric_otlp
otel_trace_exporter_type: trace_stdout
otel_metric_exporter:
otlp:
# 腾讯云 Prometheus Remote Write 地址(从控制台获取)
endpoint: "your-instance.tencentcloudprom.com"
# 认证 Token(从控制台获取)
token: "your-prometheus-token"
# 协议:http 或 grpc
protocol: "http"
# 内网访问可设为 true,公网访问设为 false
insecure: false
# OTLP 默认路径
url_path: "/v1/metrics"
resource:
service_name: "my-service"
attrs:
env: "production"
region: "ap-guangzhou"
```
## 6. 核心实现
### 6.1 OTLP Exporter 实现
```go
// OTLPExporterBuilder OTLP 导出器构建器
type OTLPExporterBuilder struct {
opts struct {
endpoint string // 目标地址
headers map[string]string // 请求头
timeout time.Duration // 超时时间
insecure bool // 是否禁用 TLS
protocol Protocol // 协议类型
urlPath string // URL 路径
}
}
// Protocol 协议类型
type Protocol int
const (
ProtocolHTTP Protocol = iota // HTTP 协议
ProtocolGRPC // gRPC 协议
)
// Build 构建 OTLP Exporter
func (b *OTLPExporterBuilder) Build(ctx context.Context) (metric.Exporter, error) {
switch b.opts.protocol {
case ProtocolHTTP:
return b.buildHTTPExporter(ctx)
case ProtocolGRPC:
return b.buildGRPCExporter(ctx)
default:
return b.buildHTTPExporter(ctx)
}
}
// buildHTTPExporter 构建 HTTP 导出器
func (b *OTLPExporterBuilder) buildHTTPExporter(ctx context.Context) (metric.Exporter, error) {
opts := []otlpmetrichttp.Option{
otlpmetrichttp.WithEndpoint(b.opts.endpoint),
}
if b.opts.insecure {
opts = append(opts, otlpmetrichttp.WithInsecure())
}
if len(b.opts.headers) > 0 {
opts = append(opts, otlpmetrichttp.WithHeaders(b.opts.headers))
}
if b.opts.timeout > 0 {
opts = append(opts, otlpmetrichttp.WithTimeout(b.opts.timeout))
}
if b.opts.urlPath != "" {
opts = append(opts, otlpmetrichttp.WithURLPath(b.opts.urlPath))
}
return otlpmetrichttp.New(ctx, opts...)
}
```
### 6.2 配置加载实现
```go
func (c *completedConfig) installMeter(ctx context.Context) ([]OpenTelemetryServiceOption, error) {
var opts []OpenTelemetryServiceOption
// 设置采集周期
collectDuration := c.Proto.GetMetricCollectDuration().AsDuration()
if collectDuration > 0 {
opts = append(opts, WithMetricCollectDuration(collectDuration))
}
metricType := c.Proto.OtelMetricExporterType
switch metricType {
case OtelMetricExporterType_metric_prometheus:
// Pull 模式:Prometheus 主动抓取
builder := prometheus_.NewPrometheusExporterBuilder(
prometheus_.WithMetricUrlPath(c.Proto.GetOtelMetricExporter().GetPrometheus().GetUrl()),
)
opts = append(opts, WithMeterPullExporter(builder))
case OtelMetricExporterType_metric_otlp:
// Push 模式:服务主动推送
otlpConfig := c.Proto.GetOtelMetricExporter().GetOtlp()
var otlpOpts []otlpmetric_.OTLPExporterBuilderOption
// 配置 endpoint
if otlpConfig.GetEndpoint() != "" {
otlpOpts = append(otlpOpts, otlpmetric_.WithEndpoint(otlpConfig.GetEndpoint()))
}
// 配置协议
if otlpConfig.GetProtocol() == "grpc" {
otlpOpts = append(otlpOpts, otlpmetric_.WithProtocol(otlpmetric_.ProtocolGRPC))
} else {
otlpOpts = append(otlpOpts, otlpmetric_.WithProtocol(otlpmetric_.ProtocolHTTP))
}
// 配置认证头
headers := make(map[string]string)
for k, v := range otlpConfig.GetHeaders() {
headers[k] = v
}
if otlpConfig.GetToken() != "" {
headers["Authorization"] = "Bearer " + otlpConfig.GetToken()
}
if len(headers) > 0 {
otlpOpts = append(otlpOpts, otlpmetric_.WithHeaders(headers))
}
builder := otlpmetric_.NewOTLPExporterBuilder(otlpOpts...)
opts = append(opts, WithMeterPushExporter(builder))
case OtelMetricExporterType_metric_stdout:
// 标准输出(调试用)
builder := stdoutmetric_.NewStdoutExporterBuilder(
stdoutmetric_.WithPrettyPrint(c.Proto.GetOtelMetricExporter().GetStdout().GetPrettyPrint()),
)
opts = append(opts, WithMeterPushExporter(builder))
}
return opts, nil
}
```
### 6.3 中间件集成
#### gRPC 指标拦截器
```go
// UnaryServerInterceptorOfMetric gRPC 一元调用指标拦截器
func UnaryServerInterceptorOfMetric() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{},
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
start := time.Now()
resp, err := handler(ctx, req)
duration := time.Since(start)
// 记录请求指标
meter_.RecordRequest(ctx, info.FullMethod, duration, err)
return resp, err
}
}
```
#### HTTP 指标中间件
```go
// MetricMiddleware HTTP 指标中间件
func MetricMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Next()
duration := time.Since(start)
// 记录请求指标
meter_.RecordHTTPRequest(c.Request.Context(),
c.Request.Method, c.Request.URL.Path,
c.Writer.Status(), duration)
}
}
```
## 7. 腾讯云 Prometheus 接入指南
### 7.1 获取配置信息
1. 登录 [腾讯云 Prometheus 监控控制台](https://console.cloud.tencent.com/monitor/prometheus)
2. 选择对应实例,进入**基本信息** > **服务地址**
3. 获取以下信息:
- **Remote Write 地址**:填入 `endpoint`
- **Token**:填入 `token`
### 7.2 配置参数说明
| 参数 | 说明 | 示例 |
|------|------|------|
| `endpoint` | Remote Write 地址(不含 https://) | `your-instance.tencentcloudprom.com` |
| `token` | 认证 Token | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |
| `protocol` | 传输协议 | `http`(推荐)或 `grpc` |
| `insecure` | 是否禁用 TLS | 同 VPC 可用 `true`,公网用 `false` |
| `url_path` | OTLP URL 路径 | `/v1/metrics` |
### 7.3 完整配置示例
```yaml
web:
monitor:
open_telemetry:
enabled: true
metric_collect_duration: 60s
otel_metric_exporter_type: metric_otlp
otel_trace_exporter_type: trace_stdout
otel_metric_exporter:
otlp:
endpoint: "your-instance.tencentcloudprom.com"
token: "your-prometheus-token"
protocol: "http"
insecure: false
url_path: "/v1/metrics"
resource:
service_name: "sea-date"
attrs:
env: "production"
region: "ap-guangzhou"
```
## 8. K8s Resource 属性
### 8.1 概述
自动从 K8s 环境变量中采集容器运行时信息,作为 OpenTelemetry Resource 属性注入到所有 Metrics 和 Traces 中。
### 8.2 支持的 K8s 属性
| 环境变量 | 属性名 | 说明 |
|----------|--------|------|
| `NODE_IP` | `k8s.node.ip` | 宿主机节点 IP |
| `POD_NAMESPACE` | `k8s.namespace.name` | Pod 命名空间 |
| `POD_NAME` | `k8s.pod.name` | Pod 名称 |
| `POD_IP` | `k8s.pod.ip` | Pod IP |
| `CONTAINER_NAME` | `k8s.container.name` | 容器名称 |
| `CONTAINER_PLATFORM` | `k8s.container.platform` | 容器平台 (STKE/TKE) |
### 8.3 K8s Deployment 配置示例
```yaml
spec:
containers:
- name: my-app
env:
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: CONTAINER_NAME
value: "my-app"
- name: CONTAINER_PLATFORM
value: "STKE"
```
### 8.4 YAML 配置
```yaml
open_telemetry:
resource:
service_name: "my-service"
service_version: "1.0.0"
attrs:
env: "production"
k8s:
enabled: true # 是否启用 K8s 属性自动检测(默认 true)
# 以下属性会自动从环境变量读取,也可以手动覆盖
# node_ip: ""
# pod_namespace: ""
# pod_name: ""
# pod_ip: ""
# container_name: ""
# container_platform: ""
apm:
token: "" # APM Token,与业务系统关联,从 APM 控制台获取
```
### 8.5 APM Token 配置
#### 概述
APM(Application Performance Management)Token 用于腾讯云 APM 服务的身份认证和数据关联。Token 会作为 Resource attribute 添加到所有 trace span 中。
#### 获取 APM Token
1. 登录 [腾讯云 APM 控制台](https://console.cloud.tencent.com/apm/monitor/access)
2. 选择对应业务系统
3. 获取 Token
#### YAML 配置
```yaml
open_telemetry:
enabled: true
resource:
service_name: "my-service"
apm:
token: "your-apm-token" # 从 APM 控制台获取
```
#### Proto 定义
```protobuf
message Resource {
string service_name = 1;
string service_version = 2;
map<string, string> attrs = 3;
K8sResource k8s = 10;
Apm apm = 11; // 腾讯云 APM 配置
ZhiYan zhiyan = 12; // 智研平台配置
}
message Apm {
string token = 1; // APM Token,与业务系统关联
}
message ZhiYan {
string app_mark = 1; // 业务指标上报 appMark
string global_app_mark = 2; // 全局指标上报 appMark
string env = 3; // 环境标识 (prod/test/dev)
string instance_mark = 4; // 实例标识
string zhiyan_apm_token = 5; // 智研 APM Token
string expand_key = 6; // 是否扩展属性到维度
}
```
#### 核心实现
```go
// APM Token key
var ApmTokenKey = attribute.Key("token")
// WithApmToken 设置 APM Token
func WithApmToken(token string) ResourceOption {
return func(o *ResourceOptions) {
o.ApmToken = token
}
}
// 在 NewResource 中添加 APM Token
if options.ApmToken != "" {
attrs = append(attrs, ApmTokenKey.String(options.ApmToken))
}
```
### 8.6 智研 (ZhiYan) 平台配置
#### 概述
智研是腾讯内部的可观测平台,支持 Metrics、Traces、Logs 的统一上报和分析。通过 OpenTelemetry 协议接入。
#### 智研 vs 腾讯云 APM 对比
| 平台 | 访问范围 | 认证方式 | 上报地址 |
|------|---------|---------|---------|
| 腾讯云 APM | 公网 | `Authorization: Bearer <token>` | `xxx.tencentcloudapi.com` |
| 智研平台 | 内网 | `tps.tenant.id` Resource Attribute | `<智研内网trace地址>:4317` |
#### 获取智研租户
1. 登录
2. 进入 监控宝 > 应用性能监控 > 接入管理
3. 获取租户信息,格式:`空间ID#日志租户#监控宝租户`
- 示例:`<空间ID>#<日志租户>#<监控宝租户>`
#### 智研上报地址
| 网络环境 | 类型 | 服务地址 | 协议 | 备注 |
|----------|------|---------|------|------|
| **内网** | Metric | `<内网metric上报地址>:4318` | HTTP | 推荐,无需 TLS |
| **外网** | Metric | `<外网metric上报地址>:4318` | **HTTPS** | 必须启用 TLS |
| 内网 | Trace | `<内网trace上报地址>:4317` | gRPC | IDC 内网 |
| 内网 | Trace | `<内网trace上报地址>:4318` | HTTP | IDC 内网 |
| 公网 | Trace | `<外网trace上报地址>:4317` | gRPC | DevCloud/研发环境 |
> **⚠️ 重要**: 外网域名 **必须使用 HTTPS**(`insecure: false`),否则会连接超时。
#### YAML 配置示例
```yaml
open_telemetry:
enabled: true
# Trace 上报到智研
otel_trace_exporter_type: trace_otlp
otel_trace_exporter:
otlp:
endpoint: "<智研trace上报地址>:4317"
protocol: "grpc"
insecure: true
# Metric 上报到智研
otel_metric_exporter_type: metric_otlp
otel_metric_exporter:
otlp:
endpoint: "<智研metric上报地址>:4317"
protocol: "grpc"
insecure: true
resource:
service_name: "my-service"
zhiyan:
# 业务指标上报 appMark(用于 App MeterProvider)
app_mark: "<your_app_mark>"
# 全局指标上报 appMark(用于 Global MeterProvider)
global_app_mark: "<your_global_app_mark>"
# 环境标识
env: "prod"
# 智研 APM Token(用于 Trace 上报)
# 格式:空间ID#日志租户#监控宝租户
zhiyan_apm_token: "<空间ID>#<日志租户>#<监控宝租户>"
# 是否将 resource 属性扩展到指标维度
expand_key: "no"
```
#### 智研 Resource Attribute Keys
| Attribute Key | 说明 | 是否必填 | 类型 |
|---------------|------|---------|------|
| `__zhiyan_app_mark__` | 上报应用标记 | **是** | string |
| `__zhiyan_env__` | 环境标识 (prod/test/dev) | **是** | string |
| `__zhiyan_instance_mark__` | 上报实例标识 | 否 | string |
| `__zhiyan_expand_tag_enable__` | 是否扩展属性到维度 | 否(默认 no) | string |
| `__zhiyan_data_grain__` | 数据粒度 (10/30/60) | 否(默认 60) | int |
| `__zhiyan_data_type__` | 数据类型,秒级填 "second" | 否 | string |
| `tps.tenant.id` | 智研 APM 租户 ID | Trace 上报必填 | string |
#### 智研上报必须配置
根据智研对接文档,以下配置项**必须正确设置**:
| 配置项 | 要求 | 说明 |
|--------|------|------|
| Delta Temporality | `temporality_delta: true` | 智研只支持 Delta 时间性 |
| Gzip 压缩 | `compression: true` | 建议启用以减少带宽 |
| 采集周期 | 与数据粒度一致 | 如分钟级数据设置 60s |
| HTTP 端口 | 4318 | OTLP HTTP 标准端口 |
#### 核心实现
```go
// 智研平台 attribute keys
var (
ZhiYanAppMarkKey = attribute.Key("__zhiyan_app_mark__")
ZhiYanInstanceMarkKey = attribute.Key("__zhiyan_instance_mark__")
ZhiYanEnvKey = attribute.Key("__zhiyan_env__")
ZhiYanExpandKey = attribute.Key("__zhiyan_expand_tag_enable__")
ZhiYanDataGrainKey = attribute.Key("__zhiyan_data_grain__")
ZhiYanDataTypeKey = attribute.Key("__zhiyan_data_type__")
ZhiYanTpsTenantIDKey = attribute.Key("tps.tenant.id")
)
// 在 NewResource 中添加智研属性
if options.ZhiYanAppMark != "" {
attrs = append(attrs, ZhiYanAppMarkKey.String(options.ZhiYanAppMark))
attrs = append(attrs, ZhiYanEnvKey.String(options.ZhiYanEnv))
attrs = append(attrs, ZhiYanExpandKey.String("no"))
}
if options.ZhiYanApmToken != "" {
attrs = append(attrs, ZhiYanTpsTenantIDKey.String(options.ZhiYanApmToken))
}
```
### 8.7 核心实现
```go
// K8s 环境变量映射
var k8sEnvToAttribute = map[string]attribute.Key{
"NODE_IP": semconv.K8SNodeNameKey,
"POD_NAMESPACE": semconv.K8SNamespaceNameKey,
"POD_NAME": semconv.K8SPodNameKey,
"POD_IP": attribute.Key("k8s.pod.ip"),
"CONTAINER_NAME": semconv.K8SContainerNameKey,
"CONTAINER_PLATFORM": attribute.Key("k8s.container.platform"),
}
// NewResource 创建包含 K8s 属性的 Resource
func NewResource(opts ...ResourceOption) (*resource.Resource, error) {
cfg := defaultResourceConfig()
for _, opt := range opts {
opt(cfg)
}
var attrs []attribute.KeyValue
// 添加服务信息
if cfg.serviceName != "" {
attrs = append(attrs, semconv.ServiceName(cfg.serviceName))
}
if cfg.serviceVersion != "" {
attrs = append(attrs, semconv.ServiceVersion(cfg.serviceVersion))
}
// 添加 K8s 属性
if cfg.enableK8s {
attrs = append(attrs, getK8sAttributes()...)
}
// 添加自定义属性
for k, v := range cfg.attrs {
attrs = append(attrs, attribute.String(k, v))
}
return resource.NewWithAttributes(semconv.SchemaURL, attrs...)
}
```
## 9. 模调上报(主/被调)
### 9.1 概述
模调上报是一种标准化的服务调用监控方案,支持:
- **被调上报 (P)**:服务端记录被调用的指标
- **主调上报 (A)**:客户端记录调用其他服务的指标
### 9.2 上报指标
| 指标名 | 类型 | 说明 |
|--------|------|------|
| `requests` | Counter | 请求数 |
| `success` | Counter | 成功数 |
| `timeout` | Counter | 超时数 |
| `abnormal` | Counter | 异常数 |
| `cost` | Counter | 累计耗时(ms) |
| `duration` | Histogram | 耗时分布 |
### 9.3 维度属性
#### 被调方 (P) 维度
| 属性 | 说明 |
|------|------|
| `ret_code` | 返回码 |
| `p_ip` | 被调 IP |
| `p_app` | 被调应用名 |
| `p_server` | 被调服务名 |
| `p_service` | 被调 Service |
| `p_interface` | 被调接口 |
#### 主调方 (A) 维度
| 属性 | 说明 |
|------|------|
| `a_ip` | 主调 IP |
| `a_app` | 主调应用名 |
| `a_server` | 主调服务名 |
| `a_service` | 主调 Service |
| `a_interface` | 主调接口 |
### 9.4 gRPC 拦截器使用示例
#### Server 端(被调上报)
```go
import interceptoropentelemetry "github.com/kaydxh/golang/pkg/middleware/grpc-middleware/opentelemetry"
server := grpc.NewServer(
grpc.ChainUnaryInterceptor(
interceptoropentelemetry.UnaryServerModularInterceptor(
interceptoropentelemetry.ModularServerConfig{
AppName: "my-app",
ServerName: "my-server",
},
),
),
grpc.ChainStreamInterceptor(
interceptoropentelemetry.StreamServerModularInterceptor(
interceptoropentelemetry.ModularServerConfig{
AppName: "my-app",
ServerName: "my-server",
},
),
),
)
```
#### Client 端(主调上报)
```go
conn, err := grpc.Dial(target,
grpc.WithChainUnaryInterceptor(
interceptoropentelemetry.UnaryClientModularInterceptor(
interceptoropentelemetry.ModularClientConfig{
AppName: "my-app",
ServerName: "my-server",
ServiceName: "my-service",
},
),
),
grpc.WithChainStreamInterceptor(
interceptoropentelemetry.StreamClientModularInterceptor(
interceptoropentelemetry.ModularClientConfig{
AppName: "my-app",
ServerName: "my-server",
ServiceName: "my-service",
},
),
),
)
```
### 9.5 核心实现
```go
// MetricReporter 模调上报器
type MetricReporter struct {
meterProvider otelmetric.MeterProvider
counters map[string]otelmetric.Int64Counter
histograms map[string]otelmetric.Float64Histogram
mu sync.RWMutex
}
// ReportServerMetric 被调上报
func (r *MetricReporter) ReportServerMetric(ctx context.Context, dim *ServerDimension, costMs float64) {
attrs := dim.ToAttributes()
// 请求数
r.getCounter(ServerReportMeterName, RequestsMetricName).Add(ctx, 1, otelmetric.WithAttributes(attrs...))
// 成功/超时/异常
if dim.IsSuccess() {
r.getCounter(ServerReportMeterName, SuccessMetricName).Add(ctx, 1, otelmetric.WithAttributes(attrs...))
} else if dim.IsTimeout() {
r.getCounter(ServerReportMeterName, TimeoutMetricName).Add(ctx, 1, otelmetric.WithAttributes(attrs...))
} else {
r.getCounter(ServerReportMeterName, AbnormalMetricName).Add(ctx, 1, otelmetric.WithAttributes(attrs...))
}
// 耗时
r.getCounter(ServerReportMeterName, CostMetricName).Add(ctx, int64(costMs), otelmetric.WithAttributes(attrs...))
r.getHistogram(ServerReportMeterName, DurationMetricName, DefaultDurationBounds).Record(ctx, costMs, otelmetric.WithAttributes(attrs...))
}
```
## 10. 自定义 Metric API
### 10.1 概述
提供便捷的 Metric API,简化指标上报操作,支持:
- 函数式 API(Context 属性传递)
- 函数式 API(显式属性传递)
- 面向对象 API(Instrument 封装)
- Global/App 双 Provider 支持
### 10.2 函数式 API(Context 属性)
```go
import "github.com/kaydxh/golang/pkg/opentelemetry/metric/api"
// 通过 context 传递属性
ctx = api.WithAttribute(ctx, "meter_name", "user_id", "12345")
ctx = api.WithAttributes(ctx, "meter_name", map[string]any{
"region": "us-west-2",
"version": "1.2.3",
})
// Counter
api.AddCounter(ctx, "business", "orders_count", 10)
api.IncrCounter(ctx, "business", "user_signups")
// Histogram
api.RecordHistogram(ctx, "latency", "api_duration", 125.5, nil)
api.RecordDuration(ctx, "latency", "db_query", 45.2) // 使用默认 bounds
```
### 10.3 函数式 API(显式属性)
```go
import "go.opentelemetry.io/otel/attribute"
// 直接传入属性,不依赖 context
api.IncrCounterWithAttrs(ctx, "http", "requests",
attribute.String("endpoint", "/api/v1/users"),
attribute.Int("status", 200),
)
api.RecordDurationWithAttrs(ctx, "http", "latency", 45.2,
attribute.String("method", "GET"),
attribute.String("path", "/users"),
)
```
### 10.4 面向对象 API
```go
// Counter 对象
counter := api.NewCounter("business", "api_calls")
counter.SetAttribute("service", "user-service")
counter.Incr(ctx)
// 链式调用
counter.With("method", "GET").With("path", "/users").Incr(ctx)
// Histogram 对象
histogram := api.NewHistogram("latency", "processing_time",
api.WithBounds([]float64{10, 50, 100, 500, 1000}),
)
histogram.SetAttribute("processor", "image")
histogram.Record(ctx, 234.5)
// Timer 对象
timer := api.NewTimer("performance", "operation_duration")
timer.SetAttribute("operation", "data_processing")
timer.Record(ctx, float64(elapsed.Milliseconds()))
```
### 10.5 Global vs App Provider
```go
// App Provider(应用级指标)- 默认
api.IncrCounter(ctx, "business", "orders")
counter := api.NewCounter("app", "signups")
// Global Provider(基础设施指标)
api.GlobalIncrCounter(ctx, "infra", "gc_cycles")
globalCounter := api.NewGlobalCounter("system", "allocations")
// 设置自定义 App Provider(可选)
api.SetAppMeterProvider(myCustomProvider)
```
### 10.6 配置驱动的双 MeterProvider
支持通过配置文件自动初始化 Global 和 App 两个独立的 MeterProvider:
#### Proto 配置定义
```protobuf
message OpenTelemetry {
// ... 其他字段 ...
// App MeterProvider configuration (separate from global)
AppMeterProvider app_meter_provider = 11;
}
message AppMeterProvider {
bool enabled = 1; // Enable separate App MeterProvider
// Exporter type for app metrics (if different from global)
OtelMetricExporterType exporter_type = 2;
// Exporter configuration (if different from global)
OtelMetricExporter exporter = 3;
// Collect duration for app metrics
google.protobuf.Duration collect_duration = 4;
// Resource attributes specific to app metrics
Resource resource = 5;
}
```
#### YAML 配置示例
```yaml
open_telemetry:
enabled: true
# Global MeterProvider (基础设施指标)
otel_metric_exporter_type: metric_prometheus
otel_metric_exporter:
prometheus:
url: "/metrics"
metric_collect_duration: "60s"
# App MeterProvider (应用级指标,独立配置)
app_meter_provider:
enabled: true
exporter_type: metric_otlp # 可以使用不同的导出器
exporter:
otlp:
endpoint: "prometheus.tencentcloudapi.com:4317"
protocol: "grpc"
token: "your-app-token"
collect_duration: "30s" # 可以使用不同的采集周期
resource:
service_name: "my-app-metrics"
attrs:
metric_type: "business"
```
#### 使用场景
| 场景 | Global Provider | App Provider |
|------|-----------------|--------------|
| **用途** | 基础设施/运维指标 | 业务/应用指标 |
| **指标类型** | CPU、内存、GC、网络 | 订单数、用户注册、业务延迟 |
| **采集周期** | 较长(60s) | 较短(15-30s) |
| **导出目标** | 本地 Prometheus | 腾讯云/远程 OTLP |
| **资源属性** | 通用服务信息 | 业务相关属性 |
#### 编程方式配置
```go
// 方式1:使用配置文件自动初始化
cfg := opentelemetry.NewConfig(
opentelemetry.WithViper(v),
)
cfg.Complete().New(ctx)
// 方式2:编程方式手动配置双 Provider
ot := opentelemetry.NewOpenTelemetryService(
// Global Provider
opentelemetry.WithMeterPullExporter(prometheusBuilder),
opentelemetry.WithMetricCollectDuration(time.Minute),
// App Provider
opentelemetry.WithAppMeterPushExporter(otlpBuilder),
opentelemetry.WithAppMetricCollectDuration(30 * time.Second),
opentelemetry.WithAppMeterResource(appResource),
)
ot.Install(ctx)
```
### 10.7 支持的属性类型
| 类型 | 示例 |
|------|------|
| `string` | `"value"` |
| `int`, `int8`, `int16`, `int32`, `int64` | `123` |
| `uint`, `uint8`, `uint16`, `uint32`, `uint64` | `456` |
| `float32`, `float64` | `3.14` |
| `bool` | `true` |
### 10.8 默认 Histogram Bounds
```go
// 延迟类(毫秒)
DefaultDurationBounds = []float64{1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000}
// 大小类(字节)
DefaultSizeBounds = []float64{100, 1000, 10000, 100000, 1000000, 10000000}
```
## 11. 资源统计
### 11.1 ResourceStatsService
自动采集系统资源指标:
```go
type ResourceStatsService struct {
checkInterval time.Duration
// 采集的指标
cpuUsage float64 // CPU 使用率
memoryUsage float64 // 内存使用率
goroutines int // Goroutine 数量
gcPauseNs uint64 // GC 暂停时间
}
```
### 11.2 采集的指标
| 指标 | 说明 | 类型 |
|------|------|------|
| `process_cpu_usage` | 进程 CPU 使用率 | Gauge |
| `process_memory_usage` | 进程内存使用率 | Gauge |
| `go_goroutines` | Goroutine 数量 | Gauge |
| `go_gc_duration_seconds` | GC 暂停时间 | Histogram |
| `go_memstats_alloc_bytes` | 已分配内存 | Gauge |
## 12. 使用示例
### 12.1 编程方式配置
```go
import (
"github.com/kaydxh/golang/pkg/opentelemetry"
"github.com/kaydxh/golang/pkg/opentelemetry/metric/otlp"
)
// 方式一:使用腾讯云 Prometheus 快捷方法
otelService := opentelemetry.NewOpenTelemetryService(
opentelemetry.WithMeterOptions(
otlp.WithTencentCloudPrometheus(
"your-instance.tencentcloudprom.com",
"your-token",
false, // 使用 TLS
),
),
)
otelService.Install(ctx)
// 方式二:自定义 OTLP 配置
otelService := opentelemetry.NewOpenTelemetryService(
opentelemetry.WithMeterOptions(
otlp.WithOTLPPushExporter(
"prometheus.example.com:4318",
otlp.WithProtocol(otlp.ProtocolHTTP),
otlp.WithHeaders(map[string]string{
"Authorization": "Bearer xxx",
}),
otlp.WithInsecure(true),
),
),
)
```
### 12.2 配置文件方式
```yaml
# sea-date.yaml
web:
monitor:
open_telemetry:
enabled: true
metric_collect_duration: 60s
otel_metric_exporter_type: metric_otlp
otel_metric_exporter:
otlp:
endpoint: "your-instance.tencentcloudprom.com"
token: "your-prometheus-token"
protocol: "http"
insecure: false
```
## 13. 文件结构
```
pkg/opentelemetry/
├── opentelemetry.go # OpenTelemetryService 主入口
├── opentelemetry.proto # Proto 配置定义
├── opentelemetry.pb.go # 生成的 Proto 代码
├── opentelemetry.yaml # 配置示例
├── opentelemetry.option.go # OpenTelemetry 选项
├── config.go # 配置加载和安装
├── config.option.go # 配置选项
├── metric/
│ ├── meter.go # MeterProvider 管理
│ ├── meter.option.go # Meter 选项
│ ├── meter.pull.exporter.go # Pull 模式导出器接口
│ ├── meter.push.exporter.go # Push 模式导出器接口
│ ├── api/ # 自定义 Metric API
│ │ ├── api.go # 便捷 API 函数
│ │ └── instrument.go # Instrument 对象封装
│ ├── report/ # 模调上报
│ │ ├── report.go # 上报核心实现
│ │ └── dimension.go # 维度定义
│ ├── prometheus/ # Prometheus Pull 导出器
│ │ ├── prometheus.metric.go
│ │ └── prometheus.metric_option.go
│ ├── otlp/ # OTLP Push 导出器
│ │ ├── otlp.metric.go
│ │ ├── otlp.metric.option.go
│ │ └── otlp.metric_option.go
│ └── stdout/ # Stdout 导出器
│ └── stdout.metric.go
├── tracer/
│ ├── tracer.go # TracerProvider 管理
│ ├── tracer.option.go # Tracer 选项
│ ├── jaeger/ # Jaeger 导出器
│ └── stdout/ # Stdout 导出器
└── resource/
└── resource.go # K8s Resource 属性
pkg/middleware/grpc-middleware/opentelemetry/
├── metric_server.interceptor.go # gRPC 指标拦截器
├── trace_server.interceptor.go # gRPC 链路拦截器(Server)
├── trace_client.interceptor.go # gRPC 链路拦截器(Client)
├── modular_server.interceptor.go # 模调上报拦截器(Server/被调)
└── modular_client.interceptor.go # 模调上报拦截器(Client/主调)
```
## 14. 设计特点总结
| 特点 | 说明 |
|------|------|
| OpenTelemetry 标准 | 基于 CNCF OpenTelemetry 标准实现 |
| 多后端支持 | 支持 Prometheus、OTLP、Jaeger、Stdout 等 |
| Pull/Push 双模式 | 同时支持 Pull(Prometheus)和 Push(OTLP)模式 |
| 腾讯云兼容 | 原生支持腾讯云 Prometheus Remote Write |
| APM Token 支持 | 支持腾讯云 APM Token 认证,作为 Resource attribute 注入 |
| 智研平台支持 | 支持腾讯内部智研平台,通过 tps.tenant.id 认证,支持 Metric/Trace 上报 |
| 配置驱动 | 通过 YAML/Proto 配置灵活切换后端 |
| 中间件集成 | gRPC/HTTP 请求自动采集指标和链路 |
| 资源监控 | 自动采集 CPU、内存、GC 等系统指标 |
| 低侵入性 | 通过中间件透明接入,业务代码无感知 |
| K8s 属性 | 自动采集 K8s 容器运行时信息 |
| 模调上报 | 支持主调/被调标准化监控 |
| 自定义 Metric API | 提供便捷的指标上报 API |
| Global/App 双 Provider | 支持基础设施和应用级指标分离 |
## 15. 常见问题排查
### 15.1 智研上报超时
**现象**:
```
[ERRO] metric export failed: context deadline exceeded: retry-able request failure
```
**原因与解决方案**:
| 错误原因 | 解决方案 |
|----------|----------|
| 使用内网地址但不在内网 | 切换到外网地址 + HTTPS |
| 使用外网地址但未启用 TLS | 设置 `insecure: false` |
| 网络不通 | 检查防火墙和网络连通性 |
**配置对照表**:
```yaml
# 内网环境(推荐)
endpoint: "<内网metric上报地址>:4318"
insecure: true # HTTP
# 外网环境
endpoint: "<外网metric上报地址>:4318"
insecure: false # 必须 HTTPS
```
### 15.2 指标未上报到智研
**检查清单**:
1. **必填字段是否配置**:
- `__zhiyan_app_mark__`:必须配置 appMark
- `__zhiyan_env__`:必须配置环境标识
2. **Temporality 是否正确**:
- 智研只支持 `Delta Temporality`
- 配置:`temporality_delta: true`
3. **采集周期是否匹配**:
- 数据粒度为 60 时,采集周期应为 60s
- 配置:`metric_collect_duration: 60s`
4. **压缩是否启用**:
- 建议启用 gzip:`compression: true`
### 15.3 指标组/Scope Name 配置
智研模调分析需要正确的指标组:
| 指标组 | 用途 | 配置 |
|--------|------|------|
| `server_report` | 被调上报 | 服务端拦截器 |
| `client_report` | 主调上报 | 客户端拦截器 |
| `attr_report` | 属性监控 | 自定义业务指标 |
| `default` | 默认 | 通用指标 |
```yaml
resource:
zhiyan:
metric_group: "server_report" # 指标组名称
```
### 15.4 完整的智研配置示例
```yaml
open_telemetry:
enabled: true
metric_collect_duration: 60s # 采集周期与数据粒度一致
otel_metric_exporter_type: metric_otlp
otel_metric_exporter:
otlp:
# 根据网络环境选择内网或外网地址
endpoint: "<智研metric上报地址>:4318"
protocol: "http"
insecure: true # 内网 HTTP / 外网必须 false
url_path: "/v1/metrics"
compression: true # 启用 gzip 压缩
temporality_delta: true # 必须使用 Delta
resource:
service_name: "my-service"
zhiyan:
global_app_mark: "<your_global_app_mark>" # 必填:appMark
env: "prod" # 必填:环境
instance_mark: "" # 选填:实例标识
expand_key: "no" # 选填:是否扩展属性
metric_group: "server_report" # 选填:指标组
# data_grain: 60 # 选填:数据粒度 (10/30/60)
# data_type: "" # 选填:秒级填 "second"
```
### 15.5 Trace 没有上报日志
**现象**:
- Meter 指标正常上报,但 Trace 没有任何 export 日志
- 调用 HTTP 接口后没有看到 span 创建
**原因分析**:
| 原因 | 说明 |
|------|------|
| TracerProvider 初始化时机错误 | otelgrpc interceptor 在创建时会缓存全局 TracerProvider,如果此时 TracerProvider 还没设置,会拿到 noop TracerProvider |
| HTTP 请求没有 trace interceptor | gRPC trace interceptor 只对 gRPC 请求生效,HTTP 请求需要单独的 HTTP trace middleware |
| Sampler 配置问题 | 默认 Sampler 可能不是 AlwaysSample,导致部分 span 被丢弃 |
**解决方案**:
1. **确保 TracerProvider 在 WebServer.Run() 之前初始化**:
```go
// options.go 中的正确顺序
s.installLogsOrDie()
s.installConfigOrDie()
ws, err := s.webServerConfig.Complete().New(ctx) // ← 先创建 WebServer
// TracerProvider 可以在 WebServer.New() 之后初始化
// 但必须在 WebServer.Run() 之前完成
s.installOpenTelemetryTracerOrDie(ctx)
s.installOpenTelemetryMeterOrDie(ctx, ws)
ws.PrepareRun().Run(ctx) // ← 启动前 Provider 已设置好
```
2. **HTTP trace middleware 动态获取 TracerProvider**:
```go
// HTTP middleware 在每次请求时动态获取 TracerProvider
func Trace(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tracer := otel.Tracer(tracerName) // ← 请求时获取,此时已设置好
ctx, span := tracer.Start(ctx, spanName, ...)
// ...
})
}
```
3. **gRPC trace interceptor 创建时缓存(注意)**:
```go
func UnaryServerTraceInterceptor(opts ...otelgrpc.Option) grpc.UnaryServerInterceptor {
// gRPC interceptor 在创建时缓存 TracerProvider
tp := otel.GetTracerProvider()
defaultOpts := []otelgrpc.Option{
otelgrpc.WithTracerProvider(tp),
}
defaultOpts = append(defaultOpts, opts...)
return otelgrpc.UnaryServerInterceptor(defaultOpts...)
}
```
3. **添加 HTTP trace middleware**:
HTTP 请求(如 `GET /Now`)不经过 gRPC interceptor,需要单独添加 HTTP trace middleware:
```go
// http trace interceptor
func Trace(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// 提取 trace context
propagator := otel.GetTextMapPropagator()
ctx = propagator.Extract(ctx, propagation.HeaderCarrier(r.Header))
// 创建 span
tracer := otel.Tracer("http-trace")
spanName := r.Method + " " + r.URL.Path
ctx, span := tracer.Start(ctx, spanName, trace.WithSpanKind(trace.SpanKindServer))
defer span.End()
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
```
4. **确保使用 AlwaysSample**:
```go
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp, batchOpts...),
sdktrace.WithResource(res),
sdktrace.WithSampler(sdktrace.AlwaysSample()), // 确保所有 span 都被记录
)
```
**验证日志**:
正确配置后,启动日志应显示:
```
[INFO] TracerProvider created with BatchSpanProcessor (batch_timeout=5s, sampler=AlwaysSample)
[INFO] UnaryServerTraceInterceptor: creating trace interceptor, TracerProvider type=*trace.TracerProvider
```
如果显示 `TracerProvider type=*trace.noopTracerProvider`,说明 TracerProvider 初始化顺序有问题。
### 15.6 Trace 上报连接失败 (EOF)
**现象**:
```
[ERRO] [OTLP] trace export failed: traces export: Post "http://xxx:4318/v1/traces": EOF
```
Span 创建成功,但导出到远程服务器失败。
**原因分析**:
| 原因 | 说明 |
|------|------|
| Endpoint 地址不可达 | 网络不通、DNS 解析失败、防火墙阻断 |
| 协议不匹配 | 外网地址需要 HTTPS,但配置了 `insecure: true` |
| 端口错误 | gRPC 用 4317,HTTP 用 4318 |
**解决方案**:
根据网络环境选择正确的配置:
```yaml
# 方案1:内网 gRPC(推荐)
otel_trace_exporter:
otlp:
endpoint: "<内网trace上报地址>:4317"
protocol: "grpc"
insecure: true
# 方案2:内网 HTTP
otel_trace_exporter:
otlp:
endpoint: "<内网trace上报地址>:4318"
protocol: "http"
insecure: true
# 方案3:外网 HTTP(必须 HTTPS)
otel_trace_exporter:
otlp:
endpoint: "<外网trace上报地址>:4318"
protocol: "http"
insecure: false # 外网必须启用 TLS
# 方案4:本地调试(stdout)
otel_trace_exporter_type: trace_stdout
```
**智研 Trace 上报地址汇总**:
| 网络环境 | 协议 | 地址 | 端口 | TLS |
|----------|------|------|------|-----|
| 内网 IDC | gRPC | `<内网trace上报地址>` | 4317 | 否 |
| 内网 IDC | HTTP | `<内网trace上报地址>` | 4318 | 否 |
| 外网/DevCloud | gRPC | `<外网trace上报地址>` | 4317 | 否 |
| 外网 | HTTP | `<外网metric上报地址>` | 4318 | **是** |
### 15.7 Tracer 和 Meter 初始化顺序问题
**问题**:Tracer 和 Meter 的初始化顺序有什么要求?
**原因分析**:
| 组件 | 必须在 WebServer 之前? | 原因 |
|------|------------------------|------|
| **Tracer** | **否** | HTTP trace middleware 在请求时动态调用 `otel.Tracer()` 获取 TracerProvider |
| **Meter** | 否(但有例外) | 指标也是在请求处理时动态调用 `otel.Meter()` 获取 |
**HTTP Trace Middleware(动态获取)**:
```go
// HTTP trace middleware 在每次请求时动态获取 TracerProvider
func Trace(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 请求时动态获取,此时 TracerProvider 已设置
tracer := otel.Tracer(tracerName) // ← 每次请求时获取
ctx, span := tracer.Start(ctx, spanName, ...)
defer span.End()
next.ServeHTTP(w, r)
})
}
```
**gRPC Trace Interceptor(创建时缓存)**:
```go
// gRPC interceptor 在创建时获取并缓存 TracerProvider
func UnaryServerTraceInterceptor(opts ...otelgrpc.Option) grpc.UnaryServerInterceptor {
// 创建时获取全局 TracerProvider 并传入
tp := otel.GetTracerProvider()
return otelgrpc.UnaryServerInterceptor(otelgrpc.WithTracerProvider(tp)...)
}
```
> **注意**:如果 gRPC interceptor 在 TracerProvider 设置之前创建,会缓存 noop TracerProvider。但当前实现中,HTTP middleware 是动态获取的,所以 Tracer 可以在 WebServer 之后初始化。
**Meter 的例外情况**:
当使用 **Prometheus Pull 模式** 时,需要在 Gin Router 上注册 `/metrics` 端点,此时需要先有 WebServer:
```go
// 需要 ws.GetGinEngine() 来注册 /metrics
s.opentelemetryConfig.ApplyOptions(opentelemetry_.WithGinRouter(ws.GetGinEngine()))
```
**推荐的初始化顺序**:
```
┌─────────────────────────────────────────────────────────────┐
│ 启动顺序 │
├─────────────────────────────────────────────────────────────┤
│ 1. installLogs │
│ 2. installConfig │
│ 3. WebServer.New() │
│ 4. installMysql/Redis │
│ 5. installOpenTelemetryTracer ←── 可以在 WebServer 之后 │
│ 6. installOpenTelemetryMeter ←── 可以在 WebServer 之后 │
│ 7. WebServer.Run() ←── 必须在 Run() 之前完成 │
└─────────────────────────────────────────────────────────────┘
```
> **关键点**:只要在 `WebServer.Run()` 之前完成 TracerProvider 和 MeterProvider 的初始化即可,因为 HTTP middleware 是在请求时动态获取 Provider 的。
### 15.8 调试技巧
**1. 启用 stdout exporter 验证 span 创建**:
```yaml
otel_trace_exporter_type: trace_stdout # 临时切换到 stdout
otel_trace_exporter:
stdout:
pretty_print: true
```
**2. 启用 metric stdout exporter 查看上报数据**:
```yaml
otel_metric_exporter_type: metric_stdout
otel_metric_exporter:
stdout:
pretty_print: true
```
**3. 日志中确认 Resource Attribute**:
```
[DEBU] [OTLP] resource attribute: __zhiyan_app_mark__=<your_app_mark>
```
**4. 确认 TracerProvider 类型**:
```
[INFO] UnaryServerTraceInterceptor: creating trace interceptor, TracerProvider type=*trace.TracerProvider
```
如果显示 `*trace.noopTracerProvider`,说明初始化顺序有问题。
**5. 检查 span export 日志**:
```
[DEBU] [OTLP] exporting 1 spans to <trace上报地址>:4317
[INFO] [OTLP] trace export success: endpoint=xxx, spans=1, duration=xxx
```
**6. 网络连通性测试**:
```bash
# 测试 gRPC 端口
nc -zv <trace上报地址> 4317
# 测试 HTTP 端口
curl -v http://<trace上报地址>:4318/v1/traces
```
================================================
FILE: doc/rate_limit_design.md
================================================
# 限流增强功能设计文档
## 1. 概述
本文档描述了 golang 库中限流(Rate Limit)功能的增强设计,支持**基于 QPS 的限流**、**并发数控制**和**不同接口不同限流策略**的能力。
## 2. 限流模式分析
### 2.1 并发控制限流器 (Limiter)
基于**Channel 信号量**的并发控制器:
```go
type Limiter struct {
mu sync.Mutex
burst int // 最大令牌数(最大并发数)
sem chan struct{} // 信号量通道
}
```
**特点**:
- 控制**同时处理的请求数**(并发数)
- 请求完成后需要调用 `Put()` 归还令牌
- 适合控制资源占用,如数据库连接数、goroutine 数量
- 基于 Channel 实现,原生支持超时和 Context 取消
### 2.2 QPS 限流器 (QPSLimiter)
基于**令牌桶算法**的速率控制器:
```go
type QPSLimiter struct {
qps float64 // 每秒生成的令牌数
burst int // 桶容量(允许的突发流量)
tokens float64 // 当前可用令牌
lastUpdate time.Time // 上次更新时间
}
```
**特点**:
- 控制**每秒允许的请求数**(速率)
- 令牌按时间自动恢复,无需归还
- 适合流量控制和防止突发流量
### 2.3 两种模式对比
| 特性 | 并发限流器 (Limiter) | QPS 限流器 (QPSLimiter) |
|------|---------------------|------------------------|
| 控制目标 | 同时处理的请求数 | 每秒允许的请求数 |
| 令牌归还 | 需要 Put() | 不需要(时间自动恢复) |
| 适用场景 | 资源保护 | 流量控制 |
| 限制维度 | 资源维度 | 时间维度 |
| 实现方式 | Channel 信号量 | 令牌桶算法 |
| Context 支持 | 原生支持 | 原生支持 |
### 2.4 组合使用
**当 QPS 和并发数同时配置时,两种限流同时生效,取更严格的限制**:
```
请求进入
↓
┌─────────────────────┐
│ QPS限流检查 │ ← 令牌桶算法,按时间恢复
│ (default_qps=1000) │
└─────────┬───────────┘
│ 通过
↓
┌─────────────────────┐
│ 并发数检查 │ ← 信号量算法,请求完成归还
│ (max_concurrency=100) │
└─────────┬───────────┘
│ 通过
↓
处理请求
↓
归还并发令牌
```
**实际吞吐量 = min(QPS限制, 并发数 × (1000/平均处理时间ms))**
## 3. 架构设计
### 3.1 整体架构
```
┌─────────────────────────────────────────────────────────────────────┐
│ 配置层 (YAML) │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ web: │ │
│ │ qps_limit: │ │
│ │ grpc: │ │
│ │ default_qps: 1000 │ │
│ │ max_concurrency: 100 │ │
│ │ http: │ │
│ │ default_qps: 1000 │ │
│ │ max_concurrency: 100 │ │
│ └───────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 中间件层 (Interceptor) │
│ ┌─────────────────────────┐ ┌─────────────────────────────────┐│
│ │ gRPC 拦截器 │ │ HTTP 中间件 ││
│ │ - QPS 限流拦截器 │ │ - QPS 限流中间件 ││
│ │ - 并发控制拦截器 │ │ - 并发控制中间件 ││
│ └─────────────────────────┘ └─────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 核心限流器层 │
│ ┌─────────────────────────┐ ┌─────────────────────────────────┐│
│ │ MethodQPSLimiter │ │ MethodLimiter ││
│ │ (方法级 QPS 限流) │ │ (方法级并发控制) ││
│ └─────────────────────────┘ └─────────────────────────────────┘│
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────┐ ┌─────────────────────────────────┐│
│ │ QPSLimiter │ │ Limiter ││
│ │ (令牌桶算法) │ │ (信号量算法) ││
│ └─────────────────────────┘ └─────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────┘
```
### 3.2 方法级限流
支持为不同的 API 接口配置不同的限流策略:
```
┌─────────────────────────────────────────────────────────────┐
│ MethodQPSLimiter │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Method -> Limiter Map │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ /api/v1/users -> QPSLimiter(qps=100, burst=20)│ │ │
│ │ │ /api/v1/orders -> QPSLimiter(qps=50, burst=10)│ │ │
│ │ │ /api/v1/products -> QPSLimiter(qps=200, burst=50)│ │ │
│ │ │ * -> QPSLimiter(qps=10, burst=5) │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## 4. 配置设计
### 4.1 配置结构
限流配置统一放在 `web.qps_limit` 下,支持 gRPC 和 HTTP 分别配置:
```yaml
web:
bind_address:
port: 10001
grpc:
timeout: 0s
http:
api_formatter: trivial_api_v20
# QPS限流配置(统一在 web 配置内)
qps_limit:
# gRPC QPS限流配置
grpc:
default_qps: 1000 # 默认QPS,0表示不限制
default_burst: 1500 # 默认突发容量,0表示使用default_qps值
max_concurrency: 100 # 最大并发数限制,0表示不限制
method_qps: # 方法级配置(可选)
- method: "/seadate.v1.SeaDateService/Now"
qps: 500
burst: 750
max_concurrency: 50
# HTTP QPS限流配置
http:
default_qps: 1000
default_burst: 1500
max_concurrency: 100
method_qps: # 路径级配置(可选)
- method: "/v1/now"
qps: 500
burst: 750
max_concurrency: 50
```
### 4.2 配置优先级
```
方法级配置 (method_qps) > 全局默认配置 (default_*)
```
| 请求路径 | method_qps 配置 | 实际使用 |
|---------|----------------|---------|
| `/v1/now` | 有配置 `qps:500` | 使用 500 QPS |
| `/v1/users` | 无配置 | 使用 `default_qps: 1000` |
### 4.3 配置参数说明
| 参数 | 类型 | 说明 | 默认值 |
|------|------|------|--------|
| `default_qps` | float64 | 默认每秒请求数限制,0表示不限制 | 0 |
| `default_burst` | int | 默认突发容量,0表示使用default_qps值 | 0 |
| `max_concurrency` | int | 最大并发数限制,0表示不限制 | 0 |
| `method_qps` | array | 方法级配置列表 | [] |
## 5. 核心实现
### 5.1 Limiter (并发控制)
基于 **Channel 信号量**实现,移除了对自定义 `sync.Cond` 的依赖:
```go
type Limiter struct {
mu sync.Mutex
burst int // 最大并发数
sem chan struct{} // 信号量通道
}
// 创建并发限流器
func NewLimiter(b int) *Limiter
// 核心方法
func (lim *Limiter) Allow() bool // 立即获取,不等待
func (lim *Limiter) AllowN(n int) bool // 获取 n 个令牌
func (lim *Limiter) AllowFor(timeout time.Duration) bool // 带超时等待
func (lim *Limiter) AllowContext(ctx context.Context) error // Context 支持
func (lim *Limiter) Put() // 归还令牌
func (lim *Limiter) PutN(n int) // 归还 n 个令牌
// 等待方法
func (lim *Limiter) WaitFor(timeout time.Duration) error
func (lim *Limiter) WaitN(timeout time.Duration, n int) error
func (lim *Limiter) WaitContext(ctx context.Context) error
func (lim *Limiter) WaitNContext(ctx context.Context, n int) error
// 查询和动态调整
func (lim *Limiter) Burst() int // 获取最大并发数
func (lim *Limiter) Tokens() int // 获取当前可用令牌
func (lim *Limiter) Bursting() int // 获取当前正在使用的令牌数
func (lim *Limiter) SetBurst(int) // 动态调整最大并发数
```
**实现原理**:
```
┌─────────────────────────────────────────────────────────────┐
│ Limiter (Channel 信号量) │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ sem: chan struct{} (buffered channel) │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ [token] [token] [token] ... [token] │ │ │
│ │ │ ← burst 个预填充令牌 │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ Allow(): select { case <-sem: return true } │ │
│ │ Put(): select { case sem <- struct{}{}: } │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
**相比旧实现的改进**:
| 改进点 | 旧实现 | 新实现 |
|-------|-------|-------|
| 依赖 | 自定义 `sync_.Cond` | 标准库 `channel` |
| 超时机制 | `cond.WaitForDo` | `select` + `time.After` |
| Context 支持 | 无 | 原生支持 |
| 动态调整 | 无 | `SetBurst()` |
| 代码复杂度 | 较高 | 简洁 |
### 5.2 QPSLimiter
基于**令牌桶算法**实现:
```go
type QPSLimiter struct {
mu sync.Mutex
qps float64 // 每秒生成的令牌数
burst int // 桶容量(最大令牌数)
tokens float64 // 当前可用令牌
lastUpdate time.Time // 上次更新时间
}
// 创建 QPS 限流器
func NewQPSLimiter(qps float64, burst int) *QPSLimiter
// 核心方法
func (l *QPSLimiter) Allow() bool // 立即判断是否允许
func (l *QPSLimiter) AllowN(n int) bool // 请求 n 个令牌
func (l *QPSLimiter) Wait(ctx context.Context) error // 阻塞等待令牌
func (l *QPSLimiter) AllowFor(timeout time.Duration) bool // 带超时等待
```
### 5.3 MethodQPSLimiter
```go
type MethodQPSLimiter struct {
mu sync.RWMutex
limiters map[string]*QPSLimiter // 方法 -> 限流器映射
global *QPSLimiter // 默认全局限流器
}
// 方法 QPS 配置
type MethodQPSConfig struct {
Method string // API 方法名
QPS float64 // 每秒请求数
Burst int // 突发容量
}
// 创建方法级限流器
func NewMethodQPSLimiter(defaultQPS float64, defaultBurst int) *MethodQPSLimiter
func NewMethodQPSLimiterWithConfigs(defaultQPS float64, defaultBurst int,
configs []MethodQPSConfig) (*MethodQPSLimiter, error)
// 动态管理方法限流
func (m *MethodQPSLimiter) AddMethod(method string, qps float64, burst int) error
func (m *MethodQPSLimiter) SetMethodQPS(method string, qps float64, burst int) error
func (m *MethodQPSLimiter) RemoveMethod(method string)
// 限流判断(自动选择对应的限流器)
func (m *MethodQPSLimiter) Allow(method string) bool
func (m *MethodQPSLimiter) AllowFor(method string, timeout time.Duration) bool
```
### 5.4 配置转换
```go
// QPSLimitConfig 限流配置结构
type QPSLimitConfig struct {
DefaultQPS float64
DefaultBurst int
MaxConcurrency int
MethodQPS []MethodQPSConfigItem
}
// 转换为gRPC网关QPS限流配置
func (c *QPSLimitConfig) ToGRPCQPSLimitConfig() gw_.QPSLimitConfig
// 转换为HTTP QPS限流配置
func (c *QPSLimitConfig) ToHTTPQPSLimitConfig() gw_.HTTPQPSLimitConfig
```
## 6. 中间件集成
### 6.1 gRPC 拦截器
```go
// 创建方法级 QPS 限流器
limiter := ratelimit.NewMethodQPSLimiter(100, 20) // 默认 100 QPS
limiter.AddMethod("/service.UserService/GetUser", 500, 100)
limiter.AddMethod("/service.OrderService/CreateOrder", 50, 10)
// 应用拦截器
server := grpc.NewServer(
grpc.UnaryInterceptor(ratelimit.UnaryServerInterceptorQPS(limiter)),
grpc.StreamInterceptor(ratelimit.StreamServerInterceptorQPS(limiter)),
)
```
### 6.2 HTTP 中间件
```go
// 创建 QPS 限流器
limiter := ratelimit.NewQPSRateLimiter(100, 20) // 默认 100 QPS
limiter.AddPath("/api/v1/users", 500, 100)
limiter.AddPath("/api/v1/orders", 50, 10)
// 应用中间件
http.Handle("/", limiter.Handler(yourHandler))
// 暴露限流统计
http.Handle("/debug/ratelimit", limiter.StatsHandler())
```
### 6.3 通过配置自动集成
在 `webserver.Config` 中自动安装限流中间件:
```go
// installHttpMiddlewareChain 安装 HTTP 中间件链
func (c *Config) installHttpMiddlewareChain() []gw_.GRPCGatewayOption {
// ... 其他中间件
// QPS限流和并发控制(通过扩展配置)
if c.opts.httpQPSLimit != nil {
opts = append(opts, gw_.WithHttpHandlerInterceptorsQPSLimitOptions(
c.opts.httpQPSLimit.ToHTTPQPSLimitConfig(),
))
}
return opts
}
// installGrpcMiddlewareChain 安装 gRPC 中间件链
func (c *Config) installGrpcMiddlewareChain() []gw_.GRPCGatewayOption {
// ... 其他中间件
// QPS限流和并发控制(通过扩展配置)
if c.opts.grpcQPSLimit != nil {
opts = append(opts, gw_.WithServerInterceptorsQPSLimitOptions(
c.opts.grpcQPSLimit.ToGRPCQPSLimitConfig(),
))
}
return opts
}
```
## 7. 使用示例
### 7.1 并发限流器基本使用
```go
// 创建并发限流器:最大 100 并发
limiter := rate.NewLimiter(100)
// 立即获取令牌
if limiter.Allow() {
defer limiter.Put()
// 处理请求
}
// 带超时等待
if limiter.AllowFor(100 * time.Millisecond) {
defer limiter.Put()
// 处理请求
}
// 使用 Context(推荐)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err := limiter.AllowContext(ctx); err == nil {
defer limiter.Put()
// 处理请求
}
// 动态调整最大并发数
limiter.SetBurst(200)
```
### 7.2 QPS 限流器基本使用
```go
// 创建 QPS 限流器:100 QPS,允许突发 20 个请求
limiter := rate.NewQPSLimiter(100, 20)
// 判断是否允许
if limiter.Allow() {
// 处理请求
}
// 带超时等待
if limiter.AllowFor(100 * time.Millisecond) {
// 处理请求
}
// 阻塞等待
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err := limiter.Wait(ctx); err == nil {
// 处理请求
}
```
### 7.3 方法级限流
```go
// 配置不同接口的 QPS
configs := []rate.MethodQPSConfig{
{Method: "/api/v1/users", QPS: 100, Burst: 20},
{Method: "/api/v1/orders", QPS: 50, Burst: 10},
{Method: "/api/v1/products", QPS: 200, Burst: 50},
}
// 创建限流器,默认 10 QPS
limiter, _ := rate.NewMethodQPSLimiterWithConfigs(10, 5, configs)
// 使用(自动选择对应的限流器)
limiter.Allow("/api/v1/users") // 使用 100 QPS
limiter.Allow("/api/v1/orders") // 使用 50 QPS
limiter.Allow("/api/v1/unknown") // 使用默认 10 QPS
```
### 7.4 动态调整
```go
limiter := rate.NewMethodQPSLimiter(100, 20)
// 动态添加方法限流
limiter.AddMethod("/api/v1/hot-endpoint", 500, 100)
// 动态调整 QPS
limiter.SetMethodQPS("/api/v1/hot-endpoint", 1000, 200)
// 移除方法限流(使用全局限流)
limiter.RemoveMethod("/api/v1/hot-endpoint")
// 调整全局 QPS
limiter.SetGlobalQPS(200, 50)
```
### 7.5 查看统计
```go
limiter := rate.NewMethodQPSLimiter(100, 20)
limiter.AddMethod("/api/v1/users", 500, 100)
// 获取统计信息
stats := limiter.Stats()
for _, s := range stats {
fmt.Printf("Method: %s, QPS: %.0f, Burst: %d, Available: %.1f\n",
s.Method, s.QPS, s.Burst, s.Tokens)
}
// Output:
// Method: *, QPS: 100, Burst: 20, Available: 20.0
// Method: /api/v1/users, QPS: 500, Burst: 100, Available: 100.0
```
### 7.6 压测验证
```bash
# 配置 max_concurrency: 10 后进行压测
bombardier -n 30000 -c 3000 -t 10s -H Content-type:application/json -m POST http://127.0.0.1:10001/Now
# 预期结果:大量请求被限流拒绝,返回 429
# HTTP codes:
# 1xx - 0, 2xx - 2047, 3xx - 0, 4xx - 27869, 5xx - 0
# 4xx 表示被限流拒绝的请求(HTTP 429 Too Many Requests)
```
## 8. API 响应格式
### 8.1 HTTP 限流响应
**QPS 限流**:
```json
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 1
{
"error": "rate_limit_exceeded",
"message": "GET /api/v1/users is rejected by http_qps middleware, QPS limit exceeded",
"code": 429
}
```
**并发数限流**:
```json
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{
"error": "concurrency_limit_exceeded",
"message": "POST /Now is rejected by http_concurrency middleware, max concurrency exceeded",
"code": 429
}
```
### 8.2 gRPC 限流响应
```
code: RESOURCE_EXHAUSTED
message: "/service.UserService/GetUser is rejected, QPS limit exceeded"
```
## 9. 文件结构
```
go/time/rate/
├── rate.go # 并发控制限流器(信号量)
├── rate_method.go # 方法级并发限流器
├── rate_qps.go # QPS 限流器(令牌桶)
├── rate_qps_method.go # 方法级 QPS 限流器
├── rate_qps_test.go # QPS 限流器测试
└── rate_test.go # 并发限流器测试
pkg/webserver/
├── config.go # Web 服务配置(安装限流中间件)
├── config.option.go # 配置选项
├── webserver.proto # Proto 定义
├── webserver.yaml # 示例配置
└── webserver_qps_limit.go # QPS 限流配置转换
pkg/grpc-gateway/
├── grpc_gateway_grpc.option.go # gRPC QPS 限流选项
└── grpc_gateway_http.option.go # HTTP QPS 限流选项
pkg/middleware/grpc-middleware/ratelimit/
├── ratelimit_server.interceptor.go # 并发限流拦截器
└── ratelimit_qps_server.interceptor.go # QPS 限流拦截器
pkg/middleware/http-middleware/ratelimiter/
├── ratelimiter.go # 并发限流中间件
└── ratelimiter_qps.go # QPS 限流中间件
```
## 10. 设计特点总结
| 特点 | 说明 |
|------|------|
| 双重限流 | 同时支持 QPS 限流(令牌桶)和并发控制(Channel 信号量) |
| 配置统一 | 限流配置统一放在 `web.qps_limit` 下,结构清晰 |
| 方法级配置 | 支持为不同 API 接口配置不同的限流策略 |
| 动态调整 | 运行时动态添加、修改、删除方法限流配置,支持 `SetBurst()` |
| 等待模式 | 支持立即返回、带超时等待、阻塞等待三种模式 |
| Context 支持 | 原生支持 `context.Context`,符合 Go 惯例 |
| 统计信息 | 提供限流统计接口,便于监控和调试 |
| 线程安全 | 使用 Channel 和互斥锁保证并发安全 |
| 无外部依赖 | 仅依赖标准库,移除了对自定义 `sync.Cond` 的依赖 |
| 向后兼容 | 旧的 `max_concurrency_unary` 等配置已废弃,统一使用新配置 |
## 11. 废弃配置说明
以下配置已废弃,统一使用 `web.qps_limit` 配置:
| 废弃配置 | 新配置 |
|---------|-------|
| `web.grpc.max_concurrency_unary` | `web.qps_limit.grpc.max_concurrency` |
| `web.grpc.max_concurrency_stream` | `web.qps_limit.grpc.max_concurrency` |
| `web.http.max_concurrency` | `web.qps_limit.http.max_concurrency` |
## 12. 实现演进
### 12.1 Limiter 重构(v2.0)
**变更原因**:
- 旧实现依赖自定义 `sync_.Cond`,增加了维护成本
- 自定义 Cond 的超时实现复杂,不如 Channel 原生支持
**变更内容**:
| 项目 | 旧实现 | 新实现 |
|------|-------|-------|
| 核心数据结构 | `tokens int` + `sync_.Cond` | `sem chan struct{}` |
| 超时等待 | `cond.WaitForDo(timeout, pred, do)` | `select { case <-sem: case <-time.After(timeout): }` |
| Context 支持 | 无 | `AllowContext()`, `WaitContext()` |
| 动态调整 | 无 | `SetBurst()` |
| 依赖 | `github.com/kaydxh/golang/go/sync` | 仅标准库 |
**API 兼容性**:
- ✅ `Allow()`, `AllowFor()`, `AllowWaitUntil()` - 签名不变
- ✅ `Put()`, `PutN()` - 签名不变
- ✅ `WaitFor()`, `WaitN()` - 签名不变
- ✅ `Burst()`, `Bursting()` - 签名不变
- ➕ 新增 `Tokens()`, `SetBurst()`, `AllowN()`, `AllowContext()`, `WaitContext()`, `WaitNContext()`
================================================
FILE: doc.go
================================================
package golang
import _ "github.com/kaydxh/golang/go"
================================================
FILE: go/archive/archive.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package archive
import (
"github.com/kaydxh/golang/go/archive/option"
)
// Archiver defines the interface for archive extraction operations
type Archiver interface {
// Extract extracts all files from srcFile to destDir and returns a list of extracted file info
Extract(srcFile, destDir string) ([]*option.FileInfo, error)
// ExtractStream extracts files from srcFile to destDir and streams the results through a channel
ExtractStream(srcFile, destDir string) <-chan option.ExtractMsg
}
================================================
FILE: go/archive/option/file_info.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package option
import (
"fmt"
"os"
)
type FileInfo struct {
Path string
FileInfo os.FileInfo
}
func (e *FileInfo) String() string {
return fmt.Sprintf(
"{path: [%v], size: [%v], modeTime: [%v]}",
e.Path,
e.FileInfo.Size(),
e.FileInfo.ModTime(),
)
}
type ExtractMsg struct {
FileInfo *FileInfo
Error error
}
func (e *ExtractMsg) String() string {
if e.Error != nil {
return fmt.Sprintf("{error: %v}", e.Error)
}
if e.FileInfo == nil {
return "{fileInfo: nil}"
}
return fmt.Sprintf(
"{path: [%v], size: [%v], modeTime: [%v]}",
e.FileInfo.Path,
e.FileInfo.FileInfo.Size(),
e.FileInfo.FileInfo.ModTime(),
)
}
================================================
FILE: go/archive/zip/zip.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package zip
import (
"archive/zip"
"bytes"
"fmt"
"io"
"path/filepath"
"strings"
"unicode/utf8"
"github.com/kaydxh/golang/go/archive/option"
os_ "github.com/kaydxh/golang/go/os"
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/transform"
)
// Zip implements the Archiver interface for ZIP archive extraction
type Zip struct {
}
func (z Zip) Extract(srcFile, destDir string) ([]*option.FileInfo, error) {
r, err := zip.OpenReader(srcFile)
if err != nil {
return nil, fmt.Errorf("failed to open zip file %s: %w", srcFile, err)
}
defer r.Close()
err = os_.MakeDirAll(destDir)
if err != nil {
return nil, fmt.Errorf("failed to create destination directory %s: %w", destDir, err)
}
var extractedFiles []*option.FileInfo
for _, f := range r.File {
fileInfo, err := z.extractAndWriteFile(destDir, f)
if err != nil {
return nil, fmt.Errorf("failed to extract file %s: %w", f.Name, err)
}
if fileInfo != nil {
extractedFiles = append(extractedFiles, fileInfo)
}
}
return extractedFiles, nil
}
func (z Zip) ExtractStream(
srcFile, destDir string,
) <-chan option.ExtractMsg {
fileInfoCh := make(chan option.ExtractMsg, 1024)
go func() {
defer close(fileInfoCh)
r, err := zip.OpenReader(srcFile)
if err != nil {
fileInfoCh <- option.ExtractMsg{
Error: fmt.Errorf("failed to open zip file %s: %w", srcFile, err),
}
return
}
defer r.Close()
err = os_.MakeDirAll(destDir)
if err != nil {
fileInfoCh <- option.ExtractMsg{
Error: fmt.Errorf("failed to create destination directory %s: %w", destDir, err),
}
return
}
for _, f := range r.File {
fileInfo, err := z.extractAndWriteFile(destDir, f)
if err != nil {
fileInfoCh <- option.ExtractMsg{
Error: fmt.Errorf("failed to extract file %s: %w", f.Name, err),
}
// Continue processing other files instead of returning
continue
}
if fileInfo != nil {
fileInfoCh <- option.ExtractMsg{
FileInfo: fileInfo,
Error: nil,
}
}
}
}()
return fileInfoCh
}
func (z Zip) extractAndWriteFile(
destDir string,
f *zip.File,
) (*option.FileInfo, error) {
if f == nil {
return nil, fmt.Errorf("invalid zip file")
}
decodeName := f.Name
if !utf8.Valid([]byte(f.Name)) {
i := bytes.NewReader([]byte(f.Name))
decoder := transform.NewReader(
i,
simplifiedchinese.GB18030.NewDecoder(),
)
content, err := io.ReadAll(decoder)
if err != nil {
return nil, fmt.Errorf("failed to decode filename %s: %w", f.Name, err)
}
decodeName = string(content)
}
baseName := filepath.Base(f.Name)
if strings.HasPrefix(baseName, ".") {
return nil, nil
}
rc, err := f.Open()
if err != nil {
return nil, fmt.Errorf("failed to open file %s from zip: %w", f.Name, err)
}
defer func() {
if closeErr := rc.Close(); closeErr != nil {
// If there's already an error, wrap it; otherwise set the close error
if err != nil {
err = fmt.Errorf("%w; close error: %v", err, closeErr)
} else {
err = fmt.Errorf("failed to close file %s: %w", f.Name, closeErr)
}
}
}()
// Security check: prevent zip slip attack by ensuring the resolved path is within destDir
path := filepath.Join(destDir, decodeName)
resolvedPath, err := filepath.Abs(path)
if err != nil {
return nil, fmt.Errorf("failed to resolve path %s: %w", path, err)
}
destDirAbs, err := filepath.Abs(destDir)
if err != nil {
return nil, fmt.Errorf("failed to resolve destination directory %s: %w", destDir, err)
}
if !strings.HasPrefix(resolvedPath, destDirAbs+string(filepath.Separator)) && resolvedPath != destDirAbs {
return nil, fmt.Errorf("zip slip detected: file path %s is outside destination directory %s", decodeName, destDir)
}
if f.FileInfo().IsDir() {
err = os_.MakeDirAll(resolvedPath)
if err != nil {
return nil, fmt.Errorf("failed to create directory %s: %w", resolvedPath, err)
}
return nil, nil
}
fn, err := os_.OpenFile(resolvedPath, false)
if err != nil {
return nil, fmt.Errorf("failed to create file %s: %w", resolvedPath, err)
}
defer fn.Close()
_, err = io.Copy(fn, rc)
if err != nil {
return nil, fmt.Errorf("failed to write file %s: %w", resolvedPath, err)
}
return &option.FileInfo{
Path: fn.Name(),
FileInfo: f.FileInfo(),
}, nil
}
================================================
FILE: go/archive/zip/zip_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package zip_test
import (
"testing"
zip_ "github.com/kaydxh/golang/go/archive/zip"
)
func TestExtractZip(t *testing.T) {
srcFile := "./新词词典.zip"
destDir := "unzip"
fileInfos, err := zip_.Zip{}.Extract(srcFile, destDir)
if err != nil {
t.Errorf("failed to Extract zip file: [%v], err: [%v]", srcFile, err)
}
t.Logf("extract file: [%v], result: [%+v]", srcFile, fileInfos)
/*
for extractMsg := range zip_.Zip{}.Extract(srcFile, destDir) {
if extractMsg.Err != nil {
fmt.Println(msg.Error)
} else {
fmt.Printf("fileInfo:[%v]", *msg.FileInfo)
}
}
*/
}
================================================
FILE: go/bytes/bytes.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package bytes
import (
"reflect"
"unsafe"
)
func Truncate(s []byte, n int) []byte {
if n < 0 {
n = 0
}
if len(s) <= n {
return s
}
return s[:n]
}
func Encode[T any](m T) []byte {
if reflect.ValueOf(m).IsZero() {
return nil
}
sz := int(unsafe.Sizeof(m))
p := make([]byte, sz)
slice := (*reflect.SliceHeader)(unsafe.Pointer(&p))
slice.Data = uintptr(unsafe.Pointer(&m))
slice.Len = sz
slice.Cap = sz
return p
}
func Decode[T any](b []byte) T {
var zero T
if len(b) == 0 {
return zero
}
var m T = *(*T)(unsafe.Pointer(&b[0]))
return m
}
================================================
FILE: go/bytes/bytes_test.go
================================================
package bytes_test
import (
"fmt"
"testing"
"unsafe"
bytes_ "github.com/kaydxh/golang/go/bytes"
)
func TestEncodeAndDecode(t *testing.T) {
// to bytes
type MyStruct struct {
X, Y, Z int
Name string
}
testCases := []struct {
s MyStruct
expected string
}{
{
s: MyStruct{1, 20, 30, "foobar"},
expected: "",
},
}
const sz = int(unsafe.Sizeof(MyStruct{}))
fmt.Printf("MyStruct size: %v\n", int(unsafe.Sizeof(MyStruct{})))
for i, testCase := range testCases {
t.Run(fmt.Sprintf("case-%d", i), func(t *testing.T) {
b := bytes_.Encode(testCase.s)
fmt.Println(b)
fmt.Printf("size of b: %v\n", len(b))
/*
var p []byte = (*(*[sz]byte)(unsafe.Pointer(&testCase.s)))[:]
fmt.Println(p)
fmt.Printf("size of p: %v\n", len(p))
*/
/*
var m = *(*MyStruct)(unsafe.Pointer(&b[0]))
fmt.Println(m)
*/
r := bytes_.Decode[MyStruct](b)
fmt.Println(r)
})
}
}
================================================
FILE: go/client/client.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package client
import (
"log"
)
type Client struct {
// options
opts struct {
Path string
ErrorLog *log.Logger
}
}
func New(options ...ClientOption) *Client {
c := &Client{}
c.ApplyOptions(options...)
return c
}
func (c *Client) logf(format string, args ...interface{}) {
if c.opts.ErrorLog != nil {
c.opts.ErrorLog.Printf(format, args...)
} else {
log.Printf(format, args...)
}
}
================================================
FILE: go/client/client.options.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package client
func WithClientOptionPath(path string) ClientOption {
return ClientOptionFunc(func(opt *Client) {
opt.opts.Path = path
})
}
================================================
FILE: go/client/client_options.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package client
// A ClientOption sets options.
type ClientOption interface {
apply(*Client)
}
// EmptyClientUrlOption does not alter the Clienturation. It can be embedded
// in another structure to build custom options.
//
// This API is EXPERIMENTAL.
type EmptyClientOption struct{}
func (EmptyClientOption) apply(*Client) {}
// ClientOptionFunc wraps a function that modifies Client into an
// implementation of the ClientOption interface.
type ClientOptionFunc func(*Client)
func (f ClientOptionFunc) apply(do *Client) {
f(do)
}
// sample code for option, default for nothing to change
func _ClientOptionWithDefault() ClientOption {
return ClientOptionFunc(func(*Client) {
// nothing to change
})
}
func (o *Client) ApplyOptions(options ...ClientOption) *Client {
for _, opt := range options {
if opt == nil {
continue
}
opt.apply(o)
}
return o
}
================================================
FILE: go/client/client_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package client_test
import (
"fmt"
"testing"
"github.com/kaydxh/golang/go/client"
)
func TestNew(t *testing.T) {
conf := client.New(client.WithClientOptionPath("/data/conf"))
fmt.Println(conf)
}
================================================
FILE: go/container/heap/heap.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package heap
import (
"container/heap"
"fmt"
"sync"
)
const (
closedMsg = "heap is closed"
)
// LessFunc is used to compare two objects in the heap.
type LessFunc func(interface{}, interface{}) bool
// KeyFunc knows how to make a key from an object. Implementations
// should be deterministic.
type KeyFunc func(interface{}) string
type heapItem struct {
obj interface{} // The object which is stored in the heap.
index int // The index of the object's key in the Heap.queue.
}
type itemKeyValue struct {
key string
obj interface{}
}
// heapData is an internal struct that implements the standard heap interface
// and keeps the data stored in the heap.
type heapData struct {
// items is a map from key of the objects to the objects and their index.
// We depend on the property that items in the map are in the queue and vice versa.
items map[string]*heapItem
// queue implements a heap data structure and keeps the order of elements
// according to the heap invariant. The queue keeps the keys of objects stored
// in "items".
queue []string
// keyFunc is used to make the key used for queued item insertion and retrieval, and
// should be deterministic.
keyFunc KeyFunc
// lessFunc is used to compare two objects in the heap.
lessFunc LessFunc
}
var (
_ = heap.Interface(&heapData{}) // heapData is a standard heap
)
// Less compares two objects and returns true if the first one should go
// in front of the second one in the heap.
func (h *heapData) Less(i, j int) bool {
if i > len(h.queue) || j > len(h.queue) {
return false
}
itemi, ok := h.items[h.queue[i]]
if !ok {
return false
}
itemj, ok := h.items[h.queue[j]]
if !ok {
return false
}
return h.lessFunc(itemi.obj, itemj.obj)
}
// Len returns the number of items in the Heap.
func (h *heapData) Len() int { return len(h.queue) }
// Swap implements swapping of two elements in the heap. This is a part of standard
// heap interface and should never be called directly.
func (h *heapData) Swap(i, j int) {
h.queue[i], h.queue[j] = h.queue[j], h.queue[i]
item := h.items[h.queue[i]]
item.index = i
item = h.items[h.queue[j]]
item.index = j
}
// Push is supposed to be called by heap.Push only.
func (h *heapData) Push(kv interface{}) {
keyValue := kv.(*itemKeyValue)
n := len(h.queue)
h.items[keyValue.key] = &heapItem{keyValue.obj, n}
h.queue = append(h.queue, keyValue.key)
}
// Pop is supposed to be called by heap.Pop only.
func (h *heapData) Pop() interface{} {
key := h.queue[len(h.queue)-1]
h.queue = h.queue[0 : len(h.queue)-1]
item, ok := h.items[key]
if !ok {
// This is an error
return nil
}
delete(h.items, key)
return item.obj
}
// Heap is a thread-safe producer/consumer queue that implements a heap data structure.
// It can be used to implement priority queues and similar data structures.
type Heap struct {
lock sync.RWMutex
cond sync.Cond
// data stores objects and has a queue that keeps their ordering according
// to the heap invariant.
data *heapData
// closed indicates that the queue is closed.
// It is mainly used to let Pop() exit its control loop while waiting for an item.
closed bool
}
// Close the Heap and signals condition variables that may be waiting to pop
// items from the heap.
func (h *Heap) Close() {
h.lock.Lock()
defer h.lock.Unlock()
h.closed = true
h.cond.Broadcast()
}
// Add inserts an item, and puts it in the queue. The item is updated if it
// already exists.
func (h *Heap) Add(obj interface{}) error {
key := h.data.keyFunc(obj)
h.lock.Lock()
defer h.lock.Unlock()
if h.closed {
return fmt.Errorf(closedMsg)
}
if _, exists := h.data.items[key]; exists {
h.data.items[key].obj = obj
heap.Fix(h.data, h.data.items[key].index)
} else {
h.addIfNotPresentLocked(key, obj)
}
h.cond.Broadcast()
return nil
}
// BulkAdd adds all the items in the list to the queue and then signals the condition
// variable. It is useful when the caller would like to add all of the items
// to the queue before consumer starts processing them.
func (h *Heap) BulkAdd(list []interface{}) error {
h.lock.Lock()
defer h.lock.Unlock()
if h.closed {
return fmt.Errorf(closedMsg)
}
for _, obj := range list {
key := h.data.keyFunc(obj)
if _, exists := h.data.items[key]; exists {
h.data.items[key].obj = obj
heap.Fix(h.data, h.data.items[key].index)
} else {
h.addIfNotPresentLocked(key, obj)
}
}
h.cond.Broadcast()
return nil
}
// AddIfNotPresent inserts an item, and puts it in the queue. If an item with
// the key is present in the map, no changes is made to the item.
//
// This is useful in a single producer/consumer scenario so that the consumer can
// safely retry items without contending with the producer and potentially enqueueing
// stale items.
func (h *Heap) AddIfNotPresent(obj interface{}) error {
id := h.data.keyFunc(obj)
h.lock.Lock()
defer h.lock.Unlock()
if h.closed {
return fmt.Errorf(closedMsg)
}
h.addIfNotPresentLocked(id, obj)
h.cond.Broadcast()
return nil
}
// AddIfHeapOrder inserts an item, and puts it in the queue. If an item with
// the key is present in the map, and new obj meet the sort of heap,
// then update the item, or no changes is made to the item.
func (h *Heap) AddIfHeapOrder(obj interface{}) error {
key := h.data.keyFunc(obj)
h.lock.Lock()
defer h.lock.Unlock()
if h.closed {
return fmt.Errorf(closedMsg)
}
if existedObj, exists := h.data.items[key]; exists {
if !h.data.lessFunc(existedObj.obj, obj) {
h.data.items[key].obj = obj
heap.Fix(h.data, h.data.items[key].index)
}
} else {
h.addIfNotPresentLocked(key, obj)
}
h.cond.Broadcast()
return nil
}
// addIfNotPresentLocked assumes the lock is already held and adds the provided
// item to the queue if it does not already exist.
func (h *Heap) addIfNotPresentLocked(key string, obj interface{}) {
if _, exists := h.data.items[key]; exists {
return
}
heap.Push(h.data, &itemKeyValue{key, obj})
}
// Update is the same as Add in this implementation. When the item does not
// exist, it is added.
func (h *Heap) Update(obj interface{}) error {
return h.Add(obj)
}
// Delete removes an item.
func (h *Heap) Delete(obj interface{}) error {
key := h.data.keyFunc(obj)
h.lock.Lock()
defer h.lock.Unlock()
if item, ok := h.data.items[key]; ok {
heap.Remove(h.data, item.index)
return nil
}
return fmt.Errorf("object not found")
}
// Pop waits until an item is ready. If multiple items are
// ready, they are returned in the order given by Heap.data.lessFunc.
func (h *Heap) Pop() (interface{}, error) {
h.lock.Lock()
defer h.lock.Unlock()
for len(h.data.queue) == 0 {
// When the queue is empty, invocation of Pop() is blocked until new item is enqueued.
// When Close() is called, the h.closed is set and the condition is broadcast,
// which causes this loop to continue and return from the Pop().
if h.closed {
return nil, fmt.Errorf("heap is closed")
}
h.cond.Wait()
}
obj := heap.Pop(h.data)
if obj == nil {
return nil, fmt.Errorf("object was removed from heap data")
}
return obj, nil
}
// List returns a list of all the items.
func (h *Heap) List() []interface{} {
h.lock.RLock()
defer h.lock.RUnlock()
list := make([]interface{}, 0, len(h.data.items))
for _, item := range h.data.items {
list = append(list, item.obj)
}
return list
}
// ListKeys returns a list of all the keys of the objects currently in the Heap.
// Note: the key order is random, because it's data structure is map
func (h *Heap) ListKeys() []string {
h.lock.RLock()
defer h.lock.RUnlock()
list := make([]string, 0, len(h.data.items))
for key := range h.data.items {
list = append(list, key)
}
return list
}
// Get returns the requested item, or sets exists=false.
// return item.obj, exists
func (h *Heap) Get(obj interface{}) (interface{}, bool) {
key := h.data.keyFunc(obj)
return h.GetByKey(key)
}
// GetByKey returns the requested item, or sets exists=false.
func (h *Heap) GetByKey(key string) (interface{}, bool) {
h.lock.RLock()
defer h.lock.RUnlock()
item, exists := h.data.items[key]
if !exists {
return nil, false
}
return item.obj, true
}
// IsClosed returns true if the queue is closed.
func (h *Heap) IsClosed() bool {
h.lock.RLock()
defer h.lock.RUnlock()
if h.closed {
return true
}
return false
}
// NewHeap returns a Heap which can be used to queue up items to process.
func NewHeap(keyFn KeyFunc, lessFn LessFunc) *Heap {
h := &Heap{
data: &heapData{
items: map[string]*heapItem{},
queue: []string{},
keyFunc: keyFn,
lessFunc: lessFn,
},
}
h.cond.L = &h.lock
return h
}
================================================
FILE: go/container/heap/heap_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package heap_test
import (
"sync"
"testing"
heap_ "github.com/kaydxh/golang/go/container/heap"
)
func testHeapObjectKeyFunc(obj interface{}) string {
return obj.(testHeapObject).name
}
type testHeapObject struct {
name string
val interface{}
}
func mkHeapObj(name string, val interface{}) testHeapObject {
return testHeapObject{name: name, val: val}
}
//minheap
func compareInts(val1 interface{}, val2 interface{}) bool {
first := val1.(testHeapObject).val.(int)
second := val2.(testHeapObject).val.(int)
return first < second
}
// TestHeapBasic tests Heap invariant and synchronization.
func TestHeapBasic(t *testing.T) {
h := heap_.NewHeap(testHeapObjectKeyFunc, compareInts)
var wg sync.WaitGroup
wg.Add(2)
const amount = 10
var i, u int
// Insert items in the heap in opposite orders in two go routines.
go func() {
for i = amount; i > 0; i-- {
h.Add(mkHeapObj(string([]rune{'a', rune(i)}), i))
}
wg.Done()
}()
go func() {
for u = 0; u < amount; u++ {
h.Add(mkHeapObj(string([]rune{'b', rune(u)}), u+1))
}
wg.Done()
}()
// Wait for the two go routines to finish.
wg.Wait()
t.Logf("heap: %+v", h.List())
// Make sure that the numbers are popped in ascending order.
prevNum := 0
for i := 0; i < amount*2; i++ {
obj, err := h.Pop()
num := obj.(testHeapObject).val.(int)
// All the items must be sorted.
if err != nil || prevNum > num {
t.Errorf("got %v out of order, last was %v", obj, prevNum)
}
t.Logf("get %v", num)
prevNum = num
}
}
// TestHeap_Get tests Heap.Get.
func TestHeap_Get(t *testing.T) {
h := heap_.NewHeap(testHeapObjectKeyFunc, compareInts)
h.Add(mkHeapObj("foo", 10))
h.Add(mkHeapObj("bar", 1))
h.Add(mkHeapObj("bal", 31))
h.Add(mkHeapObj("baz", 11))
// Get works with the key.
obj, exists := h.Get(mkHeapObj("baz", 0))
if !exists || obj.(testHeapObject).val != 11 {
t.Fatalf("unexpected error in getting element")
}
// Get non-existing object.
_, exists = h.Get(mkHeapObj("non-existing", 0))
if exists {
t.Fatalf("didn't expect to get any object")
}
}
// TestHeap_GetByKey tests Heap.GetByKey and is very similar to TestHeap_Get.
func TestHeap_GetByKey(t *testing.T) {
h := heap_.NewHeap(testHeapObjectKeyFunc, compareInts)
h.Add(mkHeapObj("foo", 10))
h.Add(mkHeapObj("bar", 1))
h.Add(mkHeapObj("bal", 31))
h.Add(mkHeapObj("baz", 11))
obj, exists := h.GetByKey("baz")
if exists == false || obj.(testHeapObject).val != 11 {
t.Fatalf("unexpected error in getting element")
}
// Get non-existing object.
_, exists = h.GetByKey("non-existing")
if exists {
t.Fatalf("didn't expect to get any object")
}
}
type Student struct {
Id string
Name string
Score float32
}
func testStudentObjectKeyFunc(obj interface{}) string {
return obj.(*Student).Id
}
//maxheap
func compareStudentScore(val1 interface{}, val2 interface{}) bool {
first := val1.(*Student).Score
second := val2.(*Student).Score
return first > second
}
func TestMaxHeap(t *testing.T) {
h := heap_.NewHeap(testStudentObjectKeyFunc, compareStudentScore)
h.AddIfHeapOrder(&Student{
Id: "id_1",
Name: "name_1",
Score: 89.2,
})
h.AddIfHeapOrder(&Student{
Id: "id_2",
Name: "name_2",
Score: 87.2,
})
h.AddIfHeapOrder(&Student{
Id: "id_3",
Name: "name_3",
Score: 97.2,
})
h.AddIfHeapOrder(&Student{
Id: "id_1",
Name: "name_3",
Score: 88.2,
})
t.Logf("list key: %v", h.ListKeys())
sz := len(h.ListKeys())
for i := 0; i < sz; i++ {
obj, err := h.Pop()
if err != nil {
t.Fatalf("failed to pop, err: %v", err)
}
t.Logf("get obj: %v", obj.(*Student))
}
}
================================================
FILE: go/container/set/set.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package set
import (
"encoding/json"
"sort"
)
// type Set[type T comparable] map[T]Empty
type Set[T comparable] map[T]Empty
func New[T comparable](items ...T) Set[T] {
// func New[T comparable]() Set[T] {
ss := make(Set[T], len(items))
ss.Insert(items...)
return ss
}
// Insert adds items to the set.
func (s Set[T]) Insert(items ...T) Set[T] {
for _, item := range items {
s[item] = Empty{}
}
return s
}
// Delete removes all items from the set.
func (s Set[T]) Delete(items ...T) Set[T] {
for _, item := range items {
delete(s, item)
}
return s
}
// Has returns true if and only if item is contained in the set.
func (s Set[T]) Has(item T) bool {
_, contained := s[item]
return contained
}
// HasAll returns true if and only if all items are contained in the set.
func (s Set[T]) HasAll(items ...T) bool {
for _, item := range items {
if !s.Has(item) {
return false
}
}
return true
}
// HasAny returns true if any items are contained in the set.
func (s Set[T]) HasAny(items ...T) bool {
for _, item := range items {
if s.Has(item) {
return true
}
}
return false
}
// Difference returns a set of objects that are not in s2
// For example:
// s1 = {a1, a2, a3}
// s2 = {a1, a2, a4, a5}
// s1.Difference(s2) = {a3}
// s2.Difference(s1) = {a4, a5}
func (s Set[T]) Difference(s2 Set[T]) Set[T] {
result := New[T]()
for key := range s {
if !s2.Has(key) {
result.Insert(key)
}
}
return result
}
// Union returns a new set which includes items in either s1 or s2.
// For example:
// s1 = {a1, a2}
// s2 = {a3, a4}
// s1.Union(s2) = {a1, a2, a3, a4}
// s2.Union(s1) = {a1, a2, a3, a4}
func (s1 Set[T]) Union(s2 Set[T]) Set[T] {
result := New[T]()
for key := range s1 {
result.Insert(key)
}
for key := range s2 {
result.Insert(key)
}
return result
}
// Intersection returns a new set which includes the item in BOTH s1 and s2
// For example:
// s1 = {a1, a2}
// s2 = {a2, a3}
// s1.Intersection(s2) = {a2}
func (s1 Set[T]) Intersection(s2 Set[T]) Set[T] {
var walk, other Set[T]
result := New[T]()
if s1.Len() < s2.Len() {
walk = s1
other = s2
} else {
walk = s2
other = s1
}
for key := range walk {
if other.Has(key) {
result.Insert(key)
}
}
return result
}
// IsSuperset returns true if and only if s1 is a superset of s2.
func (s1 Set[T]) IsSuperset(s2 Set[T]) bool {
for item := range s2 {
if !s1.Has(item) {
return false
}
}
return true
}
// Equal returns true if and only if s1 is equal (as a set) to s2.
// Two sets are equal if their membership is identical.
// (In practice, this means same elements, order doesn't matter)
func (s1 Set[T]) Equal(s2 Set[T]) bool {
return len(s1) == len(s2) && s1.IsSuperset(s2)
}
type sortableSliceOfT[T comparable] []T
func (s sortableSliceOfT[T]) Len() int { return len(s) }
func (s sortableSliceOfT[T]) Less(i, j int) bool { return lessT(s[i], s[j]) }
func (s sortableSliceOfT[T]) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// List returns the contents as a sorted Object slice.
func (s Set[T]) List() []T {
res := make(sortableSliceOfT[T], 0, len(s))
for key := range s {
res = append(res, key)
}
sort.Sort(res)
return []T(res)
}
// UnsortedList returns the slice with contents in random order.
func (s Set[T]) UnsortedList() []T {
res := make([]T, 0, len(s))
for key := range s {
res = append(res, key)
}
return res
}
// Returns a single element from the set.
func (s Set[T]) PopAny() (T, bool) {
for key := range s {
s.Delete(key)
return key, true
}
var zeroValue T
return zeroValue, false
}
// Len returns the size of the set.
func (s Set[T]) Len() int {
return len(s)
}
type LesserT[T comparable] interface {
Less(a, b T) bool
}
func lessT[T comparable](lhs, rhs T) bool {
jbl, err := json.Marshal(lhs)
if err != nil {
return false
}
jbr, err := json.Marshal(rhs)
if err != nil {
return false
}
return string(jbl) < string(jbr)
}
================================================
FILE: go/container/set/set.interface.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package set
import (
"encoding/json"
"reflect"
"sort"
)
// sets.Object is a set of Objects, implemented via map[Object]struct{} for minimal memory consumption.
type Object map[interface{}]Empty
// NewObject creates a Object from a list of values.
func NewObject(items ...interface{}) Object {
ss := Object{}
ss.Insert(items...)
return ss
}
// ObjectKeySet creates a Object from a keys of a map[Object](? extends interface{}).
// If the value passed in is not actually a map, this will panic.
func KeySet(theMap interface{}) Object {
v := reflect.ValueOf(theMap)
ret := Object{}
for _, keyValue := range v.MapKeys() {
ret.Insert(keyValue.Interface().(Object))
}
return ret
}
// Insert adds items to the set.
func (s Object) Insert(items ...interface{}) Object {
for _, item := range items {
s[item] = Empty{}
}
return s
}
// Delete removes all items from the set.
func (s Object) Delete(items ...interface{}) Object {
for _, item := range items {
delete(s, item)
}
return s
}
// Has returns true if and only if item is contained in the set.
func (s Object) Has(item interface{}) bool {
_, contained := s[item]
return contained
}
// HasAll returns true if and only if all items are contained in the set.
func (s Object) HasAll(items ...interface{}) bool {
for _, item := range items {
if !s.Has(item) {
return false
}
}
return true
}
// HasAny returns true if any items are contained in the set.
func (s Object) HasAny(items ...interface{}) bool {
for _, item := range items {
if s.Has(item) {
return true
}
}
return false
}
// Difference returns a set of objects that are not in s2
// For example:
// s1 = {a1, a2, a3}
// s2 = {a1, a2, a4, a5}
// s1.Difference(s2) = {a3}
// s2.Difference(s1) = {a4, a5}
func (s Object) Difference(s2 Object) Object {
result := NewObject()
for key := range s {
if !s2.Has(key) {
result.Insert(key)
}
}
return result
}
// Union returns a new set which includes items in either s1 or s2.
// For example:
// s1 = {a1, a2}
// s2 = {a3, a4}
// s1.Union(s2) = {a1, a2, a3, a4}
// s2.Union(s1) = {a1, a2, a3, a4}
func (s1 Object) Union(s2 Object) Object {
result := NewObject()
for key := range s1 {
result.Insert(key)
}
for key := range s2 {
result.Insert(key)
}
return result
}
// Intersection returns a new set which includes the item in BOTH s1 and s2
// For example:
// s1 = {a1, a2}
// s2 = {a2, a3}
// s1.Intersection(s2) = {a2}
func (s1 Object) Intersection(s2 Object) Object {
var walk, other Object
result := NewObject()
if s1.Len() < s2.Len() {
walk = s1
other = s2
} else {
walk = s2
other = s1
}
for key := range walk {
if other.Has(key) {
result.Insert(key)
}
}
return result
}
// IsSuperset returns true if and only if s1 is a superset of s2.
func (s1 Object) IsSuperset(s2 Object) bool {
for item := range s2 {
if !s1.Has(item) {
return false
}
}
return true
}
// Equal returns true if and only if s1 is equal (as a set) to s2.
// Two sets are equal if their membership is identical.
// (In practice, this means same elements, order doesn't matter)
func (s1 Object) Equal(s2 Object) bool {
return len(s1) == len(s2) && s1.IsSuperset(s2)
}
type sortableSliceOfObject []interface{}
func (s sortableSliceOfObject) Len() int { return len(s) }
func (s sortableSliceOfObject) Less(i, j int) bool { return lessObject(s[i], s[j]) }
func (s sortableSliceOfObject) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// List returns the contents as a sorted Object slice.
func (s Object) List() []interface{} {
res := make(sortableSliceOfObject, 0, len(s))
for key := range s {
res = append(res, key)
}
sort.Sort(res)
return []interface{}(res)
}
// UnsortedList returns the slice with contents in random order.
func (s Object) UnsortedList() []interface{} {
res := make([]interface{}, 0, len(s))
for key := range s {
res = append(res, key)
}
return res
}
// Returns a single element from the set.
func (s Object) PopAny() (interface{}, bool) {
for key := range s {
s.Delete(key)
return key, true
}
var zeroValue Object
return zeroValue, false
}
// Len returns the size of the set.
func (s Object) Len() int {
return len(s)
}
type Lesser interface {
Less(a interface{}, b interface{}) bool
}
/*
func lessObject(lhs, rhs interface{}) bool {
if lhs == nil {
return false
}
if rhs == nil {
return true
}
switch lhs := lhs.(type) {
case nil:
return false
case *string:
rhs, ok := rhs.(*string)
if !ok {
return false
}
return lhs != nil && rhs != nil && *lhs < *rhs
case *[]byte:
rhs, ok := rhs.(*[]byte)
if !ok {
return false
}
return lhs != nil && rhs != nil && string(*lhs) < string(*rhs)
case *int:
rhs, ok := rhs.(*int)
if !ok {
return false
}
return lhs != nil && rhs != nil && *lhs < *rhs
case *int32:
rhs, ok := rhs.(*int32)
if !ok {
return false
}
return lhs != nil && rhs != nil && *lhs < *rhs
case *uint32:
rhs, ok := rhs.(*uint32)
if !ok {
return false
}
return lhs != nil && rhs != nil && *lhs < *rhs
case *int64:
rhs, ok := rhs.(*int64)
if !ok {
return false
}
return lhs != nil && rhs != nil && *lhs < *rhs
case *uint64:
rhs, ok := rhs.(*uint64)
if !ok {
return false
}
return lhs != nil && rhs != nil && *lhs < *rhs
case *float32:
rhs, ok := rhs.(*float32)
if !ok {
return false
}
return lhs != nil && rhs != nil && *lhs < *rhs
case *float64:
rhs, ok := rhs.(*float64)
if !ok {
return false
}
return lhs != nil && rhs != nil && *lhs < *rhs
default:
var ll Lesser
ll, ok = lhs.(Lesser)
if !ok {
}
var err error
jb, err = json.Marshal(v)
if err != nil {
return nil, fmt.Errorf("jsonpb.Marshal: %v", err)
}
}
return false
}
*/
func lessObject(lhs, rhs interface{}) bool {
jbl, err := json.Marshal(lhs)
if err != nil {
return false
}
jbr, err := json.Marshal(rhs)
if err != nil {
return false
}
return string(jbl) < string(jbr)
}
/*
func LessObject(lhs, rhs interface{}) bool {
jbl, err := json.Marshal(lhs)
if err != nil {
return false
}
jbr, err := json.Marshal(rhs)
if err != nil {
return false
}
return string(jbl) < string(jbr)
}
*/
================================================
FILE: go/container/set/set_interface_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package set_test
import (
"testing"
set_ "github.com/kaydxh/golang/go/container/set"
)
func TestSetInsert(t *testing.T) {
s := set_.NewObject("10", "2", "5")
s.Insert("a", "d", "e")
if len(s) != 5 {
t.Errorf("Expected len=5: %d", len(s))
}
if !s.Has("a") || !s.Has("b") || !s.Has("c") || !s.Has("d") || !s.Has("e") {
t.Errorf("UnExpected contents: %#v", s)
}
//%v output value
//map[a:{} b:{} c:{} d:{} e:{}]
t.Logf("s: %v", s)
//%+v output field name + value
//map[a:{} b:{} c:{} d:{} e:{}]
t.Logf("s: %+v", s)
//%#v output struct name + field name + value
//set.Object{"a":set.Empty{}, "b":set.Empty{}, "c":set.Empty{}, "d":set.Empty{}, "e":set.Empty{}}
t.Logf("s: %#v", s)
//[a b c d e]
t.Logf("s: %v", s.List())
}
func TestSetEquals(t *testing.T) {
a := set_.NewObject("1", "2")
b := set_.NewObject("2", "1")
if !a.Equal(b) {
t.Errorf("Expected to be equal: %v vs %v", a, b)
}
//It is a set; duplicates are ignored
b = set_.NewObject("2", "1", "1")
if !a.Equal(b) {
t.Errorf("Expected to be equal: %v vs %v", a, b)
}
}
func TestSetUnion(t *testing.T) {
tests := []struct {
s1 set_.Object
s2 set_.Object
expected set_.Object
}{
{
set_.NewObject("1", "2", "3", "4"),
set_.NewObject("3", "4", "5", "6"),
set_.NewObject("1", "2", "3", "4", "5", "6"),
},
{
set_.NewObject("1", "2", "3", "4"),
set_.NewObject(),
set_.NewObject("1", "2", "3", "4"),
},
{
set_.NewObject(),
set_.NewObject("1", "2", "3", "4"),
set_.NewObject("1", "2", "3", "4"),
},
{
set_.NewObject(),
set_.NewObject(),
set_.NewObject(),
},
}
for _, test := range tests {
union := test.s1.Union(test.s2)
if union.Len() != test.expected.Len() {
t.Errorf("Expected union.Len()=%d but got %d", test.expected.Len(), union.Len())
}
if !union.Equal(test.expected) {
t.Errorf(
"Expected union.Equal(expected) but not true. union:%v expected:%v",
union.List(),
test.expected.List(),
)
}
}
}
func TestSetIntersection(t *testing.T) {
tests := []struct {
s1 set_.Object
s2 set_.Object
expected set_.Object
}{
{
set_.NewObject("1", "2", "3", "4"),
set_.NewObject("3", "4", "5", "6"),
set_.NewObject("3", "4"),
},
{
set_.NewObject("1", "2", "3", "4"),
set_.NewObject("1", "2", "3", "4"),
set_.NewObject("1", "2", "3", "4"),
},
{
set_.NewObject("1", "2", "3", "4"),
set_.NewObject(),
set_.NewObject(),
},
{
set_.NewObject(),
set_.NewObject("1", "2", "3", "4"),
set_.NewObject(),
},
{
set_.NewObject(),
set_.NewObject(),
set_.NewObject(),
},
}
for _, test := range tests {
intersection := test.s1.Intersection(test.s2)
if intersection.Len() != test.expected.Len() {
t.Errorf("Expected intersection.Len()=%d but got %d", test.expected.Len(), intersection.Len())
}
if !intersection.Equal(test.expected) {
t.Errorf(
"Expected intersection.Equal(expected) but not true. intersection:%v expected:%v",
intersection.List(),
test.expected.List(),
)
}
}
}
================================================
FILE: go/container/set/set_string.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package set
import (
"reflect"
"sort"
)
type Empty struct{}
// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption.
type String map[string]Empty
// NewString creates a String from a list of values.
func NewString(items ...string) String {
ss := String{}
ss.Insert(items...)
return ss
}
// StringKeySet creates a String from a keys of a map[string](? extends interface{}).
// If the value passed in is not actually a map, this will panic.
func StringKeySet(theMap interface{}) String {
v := reflect.ValueOf(theMap)
ret := String{}
for _, keyValue := range v.MapKeys() {
ret.Insert(keyValue.Interface().(string))
}
return ret
}
// Insert adds items to the set.
func (s String) Insert(items ...string) String {
for _, item := range items {
s[item] = Empty{}
}
return s
}
// Delete removes all items from the set.
func (s String) Delete(items ...string) String {
for _, item := range items {
delete(s, item)
}
return s
}
// Has returns true if and only if item is contained in the set.
func (s String) Has(item string) bool {
_, contained := s[item]
return contained
}
// HasAll returns true if and only if all items are contained in the set.
func (s String) HasAll(items ...string) bool {
for _, item := range items {
if !s.Has(item) {
return false
}
}
return true
}
// HasAny returns true if any items are contained in the set.
func (s String) HasAny(items ...string) bool {
for _, item := range items {
if s.Has(item) {
return true
}
}
return false
}
// Difference returns a set of objects that are not in s2
// For example:
// s1 = {a1, a2, a3}
// s2 = {a1, a2, a4, a5}
// s1.Difference(s2) = {a3}
// s2.Difference(s1) = {a4, a5}
func (s String) Difference(s2 String) String {
result := NewString()
for key := range s {
if !s2.Has(key) {
result.Insert(key)
}
}
return result
}
// Union returns a new set which includes items in either s1 or s2.
// For example:
// s1 = {a1, a2}
// s2 = {a3, a4}
// s1.Union(s2) = {a1, a2, a3, a4}
// s2.Union(s1) = {a1, a2, a3, a4}
func (s1 String) Union(s2 String) String {
result := NewString()
for key := range s1 {
result.Insert(key)
}
for key := range s2 {
result.Insert(key)
}
return result
}
// Intersection returns a new set which includes the item in BOTH s1 and s2
// For example:
// s1 = {a1, a2}
// s2 = {a2, a3}
// s1.Intersection(s2) = {a2}
func (s1 String) Intersection(s2 String) String {
var walk, other String
result := NewString()
if s1.Len() < s2.Len() {
walk = s1
other = s2
} else {
walk = s2
other = s1
}
for key := range walk {
if other.Has(key) {
result.Insert(key)
}
}
return result
}
// IsSuperset returns true if and only if s1 is a superset of s2.
func (s1 String) IsSuperset(s2 String) bool {
for item := range s2 {
if !s1.Has(item) {
return false
}
}
return true
}
// Equal returns true if and only if s1 is equal (as a set) to s2.
// Two sets are equal if their membership is identical.
// (In practice, this means same elements, order doesn't matter)
func (s1 String) Equal(s2 String) bool {
return len(s1) == len(s2) && s1.IsSuperset(s2)
}
type sortableSliceOfString []string
func (s sortableSliceOfString) Len() int { return len(s) }
func (s sortableSliceOfString) Less(i, j int) bool { return lessString(s[i], s[j]) }
func (s sortableSliceOfString) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// List returns the contents as a sorted string slice.
func (s String) List() []string {
res := make(sortableSliceOfString, 0, len(s))
for key := range s {
res = append(res, key)
}
sort.Sort(res)
return []string(res)
}
// UnsortedList returns the slice with contents in random order.
func (s String) UnsortedList() []string {
res := make([]string, 0, len(s))
for key := range s {
res = append(res, key)
}
return res
}
// Returns a single element from the set.
func (s String) PopAny() (string, bool) {
for key := range s {
s.Delete(key)
return key, true
}
var zeroValue string
return zeroValue, false
}
// Len returns the size of the set.
func (s String) Len() int {
return len(s)
}
func lessString(lhs, rhs string) bool {
return lhs < rhs
}
================================================
FILE: go/container/set/set_string_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package set_test
import (
"testing"
set_ "github.com/kaydxh/golang/go/container/set"
)
func TestStringSetInsert(t *testing.T) {
s := set_.NewString("a", "b", "c")
s.Insert("a", "d", "e")
if len(s) != 5 {
t.Errorf("Expected len=5: %d", len(s))
}
if !s.Has("a") || !s.Has("b") || !s.Has("c") || !s.Has("d") || !s.Has("e") {
t.Errorf("UnExpected contents: %#v", s)
}
//%v output value
//map[a:{} b:{} c:{} d:{} e:{}]
t.Logf("s: %v", s)
//%+v output field name + value
//map[a:{} b:{} c:{} d:{} e:{}]
t.Logf("s: %+v", s)
//%#v output struct name + field name + value
//set.String{"a":set.Empty{}, "b":set.Empty{}, "c":set.Empty{}, "d":set.Empty{}, "e":set.Empty{}}
t.Logf("s: %#v", s)
//[a b c d e]
t.Logf("s: %v", s.List())
}
func TestStringSetEquals(t *testing.T) {
a := set_.NewString("1", "2")
b := set_.NewString("2", "1")
if !a.Equal(b) {
t.Errorf("Expected to be equal: %v vs %v", a, b)
}
//It is a set; duplicates are ignored
b = set_.NewString("2", "1", "1")
if !a.Equal(b) {
t.Errorf("Expected to be equal: %v vs %v", a, b)
}
}
func TestStringSetUnion(t *testing.T) {
tests := []struct {
s1 set_.String
s2 set_.String
expected set_.String
}{
{
set_.NewString("1", "2", "3", "4"),
set_.NewString("3", "4", "5", "6"),
set_.NewString("1", "2", "3", "4", "5", "6"),
},
{
set_.NewString("1", "2", "3", "4"),
set_.NewString(),
set_.NewString("1", "2", "3", "4"),
},
{
set_.NewString(),
set_.NewString("1", "2", "3", "4"),
set_.NewString("1", "2", "3", "4"),
},
{
set_.NewString(),
set_.NewString(),
set_.NewString(),
},
}
for _, test := range tests {
union := test.s1.Union(test.s2)
if union.Len() != test.expected.Len() {
t.Errorf("Expected union.Len()=%d but got %d", test.expected.Len(), union.Len())
}
if !union.Equal(test.expected) {
t.Errorf(
"Expected union.Equal(expected) but not true. union:%v expected:%v",
union.List(),
test.expected.List(),
)
}
}
}
func TestStringSetIntersection(t *testing.T) {
tests := []struct {
s1 set_.String
s2 set_.String
expected set_.String
}{
{
set_.NewString("1", "2", "3", "4"),
set_.NewString("3", "4", "5", "6"),
set_.NewString("3", "4"),
},
{
set_.NewString("1", "2", "3", "4"),
set_.NewString("1", "2", "3", "4"),
set_.NewString("1", "2", "3", "4"),
},
{
set_.NewString("1", "2", "3", "4"),
set_.NewString(),
set_.NewString(),
},
{
set_.NewString(),
set_.NewString("1", "2", "3", "4"),
set_.NewString(),
},
{
set_.NewString(),
set_.NewString(),
set_.NewString(),
},
}
for _, test := range tests {
intersection := test.s1.Intersection(test.s2)
if intersection.Len() != test.expected.Len() {
t.Errorf("Expected intersection.Len()=%d but got %d", test.expected.Len(), intersection.Len())
}
if !intersection.Equal(test.expected) {
t.Errorf(
"Expected intersection.Equal(expected) but not true. intersection:%v expected:%v",
intersection.List(),
test.expected.List(),
)
}
}
}
================================================
FILE: go/container/set/set_test.go
================================================
package set_test
import (
"testing"
set_ "github.com/kaydxh/golang/go/container/set"
)
func TestGenericSetNew(t *testing.T) {
s := set_.New[int]()
s.Insert(2)
t.Logf("s: %v", s)
}
func TestGenericSetInsert(t *testing.T) {
s := set_.New("10", "2", "5")
s.Insert("a", "d", "e")
if len(s) != 5 {
t.Errorf("Expected len=5: %d", len(s))
}
if !s.Has("a") || !s.Has("b") || !s.Has("c") || !s.Has("d") || !s.Has("e") {
t.Errorf("UnExpected contents: %#v", s)
}
//%v output value
//map[a:{} b:{} c:{} d:{} e:{}]
t.Logf("s: %v", s)
//%+v output field name + value
//map[a:{} b:{} c:{} d:{} e:{}]
t.Logf("s: %+v", s)
//%#v output struct name + field name + value
//set.Object{"a":set.Empty{}, "b":set.Empty{}, "c":set.Empty{}, "d":set.Empty{}, "e":set.Empty{}}
t.Logf("s: %#v", s)
//[a b c d e]
t.Logf("s: %v", s.List())
}
func TestGenericSetEquals(t *testing.T) {
a := set_.New("1", "2")
b := set_.New("2", "1")
if !a.Equal(b) {
t.Errorf("Expected to be equal: %v vs %v", a, b)
}
//It is a set; duplicates are ignored
b = set_.New("2", "1", "1")
if !a.Equal(b) {
t.Errorf("Expected to be equal: %v vs %v", a, b)
}
}
func TestGenericSetUnion(t *testing.T) {
tests := []struct {
s1 set_.Set[string]
s2 set_.Set[string]
expected set_.Set[string]
}{
{
set_.New("1", "2", "3", "4"),
set_.New("3", "4", "5", "6"),
set_.New("1", "2", "3", "4", "5", "6"),
},
{
set_.New("1", "2", "3", "4"),
set_.New[string](),
set_.New("1", "2", "3", "4"),
},
{
set_.New[string](),
set_.New("1", "2", "3", "4"),
set_.New("1", "2", "3", "4"),
},
{
set_.New[string](),
set_.New[string](),
set_.New[string](),
},
}
for _, test := range tests {
union := test.s1.Union(test.s2)
if union.Len() != test.expected.Len() {
t.Errorf("Expected union.Len()=%d but got %d", test.expected.Len(), union.Len())
}
if !union.Equal(test.expected) {
t.Errorf(
"Expected union.Equal(expected) but not true. union:%v expected:%v",
union.List(),
test.expected.List(),
)
}
}
}
================================================
FILE: go/container/workqueue/queue.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package workqueue
import (
"sync"
)
type Interface interface {
Add(item interface{})
Len() int
Get() (item interface{}, shutdown bool)
Done(item interface{})
ShutDown()
ShuttingDown() bool
}
func NewQueue() *Type {
t := &Type{
dirty: set{},
processing: set{},
cond: sync.NewCond(&sync.Mutex{}),
}
return t
}
// Type is a work queue (see the package comment).
type Type struct {
// queue defines the order in which we will work on items. Every
// element of queue should be in the dirty set and not in the
// processing set.
queue []t
// dirty defines all of the items that need to be processed.
dirty set
// Things that are currently being processed are in the processing set.
// These things may be simultaneously in the dirty set. When we finish
// processing something and remove it from this set, we'll check if
// it's in the dirty set, and if so, add it to the queue.
processing set
cond *sync.Cond
shuttingDown bool
drain bool
}
type empty struct{}
type t interface{}
type set map[t]empty
func (s set) has(item t) bool {
_, exists := s[item]
return exists
}
func (s set) insert(item t) {
s[item] = empty{}
}
func (s set) delete(item t) {
delete(s, item)
}
func (s set) len() int {
return len(s)
}
// Add marks item as needing processing.
func (q *Type) Add(item interface{}) {
q.cond.L.Lock()
defer q.cond.L.Unlock()
if q.shuttingDown {
return
}
if q.dirty.has(item) {
return
}
q.dirty.insert(item)
if q.processing.has(item) {
return
}
q.queue = append(q.queue, item)
q.cond.Signal()
}
func (q *Type) Len() int {
q.cond.L.Lock()
defer q.cond.L.Unlock()
return len(q.queue)
}
func (q *Type) Get() (item interface{}, shutdown bool) {
q.cond.L.Lock()
defer q.cond.L.Unlock()
for len(q.queue) == 0 && !q.shuttingDown {
q.cond.Wait()
}
if len(q.queue) == 0 {
// We must be shutting down.
return nil, true
}
item = q.queue[0]
// The underlying array still exists and reference this object, so the object will not be garbage collected.
q.queue[0] = nil
q.queue = q.queue[1:]
q.processing.insert(item)
q.dirty.delete(item)
return item, false
}
func (q *Type) Done(item interface{}) {
q.cond.L.Lock()
defer q.cond.L.Unlock()
q.processing.delete(item)
if q.dirty.has(item) {
q.queue = append(q.queue, item)
q.cond.Signal()
} else if q.processing.len() == 0 {
q.cond.Signal()
}
}
// ShutDown will cause q to ignore all new items added to it and
// immediately instruct the worker goroutines to exit.
func (q *Type) ShutDown() {
q.setDrain(false)
q.shutdown()
}
// ShutDownWithDrain will cause q to ignore all new items added to it. As soon
// as the worker goroutines have "drained", i.e: finished processing and called
// Done on all existing items in the queue; they will be instructed to exit and
// ShutDownWithDrain will return. Hence: a strict requirement for using this is;
// your workers must ensure that Done is called on all items in the queue once
// the shut down has been initiated, if that is not the case: this will block
// indefinitely. It is, however, safe to call ShutDown after having called
// ShutDownWithDrain, as to force the queue shut down to terminate immediately
// without waiting for the drainage.
func (q *Type) ShutDownWithDrain() {
q.setDrain(true)
q.shutdown()
for q.isProcessing() && q.shouldDrain() {
q.waitForProcessing()
}
}
// isProcessing indicates if there are still items on the work queue being
// processed. It's used to drain the work queue on an eventual shutdown.
func (q *Type) isProcessing() bool {
q.cond.L.Lock()
defer q.cond.L.Unlock()
return q.processing.len() != 0
}
// waitForProcessing waits for the worker goroutines to finish processing items
// and call Done on them.
func (q *Type) waitForProcessing() {
q.cond.L.Lock()
defer q.cond.L.Unlock()
// Ensure that we do not wait on a queue which is already empty, as that
// could result in waiting for Done to be called on items in an empty queue
// which has already been shut down, which will result in waiting
// indefinitely.
if q.processing.len() == 0 {
return
}
q.cond.Wait()
}
func (q *Type) setDrain(shouldDrain bool) {
q.cond.L.Lock()
defer q.cond.L.Unlock()
q.drain = shouldDrain
}
func (q *Type) shouldDrain() bool {
q.cond.L.Lock()
defer q.cond.L.Unlock()
return q.drain
}
func (q *Type) shutdown() {
q.cond.L.Lock()
defer q.cond.L.Unlock()
q.shuttingDown = true
q.cond.Broadcast()
}
func (q *Type) ShuttingDown() bool {
q.cond.L.Lock()
defer q.cond.L.Unlock()
return q.shuttingDown
}
================================================
FILE: go/container/workqueue/queue_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package workqueue_test
import (
"sync"
"testing"
"time"
workqueue_ "github.com/kaydxh/golang/go/container/workqueue"
)
func TestBasic(t *testing.T) {
testCases := []struct {
queue *workqueue_.Type
queueShutDown func(workqueue_.Interface)
}{
{
queue: workqueue_.NewQueue(),
queueShutDown: workqueue_.Interface.ShutDown,
},
}
for _, testCase := range testCases {
// Start producers
const producers = 10
producerWG := sync.WaitGroup{}
producerWG.Add(producers)
for i := 0; i < producers; i++ {
go func(i int) {
defer producerWG.Done()
for j := 0; j < 2; j++ {
testCase.queue.Add(i)
time.Sleep(time.Millisecond)
}
}(i)
}
// Start consumers
const consumers = 10
consumerWG := sync.WaitGroup{}
consumerWG.Add(consumers)
for i := 0; i < consumers; i++ {
go func(i int) {
defer consumerWG.Done()
for {
item, quit := testCase.queue.Get()
if quit {
return
}
t.Logf("Woker %v: begin processing %v", i, item)
time.Sleep(3 * time.Millisecond)
t.Logf("Woker %v: done processing %v", i, item)
testCase.queue.Done(item)
}
}(i)
}
producerWG.Wait()
testCase.queueShutDown(testCase.queue)
testCase.queue.Add("add after shutdown!")
consumerWG.Wait()
if testCase.queue.Len() != 0 {
t.Errorf("Expected the queue to be empty, had: %v items", testCase.queue.Len())
}
}
}
func TestReinsert(t *testing.T) {
q := workqueue_.NewQueue()
q.Add("foo")
// Start processing
i, _ := q.Get()
if i != "foo" {
t.Errorf("Expected %v, got %v", "foo", i)
}
// Add it back while processing
q.Add(i)
// Finish it up
q.Done(i)
// It should be back on the queue
i, _ = q.Get()
if i != "foo" {
t.Errorf("Expected %v, got %v", "foo", i)
}
// Finish that one up
q.Done(i)
if a := q.Len(); a != 0 {
t.Errorf("Expected queue to be empty. Has %v items", a)
}
}
================================================
FILE: go/context/context.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package context
import (
"context"
"fmt"
"strconv"
"time"
)
// RequestIdKey is metadata key name for request ID
const (
DefaultHTTPRequestIDKey = "X-Request-ID"
DefaultHTTPTraceIDKey = "X-Traceid"
)
func WithTimeout(ctx context.Context, timeout time.Duration) (context.Context, context.CancelFunc) {
if timeout > 0 {
return context.WithTimeout(ctx, timeout)
}
return ctx, func() {}
}
func ExtractStringFromContext(ctx context.Context, key string) string {
if v, ok := ctx.Value(key).(string); ok {
return v
}
return ""
}
func ExtractIntegerFromContext(ctx context.Context, key string) (int64, error) {
v, ok := ctx.Value(key).(string)
if !ok {
return 0, fmt.Errorf("key[%v] value type is not string", key)
}
number, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return 0, fmt.Errorf("key[%v] value type is not number: %v", key, err)
}
return number, nil
}
func ExtractFromContext(ctx context.Context, key string) string {
switch value := ctx.Value(key).(type) {
case string:
if value != "" {
return value
}
case []string:
if len(value) > 0 {
return value[0]
}
default:
return ""
}
return ""
}
func UpdateContext(ctx context.Context, key string, values map[string]interface{}) error {
currentValues, ok := ctx.Value(key).(map[string]interface{})
if ok {
for k, v := range values {
currentValues[k] = v
}
return nil
}
return fmt.Errorf("key[%v] is not exist in context", key)
}
func SetPairContext(ctx context.Context, key, value string) context.Context {
return context.WithValue(ctx, key, value)
}
func AppendContext(ctx context.Context, key string, values ...string) context.Context {
currentValues, _ := ctx.Value(key).([]string)
currentValues = append(currentValues, values...)
return context.WithValue(ctx, key, currentValues)
}
func WithContextRequestId(ctx context.Context, id string) context.Context {
return context.WithValue(ctx, DefaultHTTPRequestIDKey, id)
}
func ExtractRequestIDFromContext(ctx context.Context) string {
if v, ok := ctx.Value(DefaultHTTPRequestIDKey).(string); ok {
return v
}
return ""
}
func ExtractTraceIDFromContext(ctx context.Context) string {
if v, ok := ctx.Value(DefaultHTTPTraceIDKey).(string); ok {
return v
}
return ""
}
================================================
FILE: go/context/context_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package context_test
import (
"context"
"fmt"
"testing"
"time"
context_ "github.com/kaydxh/golang/go/context"
)
func withField(ctx context.Context) {
ctx = context.WithValue(ctx, "abc", "abc")
fmt.Printf("context: %+v\n", ctx)
}
func TestContext(t *testing.T) {
ctx := context.Background()
t.Logf("context: %v", ctx)
withField(ctx)
t.Logf("context: %v", ctx)
}
func doA(ctx context.Context) {
{
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, time.Second)
defer cancel()
}
timer := time.NewTimer(3 * time.Second)
defer timer.Stop()
select {
case <-ctx.Done():
fmt.Println("doA timeout")
case <-timer.C:
fmt.Println("doA finish")
}
}
func doB(ctx context.Context) {
{
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, 10*time.Second)
defer cancel()
}
timer := time.NewTimer(3 * time.Second)
defer timer.Stop()
select {
case <-ctx.Done():
fmt.Println("doB timeout")
case <-timer.C:
fmt.Println("doB finish")
}
}
func TestContextTimeout(t *testing.T) {
ctx := context.Background()
doA(ctx)
doB(ctx)
}
func TestExtractIntegerFromContext(t *testing.T) {
ctx := context.Background()
testCases := []struct {
key string
value string
expected string
}{
{
key: "test-1",
value: "123",
},
{
key: "test-2",
value: "test-123",
},
}
for _, testCase := range testCases {
t.Run(testCase.key, func(t *testing.T) {
ctx = context_.SetPairContext(ctx, testCase.key, testCase.value)
number, err := context_.ExtractIntegerFromContext(ctx, testCase.key)
if err != nil {
t.Errorf("expect nil, got %v", err)
return
}
t.Logf("extract value %v by key %v ", number, testCase.key)
})
}
}
func TestExtractStringFromContext(t *testing.T) {
ctx := context.Background()
testCases := []struct {
key string
value string
expected string
}{
{
key: "test-1",
value: "123",
},
{
key: "test-2",
value: "test-123",
},
}
for _, testCase := range testCases {
t.Run(testCase.key, func(t *testing.T) {
ctx = context_.SetPairContext(ctx, testCase.key, testCase.value)
value := context_.ExtractStringFromContext(ctx, testCase.key)
t.Logf("extract value %v by key %v ", value, testCase.key)
})
}
}
================================================
FILE: go/crypto/aes/aes_cbc.go
================================================
/*
MIT License
Copyright (c) 2020 kay
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
package aes
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"io"
)
func AesCbcEncrypt(plainText, key []byte) ([]byte, error) {
if len(key) != 16 && len(key) != 32 {
return nil, ErrKeyLength
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
paddingText := pad(plainText, aes.BlockSize)
cipherText := make([]byte, aes.BlockSize+len(paddingText))
iv := cipherText[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
blockMode := cipher.NewCBCEncrypter(block, iv)
blockMode.CryptBlocks(cipherText[aes.BlockSize:], paddingText)
return cipherText, nil
}
func AesCbcDecrypt(cipherText, key []byte) ([]byte, error) {
if len(key) != 16 && len(key) != 24 {
return nil, ErrKeyLength
}
if len(cipherText) < aes.BlockSize {
return nil, ErrCipherTextLength
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
iv := cipherText[:aes.BlockSize]
cb := cipherText[aes.BlockSize:]
blockMode := cipher.NewCBCDecrypter(block, iv)
blockMode.CryptBlocks(cb, cb)
plainText, err := unpad(cb)
if err != nil {
return nil, err
}
return plainText, nil
}
func pad(plainText []byte, blockSize int) []byte {
padding := blockSize - (len(plainText) % blockSize)
padText := bytes.Repeat([]byte{byte(padding)}, padding)
newText := append(plainText, padText...)
return newText
}
func unpad(plainText []byte) ([]byte, error) {
length := len(plainText)
unpadding := int(plainText[length-1])
if unpadding > length {
return nil, ErrPaddingSize
}
return plainText[:length-unpadding], nil
}
================================================
FILE: go/crypto/aes/aes_cbc_test.go
================================================
/*
MIT License
Copyright (c) 2020 kay
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
package aes_test
import (
"fmt"
"testing"
"flag"
aes_ "github.com/kaydxh/golang/go/crypto/aes"
io_ "github.com/kaydxh/golang/go/io"
)
func TestAesCbcEncryptDecrypt(t *testing.T) {
plainText := []byte("Hello World")
fmt.Println("plainText: ", string(plainText))
key := []byte("daW3eDgPEa9TjknE")
cryptText, err := aes_.AesCbcEncrypt(plainText, key)
if err != nil {
t.Errorf("expect nil, got %v", err)
}
fmt.Println("cryptText: ", string(cryptText))
newplainText, err := aes_.AesCbcDecrypt(cryptText, key)
if err != nil {
t.Errorf("expect nil, got %v", err)
}
fmt.Println("newplainText: ", string(newplainText))
if string(newplainText) != string(plainText) {
t.Errorf("newplainText not equal plainText")
}
}
// build: go test -c aes_cbc_test.go -o decrypt_tool
// run: ./decrypt_tool -test.v --test.run TestAesCbcDecrypt -srcePath=1.jpg -destPath=2.jpg
var (
srcePath = flag.String("srcePath", "", "source encrypt image path")
destPath = flag.String("destPath", "./decryptImage.jpg", "dest decrypt image path")
)
func TestAesCbcDecrypt(t *testing.T) {
cryptText, err := io_.ReadFile(*srcePath)
if err != nil {
t.Errorf("expect nil, got %v", err)
return
}
key := []byte("daW3eDgPEa9TjknE")
newplainText, err := aes_.AesCbcDecrypt(cryptText, key)
if err != nil {
t.Errorf("expect nil, got %v", err)
}
io_.WriteFile(*destPath, newplainText, false)
}
================================================
FILE: go/crypto/aes/error.go
================================================
/*
MIT License
Copyright (c) 2020 kay
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
package aes
import "errors"
var (
ErrKeyLength = errors.New("err key lenght")
ErrPaddingSize = errors.New("err padding size")
ErrCipherTextLength = errors.New("err cipherText lenght")
)
================================================
FILE: go/crypto/md5/md5.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package md5
import (
"bytes"
"crypto/md5"
"encoding/hex"
"io"
"os"
os_ "github.com/kaydxh/golang/go/os"
)
func SumBytes(b []byte) string {
h := md5.New()
h.Write(b)
return hex.EncodeToString(h.Sum(nil))
}
func SumString(s string) string {
return SumBytes([]byte(s))
}
func SumReader(r io.Reader) (string, error) {
h := md5.New()
if _, err := io.Copy(h, r); err != nil {
return "", err
}
return hex.EncodeToString(h.Sum(nil)), nil
}
func SumReaderN(r io.Reader, n int64) (string, error) {
h := md5.New()
if _, err := io.CopyN(h, r, n); err != nil {
return "", err
}
return hex.EncodeToString(h.Sum(nil)), nil
}
func SumReaderAt(r io.ReaderAt, offset, length int64) (string, error) {
h := md5.New()
buf := make([]byte, 1024)
var total int64
for total < length {
n, err := r.ReadAt(buf, offset)
if err == nil || err == io.EOF {
if n > 0 {
_, tmpErr := io.CopyN(h, bytes.NewReader(buf), int64(n))
if tmpErr != nil {
return "", tmpErr
}
offset += int64(n)
total += int64(n)
}
if err == io.EOF {
break
}
} else {
return "", err
}
}
return hex.EncodeToString(h.Sum(nil)), nil
}
func SumFile(fileName string) (string, error) {
file, err := os_.OpenFile(fileName, true)
if err != nil {
return "", err
}
defer file.Close()
return SumReader(file)
}
func SumFileAt(fileName string, offset int64, length int64) (string, error) {
file, err := os_.OpenAll(fileName, os.O_RDWR, os.ModePerm)
if err != nil {
return "", err
}
defer file.Close()
return SumReaderAt(file, offset, length)
}
================================================
FILE: go/crypto/md5/md5_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package md5_test
import (
"fmt"
"io/ioutil"
"os"
"testing"
md5_ "github.com/kaydxh/golang/go/crypto/md5"
"gotest.tools/assert"
)
func TestMd5File(t *testing.T) {
file, err := ioutil.TempFile(".", "file")
if err != nil {
t.Errorf("expect nil, got %v", err)
}
defer os.RemoveAll(file.Name())
strContext := "hello world"
// n, err := io.WriteString(file, "hello world")
n, err := file.Write([]byte(strContext))
if err != nil {
t.Errorf("expect nil, got %v", err)
}
assert.Equal(t, len(strContext), n)
fmt.Printf("fileName: %v, n: %v\n", file.Name(), n)
sum, err := md5_.SumFile(file.Name())
if err != nil {
t.Errorf("expect nil, got %v", err)
}
assert.Equal(t, sum, md5_.SumString(strContext))
}
func TestMd5FileAt(t *testing.T) {
file, err := ioutil.TempFile(".", "file")
if err != nil {
t.Errorf("expect nil, got %v", err)
}
defer os.RemoveAll(file.Name())
testCases := []struct {
name string
words []byte
expected string
}{
{
name: "write one word",
words: []byte("test1"),
expected: "test1",
},
{
name: "write one word",
words: []byte("test2"),
expected: "test2",
},
{
name: "write one word",
words: []byte("test3"),
expected: "test3",
},
}
var offset int64
for i, testCase := range testCases {
_, err := file.Write(testCase.words)
if err != nil {
t.Errorf("expect nil, got %v", err)
}
if i > 0 {
offset += int64(len(testCases[i-1].words))
}
fmt.Printf("i: %d, offset: %v, testCase: %s\n", i, offset, testCase.words)
sum, err := md5_.SumFileAt(file.Name(), offset, int64(len(testCase.words)))
if err != nil {
t.Errorf("expect nil, got %v", err)
}
fmt.Println("sum: ", sum)
assert.Equal(t, sum, md5_.SumBytes(testCase.words))
}
}
================================================
FILE: go/crypto/sha256/sha256.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package sha256
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"io"
"os"
os_ "github.com/kaydxh/golang/go/os"
)
func SumBytes(b []byte) string {
h := sha256.New()
h.Write(b)
return hex.EncodeToString(h.Sum(nil))
}
func SumString(s string) string {
return SumBytes([]byte(s))
}
func SumReader(r io.Reader) (string, error) {
h := sha256.New()
if _, err := io.Copy(h, r); err != nil {
return "", err
}
return hex.EncodeToString(h.Sum(nil)), nil
}
func SumReaderN(r io.Reader, n int64) (string, error) {
h := sha256.New()
if _, err := io.CopyN(h, r, n); err != nil {
return "", err
}
return hex.EncodeToString(h.Sum(nil)), nil
}
func SumReaderAt(r io.ReaderAt, offset, length int64) (string, error) {
h := sha256.New()
buf := make([]byte, 1024)
var total int64
for total < length {
n, err := r.ReadAt(buf, offset)
if err == nil || err == io.EOF {
if n > 0 {
_, tmpErr := io.CopyN(h, bytes.NewReader(buf), int64(n))
if tmpErr != nil {
return "", tmpErr
}
offset += int64(n)
total += int64(n)
}
if err == io.EOF {
break
}
} else {
return "", err
}
}
return hex.EncodeToString(h.Sum(nil)), nil
}
func SumFile(fileName string) (string, error) {
file, err := os_.OpenFile(fileName, true)
if err != nil {
return "", err
}
defer file.Close()
return SumReader(file)
}
func SumFileAt(fileName string, offset int64, length int64) (string, error) {
file, err := os_.OpenAll(fileName, os.O_RDWR, os.ModePerm)
if err != nil {
return "", err
}
defer file.Close()
return SumReaderAt(file, offset, length)
}
================================================
FILE: go/crypto/sha256/sha256_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package sha256_test
import (
"fmt"
"io/ioutil"
"os"
"testing"
sha256_ "github.com/kaydxh/golang/go/crypto/sha256"
"gotest.tools/assert"
)
func TestSha256File(t *testing.T) {
file, err := ioutil.TempFile(".", "file")
if err != nil {
t.Errorf("expect nil, got %v", err)
}
defer os.RemoveAll(file.Name())
strContext := "hello world"
// n, err := io.WriteString(file, "hello world")
n, err := file.Write([]byte(strContext))
if err != nil {
t.Errorf("expect nil, got %v", err)
}
assert.Equal(t, len(strContext), n)
fmt.Printf("fileName: %v, n: %v\n", file.Name(), n)
sum, err := sha256_.SumFile(file.Name())
if err != nil {
t.Errorf("expect nil, got %v", err)
}
assert.Equal(t, sum, sha256_.SumString(strContext))
}
func TestSha256FileAt(t *testing.T) {
file, err := ioutil.TempFile(".", "file")
if err != nil {
t.Errorf("expect nil, got %v", err)
}
defer os.RemoveAll(file.Name())
testCases := []struct {
name string
words []byte
expected string
}{
{
name: "write one word",
words: []byte("test1"),
expected: "test1",
},
{
name: "write one word",
words: []byte("test2"),
expected: "test2",
},
{
name: "write one word",
words: []byte("test3"),
expected: "test3",
},
}
var offset int64
for i, testCase := range testCases {
_, err := file.Write(testCase.words)
if err != nil {
t.Errorf("expect nil, got %v", err)
}
if i > 0 {
offset += int64(len(testCases[i-1].words))
}
fmt.Printf("i: %d, offset: %v, testCase: %s\n", i, offset, testCase.words)
sum, err := sha256_.SumFileAt(file.Name(), offset, int64(len(testCase.words)))
if err != nil {
t.Errorf("expect nil, got %v", err)
}
fmt.Println("sum: ", sum)
assert.Equal(t, sum, sha256_.SumBytes(testCase.words))
}
}
================================================
FILE: go/doc.go
================================================
package _go
================================================
FILE: go/encoding/base64/base64.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package base64
import (
"encoding/base64"
"fmt"
)
func EncodeString(v string) string {
return base64.StdEncoding.EncodeToString([]byte(v))
}
func DecodeString(v string) (string, error) {
data, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return "", fmt.Errorf("base64 decode failed: %v", err)
}
return string(data), nil
}
func EncodeURL(v string) string {
return base64.URLEncoding.EncodeToString([]byte(v))
}
func DecodeURL(v string) (string, error) {
data, err := base64.URLEncoding.DecodeString(v)
if err != nil {
return "", fmt.Errorf("base64 decode url failed: %v", err)
}
return string(data), nil
}
================================================
FILE: go/encoding/base64/base64_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/package base64_test
import (
"encoding/binary"
"fmt"
"math"
"testing"
io_ "github.com/kaydxh/golang/go/io"
base64_ "github.com/kaydxh/golang/go/encoding/base64"
"gotest.tools/v3/assert"
)
func TestString(t *testing.T) {
testCases := []struct {
name string
expected string
}{
{
name: "hello word",
expected: "",
},
{
name: "http://12306.com?a=%b",
expected: "",
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
encoded := base64_.EncodeString(testCase.name)
t.Logf("base64 encode : %v", encoded)
decoded, err := base64_.DecodeString(encoded)
if err != nil {
t.Fatalf("failed to decode string, err: %v", err)
}
assert.Equal(t, testCase.name, decoded)
})
}
/*
content := "hello word"
encoded := base64_.EncodeString(content)
t.Logf("base64 encode : %v", encoded)
decoded, err := base64_.DecodeString(encoded)
if err != nil {
t.Fatalf("failed to decode string, err: %v", err)
}
t.Logf("base64 decode : %v", decoded)
*/
//assert.Equal(t, content, decoded)
}
func TestURL(t *testing.T) {
testCases := []struct {
name string
expected string
}{
{
name: `http://baidu.com?a=10&b="hello"`,
expected: "",
},
{
name: "http://12306.com?a=%b",
expected: "",
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
encoded := base64_.EncodeURL(testCase.name)
t.Logf("base64 encode : %v", encoded)
decoded, err := base64_.DecodeURL(encoded)
if err != nil {
t.Fatalf("failed to decode url, err: %v", err)
}
assert.Equal(t, testCase.name, decoded)
})
}
}
func TestDecodeString(t *testing.T) {
testCases := []struct {
value string
expected string
}{
{
value: "PeNT+D5jU/g=",
expected: "",
},
}
for i, testCase := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
decoded, err := base64_.DecodeString(testCase.value)
if err != nil {
t.Fatalf("failed to decode string, err: %v", err)
}
t.Logf("decode string len: %v, value len: %v", len(decoded), len(testCase.value))
j := 0
for i := 0; i < len(decoded); i += 4 {
bits := binary.LittleEndian.Uint32([]byte(decoded[i : i+4]))
fmt.Printf("%f ", math.Float32frombits(bits))
j++
}
fmt.Printf("j=%v", j)
})
}
}
func TestDecodeFile(t *testing.T) {
testCases := []struct {
value string
expected string
}{
{
value: "./1.txt",
expected: "",
},
}
for i, testCase := range testCases {
encodedValue, err := io_.ReadFile(testCase.value)
if err != nil {
t.Fatalf("failed to read file: %v, err: %v", testCase.value, err)
}
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
decoded, err := base64_.DecodeString(string(encodedValue))
if err != nil {
t.Fatalf("failed to decode string, err: %v", err)
}
t.Logf("decode string len: %v, value len: %v", len(decoded), len(testCase.value))
io_.WriteFile(testCase.value+".mp4", []byte(decoded), false)
})
}
}
================================================
FILE: go/encoding/hash/hash.go
================================================
/*
*Copyright (c) 2023, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package hash
import "hash/crc32"
func HashCode(s string) uint32 {
return crc32.ChecksumIEEE([]byte(s))
}
================================================
FILE: go/encoding/hash/hash_test.go
================================================
/*
*Copyright (c) 2023, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package hash_test
import (
"fmt"
"testing"
hash_ "github.com/kaydxh/golang/go/encoding/hash"
)
func TestHashCode(t *testing.T) {
testCases := []struct {
value string
expected string
}{
{
value: "0",
expected: "",
},
{
value: "1",
expected: "",
},
{
value: "2",
expected: "",
},
{
value: "10",
expected: "",
},
}
for i, testCase := range testCases {
t.Run(fmt.Sprintf("%v", i), func(t *testing.T) {
hashCode := hash_.HashCode(testCase.value)
t.Logf("%v hash code %v, mod10 %v", testCase.value, hashCode, hashCode%10)
})
}
}
================================================
FILE: go/encoding/jwt/jwt.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
// Package jwt 提供轻量级的 JWT(JSON Web Token)解析工具。
//
// 注意:本包仅解析 JWT payload,不验证签名。适用于以下场景:
// - Token 来自可信的服务端(server-to-server)
// - 仅需提取 claims 中的字段用于日志、路由等非鉴权用途
//
// 如果 Token 来自不可信客户端或用于鉴权决策,必须使用带签名验证的 JWT 库。
package jwt
import (
"encoding/base64"
"encoding/json"
"fmt"
"strings"
)
// ParsePayload 解析 JWT token 的 payload 部分,返回 claims map。
// 不验证签名,仅做 base64url 解码 + JSON 反序列化。
// token 格式必须为标准 JWT 三段式:header.payload.signature。
func ParsePayload(token string) (map[string]interface{}, error) {
if token == "" {
return nil, fmt.Errorf("jwt: empty token")
}
parts := strings.Split(token, ".")
if len(parts) != 3 {
return nil, fmt.Errorf("jwt: invalid token format, expected 3 parts, got %d", len(parts))
}
// base64url 解码 payload(JWT 标准使用无 padding 的 base64url)
decoded, err := base64.RawURLEncoding.DecodeString(parts[1])
if err != nil {
// 兼容带 padding 的 base64url
decoded, err = base64.URLEncoding.DecodeString(padBase64(parts[1]))
if err != nil {
// 最后尝试标准 base64(某些非标准实现可能使用)
decoded, err = base64.StdEncoding.DecodeString(padBase64(parts[1]))
if err != nil {
return nil, fmt.Errorf("jwt: decode payload: %w", err)
}
}
}
var claims map[string]interface{}
if err := json.Unmarshal(decoded, &claims); err != nil {
return nil, fmt.Errorf("jwt: unmarshal payload: %w", err)
}
return claims, nil
}
// GetClaimString 从 claims 中安全提取字符串类型的字段值。
// 如果字段不存在或类型不是 string,返回空字符串。
func GetClaimString(claims map[string]interface{}, key string) string {
if claims == nil {
return ""
}
v, ok := claims[key].(string)
if !ok {
return ""
}
return v
}
// GetClaimFloat64 从 claims 中安全提取数值类型的字段值。
// JSON 数字默认反序列化为 float64,如果字段不存在或类型不匹配,返回 0。
func GetClaimFloat64(claims map[string]interface{}, key string) float64 {
if claims == nil {
return 0
}
v, ok := claims[key].(float64)
if !ok {
return 0
}
return v
}
// padBase64 为 base64 字符串补齐 padding。
func padBase64(s string) string {
switch len(s) % 4 {
case 2:
return s + "=="
case 3:
return s + "="
}
return s
}
================================================
FILE: go/encoding/jwt/jwt_test.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package jwt
import (
"testing"
)
func TestParsePayload(t *testing.T) {
tests := []struct {
name string
token string
wantErr bool
check func(claims map[string]interface{}) bool
}{
{
name: "空 token",
token: "",
wantErr: true,
},
{
name: "非法格式(只有一段)",
token: "abc",
wantErr: true,
},
{
name: "非法格式(只有两段)",
token: "abc.def",
wantErr: true,
},
{
name: "合法 JWT(base64url 无 padding)",
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYWxpY2UiLCJleHAiOjE3MTk5OTk5OTl9.signature",
check: func(claims map[string]interface{}) bool {
return GetClaimString(claims, "user_id") == "alice"
},
},
{
name: "payload 为空 JSON 对象",
token: "eyJhbGciOiJIUzI1NiJ9.e30.signature",
check: func(claims map[string]interface{}) bool {
return len(claims) == 0
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
claims, err := ParsePayload(tt.token)
if (err != nil) != tt.wantErr {
t.Errorf("ParsePayload() error = %v, wantErr %v", err, tt.wantErr)
return
}
if tt.check != nil && !tt.check(claims) {
t.Errorf("ParsePayload() claims check failed, claims = %v", claims)
}
})
}
}
func TestGetClaimString(t *testing.T) {
claims := map[string]interface{}{
"user_id": "bob",
"count": float64(42),
}
if got := GetClaimString(claims, "user_id"); got != "bob" {
t.Errorf("GetClaimString(user_id) = %q, want %q", got, "bob")
}
if got := GetClaimString(claims, "missing"); got != "" {
t.Errorf("GetClaimString(missing) = %q, want empty", got)
}
if got := GetClaimString(claims, "count"); got != "" {
t.Errorf("GetClaimString(count) = %q, want empty (type mismatch)", got)
}
if got := GetClaimString(nil, "user_id"); got != "" {
t.Errorf("GetClaimString(nil) = %q, want empty", got)
}
}
func TestGetClaimFloat64(t *testing.T) {
claims := map[string]interface{}{
"exp": float64(1719999999),
"user_id": "alice",
}
if got := GetClaimFloat64(claims, "exp"); got != 1719999999 {
t.Errorf("GetClaimFloat64(exp) = %v, want %v", got, 1719999999)
}
if got := GetClaimFloat64(claims, "user_id"); got != 0 {
t.Errorf("GetClaimFloat64(user_id) = %v, want 0 (type mismatch)", got)
}
if got := GetClaimFloat64(nil, "exp"); got != 0 {
t.Errorf("GetClaimFloat64(nil) = %v, want 0", got)
}
}
================================================
FILE: go/encoding/protojson/decode.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package protojson
import (
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
)
type Unmarshaler struct {
// UnmarshalOptions is a configurable JSON format parser.
protojson.UnmarshalOptions
}
func Unmarshal(data []byte, pb proto.Message, options ...UnmarshalerOption) error {
m := Unmarshaler{
UnmarshalOptions: protojson.UnmarshalOptions{
AllowPartial: true,
DiscardUnknown: true,
},
}
m.ApplyOptions(options...)
return m.Unmarshal(data, pb)
}
================================================
FILE: go/encoding/protojson/decode.option.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package protojson
// If AllowPartial is set, input for messages that will result in missing
func WithUnMashalAllowPartial(allowPartial bool) UnmarshalerOption {
return UnmarshalerOptionFunc(func(m *Unmarshaler) {
m.AllowPartial = allowPartial
})
}
// If DiscardUnknown is set, unknown fields are ignored.
func WithUnmashalDiscardUnknown(discardUnknown bool) UnmarshalerOption {
return UnmarshalerOptionFunc(func(m *Unmarshaler) {
m.DiscardUnknown = discardUnknown
})
}
================================================
FILE: go/encoding/protojson/decode_option.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/
package protojson
// A UnmarshalerOption sets options.
type UnmarshalerOption interface {
apply(*Unmarshaler)
}
// EmptyUnmarshalerOption does not alter the configuration. It can be embedded
// in another structure to build custom options.
//
// This API is EXPERIMENTAL.
type EmptyUnmarshalerOption struct{}
func (EmptyUnmarshalerOption) apply(*Unmarshaler) {}
// UnmarshalerOptionFunc wraps a function that modifies Client into an
// implementation of the UnmarshalerOption interface.
type UnmarshalerOptionFunc func(*Unmarshaler)
func (f UnmarshalerOptionFunc) apply(do *Unmarshaler) {
f(do)
}
// sample code for option, default for nothing to change
func _UnmarshalerOptionWithDefault() UnmarshalerOption {
return UnmarshalerOptionFunc(func(*Unmarshaler) {
// nothing to change
})
}
func (o *Unmarshaler) ApplyOptions(options ...UnmarshalerOption) *Unmarshaler {
for _, opt := range options {
if opt == nil {
continue
}
opt.apply(o)
}
return o
}
================================================
FILE: go/encoding/protojson/encode.go
================================================
/*
*Copyright (c) 2022, kaydxh
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be
gitextract_tcizrmu1/
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── doc/
│ ├── health_check_design.md
│ ├── opentelemetry_design.md
│ └── rate_limit_design.md
├── doc.go
├── go/
│ ├── archive/
│ │ ├── archive.go
│ │ ├── option/
│ │ │ └── file_info.go
│ │ └── zip/
│ │ ├── zip.go
│ │ └── zip_test.go
│ ├── bytes/
│ │ ├── bytes.go
│ │ └── bytes_test.go
│ ├── client/
│ │ ├── client.go
│ │ ├── client.options.go
│ │ ├── client_options.go
│ │ └── client_test.go
│ ├── container/
│ │ ├── heap/
│ │ │ ├── heap.go
│ │ │ └── heap_test.go
│ │ ├── set/
│ │ │ ├── set.go
│ │ │ ├── set.interface.go
│ │ │ ├── set_interface_test.go
│ │ │ ├── set_string.go
│ │ │ ├── set_string_test.go
│ │ │ └── set_test.go
│ │ └── workqueue/
│ │ ├── queue.go
│ │ └── queue_test.go
│ ├── context/
│ │ ├── context.go
│ │ └── context_test.go
│ ├── crypto/
│ │ ├── aes/
│ │ │ ├── aes_cbc.go
│ │ │ ├── aes_cbc_test.go
│ │ │ └── error.go
│ │ ├── md5/
│ │ │ ├── md5.go
│ │ │ └── md5_test.go
│ │ └── sha256/
│ │ ├── sha256.go
│ │ └── sha256_test.go
│ ├── doc.go
│ ├── encoding/
│ │ ├── base64/
│ │ │ ├── base64.go
│ │ │ └── base64_test.go
│ │ ├── hash/
│ │ │ ├── hash.go
│ │ │ └── hash_test.go
│ │ ├── jwt/
│ │ │ ├── jwt.go
│ │ │ └── jwt_test.go
│ │ └── protojson/
│ │ ├── decode.go
│ │ ├── decode.option.go
│ │ ├── decode_option.go
│ │ ├── encode.go
│ │ ├── encode.option.go
│ │ ├── encode_option.go
│ │ ├── protojson_test.go
│ │ └── testdata/
│ │ ├── date.pb.go
│ │ └── date.proto
│ ├── errors/
│ │ ├── error.code.go
│ │ ├── error.grpc.go
│ │ ├── errors.go
│ │ ├── errors_test.go
│ │ └── handler.go
│ ├── filesystem/
│ │ ├── filesystem.go
│ │ └── mountpoint.go
│ ├── flag/
│ │ └── flag.go
│ ├── go.mod
│ ├── go.sum
│ ├── idgen/
│ │ ├── id_gen.go
│ │ ├── id_gen_test.go
│ │ ├── wk_id_gen.go
│ │ └── wk_id_gen_test.go
│ ├── io/
│ │ ├── copy.go
│ │ ├── copy_darwin.go
│ │ ├── copy_linux.go
│ │ ├── copy_test.go
│ │ ├── io.go
│ │ ├── io_test.go
│ │ └── testdata/
│ │ ├── dir/
│ │ │ ├── file/
│ │ │ │ └── 1.txt
│ │ │ └── hello.text
│ │ └── file/
│ │ └── 1.txt
│ ├── math/
│ │ ├── exp/
│ │ │ ├── exp.go
│ │ │ └── exp_test.go
│ │ ├── math.go
│ │ ├── math_test.go
│ │ └── rand/
│ │ ├── rand.go
│ │ └── rand_test.go
│ ├── net/
│ │ ├── grpc/
│ │ │ ├── example/
│ │ │ │ ├── data.pb.go
│ │ │ │ ├── data.proto
│ │ │ │ ├── data.repository.go
│ │ │ │ ├── data.repository_test.go
│ │ │ │ └── data_grpc.pb.go
│ │ │ ├── grpc_client.go
│ │ │ ├── grpc_client.option.go
│ │ │ ├── grpc_client.repository.factory.go
│ │ │ ├── grpc_client.repository.go
│ │ │ ├── grpc_client_option.go
│ │ │ ├── grpc_client_test.go
│ │ │ ├── grpc_stats.handler.go
│ │ │ └── ip.go
│ │ ├── http/
│ │ │ ├── clone.go
│ │ │ ├── example/
│ │ │ │ ├── data.pb.go
│ │ │ │ ├── data.proto
│ │ │ │ └── http_client.repository_test.go
│ │ │ ├── http_client.do.go
│ │ │ ├── http_client.go
│ │ │ ├── http_client.option.go
│ │ │ ├── http_client.repository.factory.go
│ │ │ ├── http_client.repository.go
│ │ │ ├── http_client_option.go
│ │ │ ├── http_client_proxy.go
│ │ │ ├── http_client_test.go
│ │ │ ├── http_error.go
│ │ │ ├── http_handler_chain.option.go
│ │ │ ├── http_handler_interceptor.go
│ │ │ ├── http_handler_interceptor.option.go
│ │ │ ├── http_host_context.go
│ │ │ ├── http_proxy_context.go
│ │ │ ├── http_request_id.go
│ │ │ ├── http_round_trip.go
│ │ │ ├── http_transport.go
│ │ │ ├── http_transport.host.go
│ │ │ ├── http_transport.proxy.go
│ │ │ ├── ip.go
│ │ │ └── response_writer.go
│ │ ├── ip.go
│ │ ├── ip_test.go
│ │ ├── mac.go
│ │ ├── mac_test.go
│ │ ├── parse.go
│ │ ├── resolver/
│ │ │ ├── build.go
│ │ │ ├── build.option.go
│ │ │ ├── build_option.go
│ │ │ ├── dns/
│ │ │ │ ├── dns_resolver.go
│ │ │ │ ├── dns_resolver_builder.option.go
│ │ │ │ └── dns_resolver_builder_option.go
│ │ │ ├── passthrough/
│ │ │ │ └── passthrough.go
│ │ │ ├── register.reslover.go
│ │ │ ├── resolve/
│ │ │ │ └── resolve.go
│ │ │ ├── resolve.all.option.go
│ │ │ ├── resolve.all_option.go
│ │ │ ├── resolve.now_option.go
│ │ │ ├── resolve.one.option.go
│ │ │ ├── resolve.one_option.go
│ │ │ ├── resolver.go
│ │ │ ├── resolver_test.go
│ │ │ ├── target.go
│ │ │ └── unix/
│ │ │ └── unix.go
│ │ └── url/
│ │ ├── url.go
│ │ ├── url.resolve.go
│ │ ├── url_codec.go
│ │ ├── url_option.go
│ │ ├── url_test.go
│ │ └── value.go
│ ├── os/
│ │ ├── env.go
│ │ ├── env_test.go
│ │ ├── exec/
│ │ │ ├── exec.go
│ │ │ ├── exec.options.go
│ │ │ ├── exec_options.go
│ │ │ └── exec_test.go
│ │ ├── file.go
│ │ ├── file_test.go
│ │ ├── getwd.go
│ │ ├── getwd_test.go
│ │ ├── proc.go
│ │ ├── proc_darwin.go
│ │ ├── proc_linux.go
│ │ ├── proc_test.go
│ │ ├── remove_file.go
│ │ ├── signal_posix.go
│ │ ├── term/
│ │ │ └── term.go
│ │ ├── value.go
│ │ └── value_test.go
│ ├── path/
│ │ └── filepath/
│ │ ├── match.go
│ │ ├── path.go
│ │ └── path_test.go
│ ├── reflect/
│ │ ├── array.go
│ │ ├── array_test.go
│ │ ├── error.go
│ │ ├── id.go
│ │ ├── struct.go
│ │ ├── struct_test.go
│ │ ├── truncate.go
│ │ ├── truncate_test.go
│ │ ├── value.go
│ │ └── value_test.go
│ ├── runtime/
│ │ ├── extern.go
│ │ ├── extern_test.go
│ │ ├── function.go
│ │ ├── function_test.go
│ │ ├── goroutine.go
│ │ ├── marshaler/
│ │ │ ├── jsonpb.marshaler.go
│ │ │ ├── jsonpb.marshaler.option.go
│ │ │ ├── jsonpb.marshaler_option.go
│ │ │ └── proto.marshaler.go
│ │ ├── meta.data.go
│ │ ├── panic.go
│ │ ├── panic_test.go
│ │ └── stack.go
│ ├── slices/
│ │ ├── slices.go
│ │ └── slices_test.go
│ ├── strconv/
│ │ ├── atoi.go
│ │ ├── atoi_test.go
│ │ ├── atonum.go
│ │ ├── atonum_test.go
│ │ └── itoa.go
│ ├── strings/
│ │ ├── string_slice.go
│ │ ├── string_slice_test.go
│ │ ├── strings.go
│ │ └── strings_test.go
│ ├── sync/
│ │ ├── atomic/
│ │ │ ├── file_lock.go
│ │ │ └── file_lock_test.go
│ │ ├── cond.go
│ │ └── cond_test.go
│ ├── syscall/
│ │ ├── disk.go
│ │ ├── disk_test.go
│ │ ├── memory_darwin.go
│ │ ├── memory_linux.go
│ │ ├── memory_linux_test.go
│ │ ├── rlimit.go
│ │ ├── rlimit_test.go
│ │ └── syscall.go
│ ├── time/
│ │ ├── backoff.go
│ │ ├── exponential_backoff.go
│ │ ├── exponential_backoff.options.go
│ │ ├── exponential_backoff_options.go
│ │ ├── exponential_backoff_test.go
│ │ ├── exponentialbackeoff_syncmap.go
│ │ ├── rate/
│ │ │ ├── rate.go
│ │ │ ├── rate_method.go
│ │ │ ├── rate_qps.go
│ │ │ ├── rate_qps_method.go
│ │ │ ├── rate_qps_test.go
│ │ │ └── rate_test.go
│ │ ├── time.go
│ │ ├── time_counter.go
│ │ ├── time_counter_test.go
│ │ ├── time_test.go
│ │ ├── wait.go
│ │ └── wait_test.go
│ ├── unsafe/
│ │ └── unsafe.go
│ └── utils/
│ ├── compare.go
│ ├── generics_get.go
│ └── generics_get_test.go
├── go.mod
├── go.sum
├── pkg/
│ ├── binlog/
│ │ ├── binlog.archive.go
│ │ ├── binlog.go
│ │ ├── binlog.option.go
│ │ ├── binlog.pb.go
│ │ ├── binlog.proto
│ │ ├── binlog.yaml
│ │ ├── binlog_option.go
│ │ ├── binlog_test.go
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── datastore/
│ │ │ ├── data.store.go
│ │ │ ├── dbstore/
│ │ │ │ └── db.store.go
│ │ │ ├── filestore/
│ │ │ │ └── file.store.go
│ │ │ └── message.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── config/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── container/
│ │ ├── docker/
│ │ │ └── docker.proto
│ │ ├── go.mod
│ │ └── go.sum
│ ├── crontab/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── crontab.go
│ │ ├── crontab.pb.go
│ │ ├── crontab.proto
│ │ ├── crontab.yaml
│ │ ├── crontab_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── testdata/
│ │ ├── 1.txt
│ │ ├── 2.txt
│ │ └── 3.txt
│ ├── database/
│ │ ├── db.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── mysql/
│ │ │ ├── config.go
│ │ │ ├── config.option.go
│ │ │ ├── config_option.go
│ │ │ ├── migrate/
│ │ │ │ └── rename_db.sql
│ │ │ ├── mysql.go
│ │ │ ├── mysql.option.go
│ │ │ ├── mysql.pb.go
│ │ │ ├── mysql.proto
│ │ │ ├── mysql.yaml
│ │ │ ├── mysql_operate_test.go
│ │ │ ├── mysql_options.go
│ │ │ ├── mysql_test.go
│ │ │ ├── mysql_transaction.go
│ │ │ ├── sql.go
│ │ │ ├── sql_exec.go
│ │ │ ├── sql_test.go
│ │ │ └── sql_type.go
│ │ └── redis/
│ │ ├── command.get.values.go
│ │ ├── command.hset.go
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── redis.go
│ │ ├── redis.options.go
│ │ ├── redis.pb.go
│ │ ├── redis.proto
│ │ ├── redis.yaml
│ │ ├── redis_benchmark_test.go
│ │ ├── redis_hset_test.go
│ │ ├── redis_key_delete_test.go
│ │ ├── redis_key_test.go
│ │ ├── redis_list_test.go
│ │ ├── redis_options.go
│ │ ├── redis_set_test.go
│ │ ├── redis_string_test.go
│ │ ├── redis_transaction_test.go
│ │ ├── redis_type.go
│ │ └── redis_zset_test.go
│ ├── discovery/
│ │ ├── consul/
│ │ │ └── discovery.go
│ │ ├── etcd/
│ │ │ ├── config.go
│ │ │ ├── config.option.go
│ │ │ ├── config_option.go
│ │ │ ├── etcd.go
│ │ │ ├── etcd.option.go
│ │ │ ├── etcd.pb.go
│ │ │ ├── etcd.proto
│ │ │ ├── etcd.watch.go
│ │ │ ├── etcd.yaml
│ │ │ ├── etcd_options.go
│ │ │ ├── etcd_test.go
│ │ │ └── etcd_type.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── file-cleanup/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── disk/
│ │ │ ├── disk_cleaner.go
│ │ │ ├── disk_cleaner.option.go
│ │ │ ├── disk_cleaner.pb.go
│ │ │ ├── disk_cleaner.proto
│ │ │ └── disk_cleaner_option.go
│ │ ├── disk_cleaner_test.go
│ │ ├── diskcleaner.yaml
│ │ ├── file_cleaner.go
│ │ ├── file_cleaner.option.go
│ │ ├── file_cleaner_option.go
│ │ ├── file_cleaner_test.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── file-rotate/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── rotate_file.go
│ │ ├── rotate_file.option.go
│ │ ├── rotate_file_option.go
│ │ └── rotate_file_test.go
│ ├── file-transfer/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── file.transfer.go
│ │ ├── file.transfer.option.go
│ │ ├── file.transfer_option.go
│ │ ├── file.transfer_test.go
│ │ ├── ft.pb.go
│ │ ├── ft.proto
│ │ ├── ft.yaml
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── upload/
│ │ ├── upload.svr.go
│ │ └── upload.svr_test.go
│ ├── fsnotify/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── fsnotify.go
│ │ ├── fsnotify.option.go
│ │ ├── fsnotify.pb.go
│ │ ├── fsnotify.proto
│ │ ├── fsnotify.yaml
│ │ ├── fsnotify_option.go
│ │ ├── fsnotify_test.go
│ │ ├── go.mod
│ │ └── go.sum
│ ├── gocv/
│ │ ├── cgo/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── api/
│ │ │ │ └── openapi-spec/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── Makefile
│ │ │ │ ├── gocv/
│ │ │ │ │ ├── CMakeLists.txt
│ │ │ │ │ ├── gocv.magick.pb.go
│ │ │ │ │ ├── gocv.magick.pb.h
│ │ │ │ │ ├── gocv.magick.proto
│ │ │ │ │ └── libproto-gocv.a
│ │ │ │ ├── proto.gen.go
│ │ │ │ ├── scripts/
│ │ │ │ │ └── proto-gen.sh
│ │ │ │ ├── thirdparty.cmake
│ │ │ │ ├── thirdparty.srv.cmake
│ │ │ │ └── types/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── code/
│ │ │ │ │ ├── code.error.go
│ │ │ │ │ ├── sdk-go.code.pb.go
│ │ │ │ │ ├── sdk-go.code.pb.h
│ │ │ │ │ └── sdk-go.code.proto
│ │ │ │ ├── libproto-types.a
│ │ │ │ ├── sdk-go.types.pb.go
│ │ │ │ ├── sdk-go.types.pb.h
│ │ │ │ └── sdk-go.types.proto
│ │ │ ├── cmake/
│ │ │ │ └── FindProtobuf.cmake
│ │ │ ├── gocv/
│ │ │ │ ├── Makefile
│ │ │ │ ├── gocv.go
│ │ │ │ ├── gocv_test.go
│ │ │ │ ├── magick.h
│ │ │ │ ├── magick_linux_amd64.cpp
│ │ │ │ └── magick_linux_amd64.go
│ │ │ ├── pkgconfig/
│ │ │ │ ├── graphics-magick.pc
│ │ │ │ ├── opencv2.pc
│ │ │ │ ├── opencv4.pc
│ │ │ │ ├── protobuf.pc
│ │ │ │ ├── pybind11.pc
│ │ │ │ └── python3-embed.pc
│ │ │ ├── script/
│ │ │ │ └── version.sh
│ │ │ ├── swig/
│ │ │ │ ├── gocv/
│ │ │ │ │ ├── Makefile
│ │ │ │ │ ├── cgo.go
│ │ │ │ │ ├── gocv.go
│ │ │ │ │ ├── gocv.h
│ │ │ │ │ ├── gocv.swigcxx
│ │ │ │ │ ├── gocv_linux_amd64.cpp
│ │ │ │ │ ├── gocv_linux_amd64.go
│ │ │ │ │ ├── gocv_test.go
│ │ │ │ │ ├── gocv_wrap.cxx
│ │ │ │ │ └── gocv_wrap.h
│ │ │ │ ├── pycv/
│ │ │ │ │ ├── Makefile
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── cgo.go
│ │ │ │ │ ├── pycv.go
│ │ │ │ │ ├── pycv.h
│ │ │ │ │ ├── pycv.py
│ │ │ │ │ ├── pycv.swigcxx
│ │ │ │ │ ├── pycv_linux_amd64.cpp
│ │ │ │ │ ├── pycv_test.go
│ │ │ │ │ ├── pycv_wrap.cxx
│ │ │ │ │ └── pycv_wrap.h
│ │ │ │ └── types/
│ │ │ │ └── pybind11/
│ │ │ │ ├── pybind11.swigcxx
│ │ │ │ └── pybind11_mock.h
│ │ │ └── third_path/
│ │ │ ├── graphics-magick/
│ │ │ │ ├── bin/
│ │ │ │ │ ├── GraphicsMagick++-config
│ │ │ │ │ ├── GraphicsMagick-config
│ │ │ │ │ ├── GraphicsMagickWand-config
│ │ │ │ │ └── gm
│ │ │ │ ├── include/
│ │ │ │ │ ├── GraphicsMagick/
│ │ │ │ │ │ ├── Magick++/
│ │ │ │ │ │ │ ├── Blob.h
│ │ │ │ │ │ │ ├── CoderInfo.h
│ │ │ │ │ │ │ ├── Color.h
│ │ │ │ │ │ │ ├── Drawable.h
│ │ │ │ │ │ │ ├── Exception.h
│ │ │ │ │ │ │ ├── Geometry.h
│ │ │ │ │ │ │ ├── Image.h
│ │ │ │ │ │ │ ├── Include.h
│ │ │ │ │ │ │ ├── Montage.h
│ │ │ │ │ │ │ ├── Pixels.h
│ │ │ │ │ │ │ ├── STL.h
│ │ │ │ │ │ │ └── TypeMetric.h
│ │ │ │ │ │ ├── Magick++.h
│ │ │ │ │ │ ├── magick/
│ │ │ │ │ │ │ ├── analyze.h
│ │ │ │ │ │ │ ├── api.h
│ │ │ │ │ │ │ ├── attribute.h
│ │ │ │ │ │ │ ├── average.h
│ │ │ │ │ │ │ ├── blob.h
│ │ │ │ │ │ │ ├── cdl.h
│ │ │ │ │ │ │ ├── channel.h
│ │ │ │ │ │ │ ├── color.h
│ │ │ │ │ │ │ ├── color_lookup.h
│ │ │ │ │ │ │ ├── colormap.h
│ │ │ │ │ │ │ ├── colorspace.h
│ │ │ │ │ │ │ ├── command.h
│ │ │ │ │ │ │ ├── common.h
│ │ │ │ │ │ │ ├── compare.h
│ │ │ │ │ │ │ ├── composite.h
│ │ │ │ │ │ │ ├── compress.h
│ │ │ │ │ │ │ ├── confirm_access.h
│ │ │ │ │ │ │ ├── constitute.h
│ │ │ │ │ │ │ ├── decorate.h
│ │ │ │ │ │ │ ├── delegate.h
│ │ │ │ │ │ │ ├── deprecate.h
│ │ │ │ │ │ │ ├── describe.h
│ │ │ │ │ │ │ ├── draw.h
│ │ │ │ │ │ │ ├── effect.h
│ │ │ │ │ │ │ ├── enhance.h
│ │ │ │ │ │ │ ├── error.h
│ │ │ │ │ │ │ ├── forward.h
│ │ │ │ │ │ │ ├── fx.h
│ │ │ │ │ │ │ ├── gem.h
│ │ │ │ │ │ │ ├── gradient.h
│ │ │ │ │ │ │ ├── hclut.h
│ │ │ │ │ │ │ ├── image.h
│ │ │ │ │ │ │ ├── list.h
│ │ │ │ │ │ │ ├── log.h
│ │ │ │ │ │ │ ├── magic.h
│ │ │ │ │ │ │ ├── magick.h
│ │ │ │ │ │ │ ├── magick_config.h
│ │ │ │ │ │ │ ├── magick_types.h
│ │ │ │ │ │ │ ├── memory.h
│ │ │ │ │ │ │ ├── module.h
│ │ │ │ │ │ │ ├── monitor.h
│ │ │ │ │ │ │ ├── montage.h
│ │ │ │ │ │ │ ├── operator.h
│ │ │ │ │ │ │ ├── paint.h
│ │ │ │ │ │ │ ├── pixel_cache.h
│ │ │ │ │ │ │ ├── pixel_iterator.h
│ │ │ │ │ │ │ ├── plasma.h
│ │ │ │ │ │ │ ├── profile.h
│ │ │ │ │ │ │ ├── quantize.h
│ │ │ │ │ │ │ ├── random.h
│ │ │ │ │ │ │ ├── registry.h
│ │ │ │ │ │ │ ├── render.h
│ │ │ │ │ │ │ ├── resize.h
│ │ │ │ │ │ │ ├── resource.h
│ │ │ │ │ │ │ ├── shear.h
│ │ │ │ │ │ │ ├── signature.h
│ │ │ │ │ │ │ ├── statistics.h
│ │ │ │ │ │ │ ├── symbols.h
│ │ │ │ │ │ │ ├── texture.h
│ │ │ │ │ │ │ ├── timer.h
│ │ │ │ │ │ │ ├── transform.h
│ │ │ │ │ │ │ ├── type.h
│ │ │ │ │ │ │ ├── utility.h
│ │ │ │ │ │ │ └── version.h
│ │ │ │ │ │ └── wand/
│ │ │ │ │ │ ├── drawing_wand.h
│ │ │ │ │ │ ├── magick_wand.h
│ │ │ │ │ │ ├── pixel_wand.h
│ │ │ │ │ │ ├── wand_api.h
│ │ │ │ │ │ └── wand_symbols.h
│ │ │ │ │ ├── Magick++/
│ │ │ │ │ │ ├── Blob.h
│ │ │ │ │ │ ├── CoderInfo.h
│ │ │ │ │ │ ├── Color.h
│ │ │ │ │ │ ├── Drawable.h
│ │ │ │ │ │ ├── Exception.h
│ │ │ │ │ │ ├── Geometry.h
│ │ │ │ │ │ ├── Image.h
│ │ │ │ │ │ ├── Include.h
│ │ │ │ │ │ ├── Montage.h
│ │ │ │ │ │ ├── Pixels.h
│ │ │ │ │ │ ├── STL.h
│ │ │ │ │ │ └── TypeMetric.h
│ │ │ │ │ ├── Magick++.h
│ │ │ │ │ ├── magick/
│ │ │ │ │ │ ├── analyze.h
│ │ │ │ │ │ ├── api.h
│ │ │ │ │ │ ├── attribute.h
│ │ │ │ │ │ ├── average.h
│ │ │ │ │ │ ├── blob.h
│ │ │ │ │ │ ├── cdl.h
│ │ │ │ │ │ ├── channel.h
│ │ │ │ │ │ ├── color.h
│ │ │ │ │ │ ├── color_lookup.h
│ │ │ │ │ │ ├── colormap.h
│ │ │ │ │ │ ├── colorspace.h
│ │ │ │ │ │ ├── command.h
│ │ │ │ │ │ ├── common.h
│ │ │ │ │ │ ├── compare.h
│ │ │ │ │ │ ├── composite.h
│ │ │ │ │ │ ├── compress.h
│ │ │ │ │ │ ├── confirm_access.h
│ │ │ │ │ │ ├── constitute.h
│ │ │ │ │ │ ├── decorate.h
│ │ │ │ │ │ ├── delegate.h
│ │ │ │ │ │ ├── deprecate.h
│ │ │ │ │ │ ├── describe.h
│ │ │ │ │ │ ├── draw.h
│ │ │ │ │ │ ├── effect.h
│ │ │ │ │ │ ├── enhance.h
│ │ │ │ │ │ ├── error.h
│ │ │ │ │ │ ├── forward.h
│ │ │ │ │ │ ├── fx.h
│ │ │ │ │ │ ├── gem.h
│ │ │ │ │ │ ├── gradient.h
│ │ │ │ │ │ ├── hclut.h
│ │ │ │ │ │ ├── image.h
│ │ │ │ │ │ ├── list.h
│ │ │ │ │ │ ├── log.h
│ │ │ │ │ │ ├── magic.h
│ │ │ │ │ │ ├── magick.h
│ │ │ │ │ │ ├── magick_config.h
│ │ │ │ │ │ ├── magick_types.h
│ │ │ │ │ │ ├── memory.h
│ │ │ │ │ │ ├── module.h
│ │ │ │ │ │ ├── monitor.h
│ │ │ │ │ │ ├── montage.h
│ │ │ │ │ │ ├── operator.h
│ │ │ │ │ │ ├── paint.h
│ │ │ │ │ │ ├── pixel_cache.h
│ │ │ │ │ │ ├── pixel_iterator.h
│ │ │ │ │ │ ├── plasma.h
│ │ │ │ │ │ ├── profile.h
│ │ │ │ │ │ ├── quantize.h
│ │ │ │ │ │ ├── random.h
│ │ │ │ │ │ ├── registry.h
│ │ │ │ │ │ ├── render.h
│ │ │ │ │ │ ├── resize.h
│ │ │ │ │ │ ├── resource.h
│ │ │ │ │ │ ├── shear.h
│ │ │ │ │ │ ├── signature.h
│ │ │ │ │ │ ├── statistics.h
│ │ │ │ │ │ ├── symbols.h
│ │ │ │ │ │ ├── texture.h
│ │ │ │ │ │ ├── timer.h
│ │ │ │ │ │ ├── transform.h
│ │ │ │ │ │ ├── type.h
│ │ │ │ │ │ ├── utility.h
│ │ │ │ │ │ └── version.h
│ │ │ │ │ └── wand/
│ │ │ │ │ ├── drawing_wand.h
│ │ │ │ │ ├── magick_wand.h
│ │ │ │ │ ├── pixel_wand.h
│ │ │ │ │ ├── wand_api.h
│ │ │ │ │ └── wand_symbols.h
│ │ │ │ ├── lib/
│ │ │ │ │ ├── GraphicsMagick-1.3.35/
│ │ │ │ │ │ └── config/
│ │ │ │ │ │ ├── delegates.mgk
│ │ │ │ │ │ ├── type-ghostscript.mgk
│ │ │ │ │ │ ├── type-solaris.mgk
│ │ │ │ │ │ ├── type-windows.mgk
│ │ │ │ │ │ └── type.mgk
│ │ │ │ │ ├── libGraphicsMagick++.a
│ │ │ │ │ ├── libGraphicsMagick++.so.12.4.3
│ │ │ │ │ ├── libGraphicsMagick.a
│ │ │ │ │ ├── libGraphicsMagick.so.3.21.0
│ │ │ │ │ ├── libGraphicsMagickWand.a
│ │ │ │ │ ├── libGraphicsMagickWand.so.2.9.4
│ │ │ │ │ ├── libjbig.so.2.0
│ │ │ │ │ ├── libpng15.so.15
│ │ │ │ │ ├── libtiff.so.5
│ │ │ │ │ ├── libtiff.so.5.2.0
│ │ │ │ │ ├── libwebp.so.4
│ │ │ │ │ ├── libwebp.so.4.0.2
│ │ │ │ │ ├── libwebpmux.so.0
│ │ │ │ │ ├── libwebpmux.so.0.0.0
│ │ │ │ │ └── pkgconfig/
│ │ │ │ │ ├── GraphicsMagick++.pc
│ │ │ │ │ ├── GraphicsMagick.pc
│ │ │ │ │ └── GraphicsMagickWand.pc
│ │ │ │ └── share/
│ │ │ │ ├── GraphicsMagick-1.3.35/
│ │ │ │ │ └── config/
│ │ │ │ │ ├── colors.mgk
│ │ │ │ │ ├── log.mgk
│ │ │ │ │ └── modules.mgk
│ │ │ │ ├── doc/
│ │ │ │ │ └── GraphicsMagick/
│ │ │ │ │ ├── ChangeLog
│ │ │ │ │ ├── ChangeLog.2001
│ │ │ │ │ ├── ChangeLog.2002
│ │ │ │ │ ├── ChangeLog.2003
│ │ │ │ │ ├── ChangeLog.2004
│ │ │ │ │ ├── ChangeLog.2005
│ │ │ │ │ ├── ChangeLog.2006
│ │ │ │ │ ├── ChangeLog.2007
│ │ │ │ │ ├── ChangeLog.2008
│ │ │ │ │ ├── ChangeLog.2009
│ │ │ │ │ ├── ChangeLog.2010
│ │ │ │ │ ├── ChangeLog.2011
│ │ │ │ │ ├── ChangeLog.2012
│ │ │ │ │ ├── ChangeLog.2013
│ │ │ │ │ ├── ChangeLog.2014
│ │ │ │ │ ├── ChangeLog.2015
│ │ │ │ │ ├── ChangeLog.2016
│ │ │ │ │ ├── ChangeLog.2017
│ │ │ │ │ ├── ChangeLog.2018
│ │ │ │ │ ├── ChangeLog.2019
│ │ │ │ │ ├── Copyright.txt
│ │ │ │ │ ├── NEWS.txt
│ │ │ │ │ └── www/
│ │ │ │ │ ├── ChangeLog-2001.html
│ │ │ │ │ ├── ChangeLog-2002.html
│ │ │ │ │ ├── ChangeLog-2003.html
│ │ │ │ │ ├── ChangeLog-2004.html
│ │ │ │ │ ├── ChangeLog-2005.html
│ │ │ │ │ ├── ChangeLog-2006.html
│ │ │ │ │ ├── ChangeLog-2007.html
│ │ │ │ │ ├── ChangeLog-2008.html
│ │ │ │ │ ├── ChangeLog-2009.html
│ │ │ │ │ ├── ChangeLog-2010.html
│ │ │ │ │ ├── ChangeLog-2011.html
│ │ │ │ │ ├── ChangeLog-2012.html
│ │ │ │ │ ├── ChangeLog-2013.html
│ │ │ │ │ ├── ChangeLog-2014.html
│ │ │ │ │ ├── ChangeLog-2015.html
│ │ │ │ │ ├── ChangeLog-2016.html
│ │ │ │ │ ├── ChangeLog-2017.html
│ │ │ │ │ ├── ChangeLog-2018.html
│ │ │ │ │ ├── ChangeLog-2019.html
│ │ │ │ │ ├── Changelog.html
│ │ │ │ │ ├── Changes.html
│ │ │ │ │ ├── Copyright.html
│ │ │ │ │ ├── FAQ.html
│ │ │ │ │ ├── GraphicsMagick.html
│ │ │ │ │ ├── Hg.html
│ │ │ │ │ ├── INSTALL-unix.html
│ │ │ │ │ ├── INSTALL-windows.html
│ │ │ │ │ ├── ImageMagickObject.html
│ │ │ │ │ ├── Magick++/
│ │ │ │ │ │ ├── Blob.html
│ │ │ │ │ │ ├── ChangeLog.html
│ │ │ │ │ │ ├── CoderInfo.html
│ │ │ │ │ │ ├── Color.html
│ │ │ │ │ │ ├── Drawable.html
│ │ │ │ │ │ ├── Enumerations.html
│ │ │ │ │ │ ├── Exception.html
│ │ │ │ │ │ ├── FormatCharacters.html
│ │ │ │ │ │ ├── Geometry.html
│ │ │ │ │ │ ├── Image.html
│ │ │ │ │ │ ├── ImageDesign.html
│ │ │ │ │ │ ├── Montage.html
│ │ │ │ │ │ ├── PixelPacket.html
│ │ │ │ │ │ ├── Pixels.html
│ │ │ │ │ │ ├── STL.html
│ │ │ │ │ │ ├── TypeMetric.html
│ │ │ │ │ │ └── index.html
│ │ │ │ │ ├── NEWS.html
│ │ │ │ │ ├── OpenMP.html
│ │ │ │ │ ├── README.html
│ │ │ │ │ ├── animate.html
│ │ │ │ │ ├── api/
│ │ │ │ │ │ ├── animate.html
│ │ │ │ │ │ ├── annotate.html
│ │ │ │ │ │ ├── api.html
│ │ │ │ │ │ ├── attribute.html
│ │ │ │ │ │ ├── average.html
│ │ │ │ │ │ ├── blob.html
│ │ │ │ │ │ ├── cdl.html
│ │ │ │ │ │ ├── channel.html
│ │ │ │ │ │ ├── color.html
│ │ │ │ │ │ ├── colormap.html
│ │ │ │ │ │ ├── compare.html
│ │ │ │ │ │ ├── composite.html
│ │ │ │ │ │ ├── confirm_access.html
│ │ │ │ │ │ ├── constitute.html
│ │ │ │ │ │ ├── decorate.html
│ │ │ │ │ │ ├── deprecate.html
│ │ │ │ │ │ ├── describe.html
│ │ │ │ │ │ ├── display.html
│ │ │ │ │ │ ├── draw.html
│ │ │ │ │ │ ├── effect.html
│ │ │ │ │ │ ├── enhance.html
│ │ │ │ │ │ ├── error.html
│ │ │ │ │ │ ├── export.html
│ │ │ │ │ │ ├── fx.html
│ │ │ │ │ │ ├── hclut.html
│ │ │ │ │ │ ├── image.html
│ │ │ │ │ │ ├── import.html
│ │ │ │ │ │ ├── list.html
│ │ │ │ │ │ ├── magick.html
│ │ │ │ │ │ ├── memory.html
│ │ │ │ │ │ ├── monitor.html
│ │ │ │ │ │ ├── montage.html
│ │ │ │ │ │ ├── operator.html
│ │ │ │ │ │ ├── paint.html
│ │ │ │ │ │ ├── pixel_cache.html
│ │ │ │ │ │ ├── pixel_iterator.html
│ │ │ │ │ │ ├── plasma.html
│ │ │ │ │ │ ├── profile.html
│ │ │ │ │ │ ├── quantize.html
│ │ │ │ │ │ ├── registry.html
│ │ │ │ │ │ ├── render.html
│ │ │ │ │ │ ├── resize.html
│ │ │ │ │ │ ├── resource.html
│ │ │ │ │ │ ├── segment.html
│ │ │ │ │ │ ├── shear.html
│ │ │ │ │ │ ├── signature.html
│ │ │ │ │ │ ├── statistics.html
│ │ │ │ │ │ ├── texture.html
│ │ │ │ │ │ ├── transform.html
│ │ │ │ │ │ ├── types.html
│ │ │ │ │ │ └── widget.html
│ │ │ │ │ ├── authors.html
│ │ │ │ │ ├── batch.html
│ │ │ │ │ ├── benchmark.html
│ │ │ │ │ ├── benchmarks.html
│ │ │ │ │ ├── bugs.html
│ │ │ │ │ ├── color.html
│ │ │ │ │ ├── compare.html
│ │ │ │ │ ├── composite.html
│ │ │ │ │ ├── conjure.html
│ │ │ │ │ ├── contribute.html
│ │ │ │ │ ├── convert.html
│ │ │ │ │ ├── display.html
│ │ │ │ │ ├── docutils-api.css
│ │ │ │ │ ├── docutils-articles.css
│ │ │ │ │ ├── download.html
│ │ │ │ │ ├── formats.html
│ │ │ │ │ ├── gm.html
│ │ │ │ │ ├── identify.html
│ │ │ │ │ ├── import.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── links.html
│ │ │ │ │ ├── magick.css
│ │ │ │ │ ├── miff.html
│ │ │ │ │ ├── mission.html
│ │ │ │ │ ├── mogrify.html
│ │ │ │ │ ├── montage.html
│ │ │ │ │ ├── motion-picture.html
│ │ │ │ │ ├── perl.html
│ │ │ │ │ ├── process.html
│ │ │ │ │ ├── programming.html
│ │ │ │ │ ├── project.html
│ │ │ │ │ ├── quantize.html
│ │ │ │ │ ├── reference.html
│ │ │ │ │ ├── security.html
│ │ │ │ │ ├── smile.c
│ │ │ │ │ ├── thanks.html
│ │ │ │ │ ├── time.html
│ │ │ │ │ ├── tools.html
│ │ │ │ │ ├── utilities.html
│ │ │ │ │ ├── version.html
│ │ │ │ │ └── wand/
│ │ │ │ │ ├── drawing_wand.html
│ │ │ │ │ ├── magick_wand.html
│ │ │ │ │ ├── pixel_wand.html
│ │ │ │ │ └── wand.html
│ │ │ │ └── man/
│ │ │ │ ├── man1/
│ │ │ │ │ ├── GraphicsMagick++-config.1
│ │ │ │ │ ├── GraphicsMagick-config.1
│ │ │ │ │ ├── GraphicsMagickWand-config.1
│ │ │ │ │ └── gm.1
│ │ │ │ ├── man4/
│ │ │ │ │ └── miff.4
│ │ │ │ └── man5/
│ │ │ │ └── quantize.5
│ │ │ ├── opencv2/
│ │ │ │ ├── include/
│ │ │ │ │ ├── opencv/
│ │ │ │ │ │ ├── cv.h
│ │ │ │ │ │ ├── cv.hpp
│ │ │ │ │ │ ├── cvaux.h
│ │ │ │ │ │ ├── cvaux.hpp
│ │ │ │ │ │ ├── cvwimage.h
│ │ │ │ │ │ ├── cxcore.h
│ │ │ │ │ │ ├── cxcore.hpp
│ │ │ │ │ │ ├── cxeigen.hpp
│ │ │ │ │ │ ├── cxmisc.h
│ │ │ │ │ │ ├── highgui.h
│ │ │ │ │ │ └── ml.h
│ │ │ │ │ └── opencv2/
│ │ │ │ │ ├── calib3d/
│ │ │ │ │ │ └── calib3d.hpp
│ │ │ │ │ ├── contrib/
│ │ │ │ │ │ ├── contrib.hpp
│ │ │ │ │ │ ├── detection_based_tracker.hpp
│ │ │ │ │ │ ├── hybridtracker.hpp
│ │ │ │ │ │ ├── openfabmap.hpp
│ │ │ │ │ │ └── retina.hpp
│ │ │ │ │ ├── features2d/
│ │ │ │ │ │ └── features2d.hpp
│ │ │ │ │ ├── flann/
│ │ │ │ │ │ ├── all_indices.h
│ │ │ │ │ │ ├── allocator.h
│ │ │ │ │ │ ├── any.h
│ │ │ │ │ │ ├── autotuned_index.h
│ │ │ │ │ │ ├── composite_index.h
│ │ │ │ │ │ ├── config.h
│ │ │ │ │ │ ├── defines.h
│ │ │ │ │ │ ├── dist.h
│ │ │ │ │ │ ├── dummy.h
│ │ │ │ │ │ ├── dynamic_bitset.h
│ │ │ │ │ │ ├── flann.hpp
│ │ │ │ │ │ ├── flann_base.hpp
│ │ │ │ │ │ ├── general.h
│ │ │ │ │ │ ├── ground_truth.h
│ │ │ │ │ │ ├── hdf5.h
│ │ │ │ │ │ ├── heap.h
│ │ │ │ │ │ ├── hierarchical_clustering_index.h
│ │ │ │ │ │ ├── index_testing.h
│ │ │ │ │ │ ├── kdtree_index.h
│ │ │ │ │ │ ├── kdtree_single_index.h
│ │ │ │ │ │ ├── kmeans_index.h
│ │ │ │ │ │ ├── linear_index.h
│ │ │ │ │ │ ├── logger.h
│ │ │ │ │ │ ├── lsh_index.h
│ │ │ │ │ │ ├── lsh_table.h
│ │ │ │ │ │ ├── matrix.h
│ │ │ │ │ │ ├── miniflann.hpp
│ │ │ │ │ │ ├── nn_index.h
│ │ │ │ │ │ ├── object_factory.h
│ │ │ │ │ │ ├── params.h
│ │ │ │ │ │ ├── random.h
│ │ │ │ │ │ ├── result_set.h
│ │ │ │ │ │ ├── sampling.h
│ │ │ │ │ │ ├── saving.h
│ │ │ │ │ │ ├── simplex_downhill.h
│ │ │ │ │ │ └── timer.h
│ │ │ │ │ ├── gpu/
│ │ │ │ │ │ ├── device/
│ │ │ │ │ │ │ ├── block.hpp
│ │ │ │ │ │ │ ├── border_interpolate.hpp
│ │ │ │ │ │ │ ├── color.hpp
│ │ │ │ │ │ │ ├── common.hpp
│ │ │ │ │ │ │ ├── datamov_utils.hpp
│ │ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ │ ├── color_detail.hpp
│ │ │ │ │ │ │ │ ├── reduce.hpp
│ │ │ │ │ │ │ │ ├── reduce_key_val.hpp
│ │ │ │ │ │ │ │ ├── transform_detail.hpp
│ │ │ │ │ │ │ │ ├── type_traits_detail.hpp
│ │ │ │ │ │ │ │ └── vec_distance_detail.hpp
│ │ │ │ │ │ │ ├── dynamic_smem.hpp
│ │ │ │ │ │ │ ├── emulation.hpp
│ │ │ │ │ │ │ ├── filters.hpp
│ │ │ │ │ │ │ ├── funcattrib.hpp
│ │ │ │ │ │ │ ├── functional.hpp
│ │ │ │ │ │ │ ├── limits.hpp
│ │ │ │ │ │ │ ├── reduce.hpp
│ │ │ │ │ │ │ ├── saturate_cast.hpp
│ │ │ │ │ │ │ ├── scan.hpp
│ │ │ │ │ │ │ ├── simd_functions.hpp
│ │ │ │ │ │ │ ├── static_check.hpp
│ │ │ │ │ │ │ ├── transform.hpp
│ │ │ │ │ │ │ ├── type_traits.hpp
│ │ │ │ │ │ │ ├── utility.hpp
│ │ │ │ │ │ │ ├── vec_distance.hpp
│ │ │ │ │ │ │ ├── vec_math.hpp
│ │ │ │ │ │ │ ├── vec_traits.hpp
│ │ │ │ │ │ │ ├── warp.hpp
│ │ │ │ │ │ │ ├── warp_reduce.hpp
│ │ │ │ │ │ │ └── warp_shuffle.hpp
│ │ │ │ │ │ ├── devmem2d.hpp
│ │ │ │ │ │ ├── gpu.hpp
│ │ │ │ │ │ ├── gpumat.hpp
│ │ │ │ │ │ └── stream_accessor.hpp
│ │ │ │ │ ├── highgui/
│ │ │ │ │ │ ├── cap_ios.h
│ │ │ │ │ │ ├── highgui.hpp
│ │ │ │ │ │ ├── highgui_c.h
│ │ │ │ │ │ └── ios.h
│ │ │ │ │ ├── imgproc/
│ │ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ │ ├── imgproc_c.h
│ │ │ │ │ │ └── types_c.h
│ │ │ │ │ ├── legacy/
│ │ │ │ │ │ ├── blobtrack.hpp
│ │ │ │ │ │ ├── compat.hpp
│ │ │ │ │ │ ├── legacy.hpp
│ │ │ │ │ │ └── streams.hpp
│ │ │ │ │ ├── ml/
│ │ │ │ │ │ └── ml.hpp
│ │ │ │ │ ├── nonfree/
│ │ │ │ │ │ ├── features2d.hpp
│ │ │ │ │ │ ├── gpu.hpp
│ │ │ │ │ │ ├── nonfree.hpp
│ │ │ │ │ │ └── ocl.hpp
│ │ │ │ │ ├── objdetect/
│ │ │ │ │ │ └── objdetect.hpp
│ │ │ │ │ ├── ocl/
│ │ │ │ │ │ ├── matrix_operations.hpp
│ │ │ │ │ │ └── ocl.hpp
│ │ │ │ │ ├── opencv.hpp
│ │ │ │ │ ├── opencv_modules.hpp
│ │ │ │ │ ├── photo/
│ │ │ │ │ │ ├── photo.hpp
│ │ │ │ │ │ └── photo_c.h
│ │ │ │ │ ├── stitching/
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ ├── autocalib.hpp
│ │ │ │ │ │ │ ├── blenders.hpp
│ │ │ │ │ │ │ ├── camera.hpp
│ │ │ │ │ │ │ ├── exposure_compensate.hpp
│ │ │ │ │ │ │ ├── matchers.hpp
│ │ │ │ │ │ │ ├── motion_estimators.hpp
│ │ │ │ │ │ │ ├── seam_finders.hpp
│ │ │ │ │ │ │ ├── util.hpp
│ │ │ │ │ │ │ ├── util_inl.hpp
│ │ │ │ │ │ │ ├── warpers.hpp
│ │ │ │ │ │ │ └── warpers_inl.hpp
│ │ │ │ │ │ ├── stitcher.hpp
│ │ │ │ │ │ └── warpers.hpp
│ │ │ │ │ ├── superres/
│ │ │ │ │ │ ├── optical_flow.hpp
│ │ │ │ │ │ └── superres.hpp
│ │ │ │ │ ├── ts/
│ │ │ │ │ │ ├── gpu_perf.hpp
│ │ │ │ │ │ ├── gpu_test.hpp
│ │ │ │ │ │ ├── ts.hpp
│ │ │ │ │ │ ├── ts_gtest.h
│ │ │ │ │ │ └── ts_perf.hpp
│ │ │ │ │ ├── video/
│ │ │ │ │ │ ├── background_segm.hpp
│ │ │ │ │ │ ├── tracking.hpp
│ │ │ │ │ │ └── video.hpp
│ │ │ │ │ └── videostab/
│ │ │ │ │ ├── deblurring.hpp
│ │ │ │ │ ├── fast_marching.hpp
│ │ │ │ │ ├── fast_marching_inl.hpp
│ │ │ │ │ ├── frame_source.hpp
│ │ │ │ │ ├── global_motion.hpp
│ │ │ │ │ ├── inpainting.hpp
│ │ │ │ │ ├── log.hpp
│ │ │ │ │ ├── motion_stabilizing.hpp
│ │ │ │ │ ├── optical_flow.hpp
│ │ │ │ │ ├── stabilizer.hpp
│ │ │ │ │ └── videostab.hpp
│ │ │ │ ├── lib/
│ │ │ │ │ ├── libIlmImf.a
│ │ │ │ │ ├── libjpeg.a
│ │ │ │ │ ├── libjpeg.so.62.3.0
│ │ │ │ │ ├── liblibjasper.a
│ │ │ │ │ ├── liblibpng.a
│ │ │ │ │ ├── liblibtiff.a
│ │ │ │ │ ├── libopencv_calib3d.so.2.4.12
│ │ │ │ │ ├── libopencv_contrib.so.2.4.12
│ │ │ │ │ ├── libopencv_core.so.2.4.12
│ │ │ │ │ ├── libopencv_features2d.so.2.4.12
│ │ │ │ │ ├── libopencv_flann.so.2.4.12
│ │ │ │ │ ├── libopencv_gpu.so.2.4.12
│ │ │ │ │ ├── libopencv_highgui.so.2.4.12
│ │ │ │ │ ├── libopencv_imgproc.so.2.4.12
│ │ │ │ │ ├── libopencv_legacy.so.2.4.12
│ │ │ │ │ ├── libopencv_ml.so.2.4.12
│ │ │ │ │ ├── libopencv_nonfree.so.2.4.12
│ │ │ │ │ ├── libopencv_objdetect.so.2.4.12
│ │ │ │ │ ├── libopencv_ocl.so.2.4.12
│ │ │ │ │ ├── libopencv_photo.so.2.4.12
│ │ │ │ │ ├── libopencv_stitching.so.2.4.12
│ │ │ │ │ ├── libopencv_superres.so.2.4.12
│ │ │ │ │ ├── libopencv_ts.a
│ │ │ │ │ ├── libopencv_video.so.2.4.12
│ │ │ │ │ ├── libopencv_videostab.so.2.4.12
│ │ │ │ │ ├── libturbojpeg.a
│ │ │ │ │ ├── libturbojpeg.so.0.2.0
│ │ │ │ │ └── pkgconfig/
│ │ │ │ │ └── opencv.pc
│ │ │ │ └── version.txt
│ │ │ ├── opencv4/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── include/
│ │ │ │ │ └── opencv2/
│ │ │ │ │ ├── calib3d/
│ │ │ │ │ │ ├── calib3d.hpp
│ │ │ │ │ │ └── calib3d_c.h
│ │ │ │ │ ├── calib3d.hpp
│ │ │ │ │ ├── core/
│ │ │ │ │ │ ├── affine.hpp
│ │ │ │ │ │ ├── async.hpp
│ │ │ │ │ │ ├── base.hpp
│ │ │ │ │ │ ├── bindings_utils.hpp
│ │ │ │ │ │ ├── bufferpool.hpp
│ │ │ │ │ │ ├── check.hpp
│ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ ├── core_c.h
│ │ │ │ │ │ ├── cuda/
│ │ │ │ │ │ │ ├── block.hpp
│ │ │ │ │ │ │ ├── border_interpolate.hpp
│ │ │ │ │ │ │ ├── color.hpp
│ │ │ │ │ │ │ ├── common.hpp
│ │ │ │ │ │ │ ├── datamov_utils.hpp
│ │ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ │ ├── color_detail.hpp
│ │ │ │ │ │ │ │ ├── reduce.hpp
│ │ │ │ │ │ │ │ ├── reduce_key_val.hpp
│ │ │ │ │ │ │ │ ├── transform_detail.hpp
│ │ │ │ │ │ │ │ ├── type_traits_detail.hpp
│ │ │ │ │ │ │ │ └── vec_distance_detail.hpp
│ │ │ │ │ │ │ ├── dynamic_smem.hpp
│ │ │ │ │ │ │ ├── emulation.hpp
│ │ │ │ │ │ │ ├── filters.hpp
│ │ │ │ │ │ │ ├── funcattrib.hpp
│ │ │ │ │ │ │ ├── functional.hpp
│ │ │ │ │ │ │ ├── limits.hpp
│ │ │ │ │ │ │ ├── reduce.hpp
│ │ │ │ │ │ │ ├── saturate_cast.hpp
│ │ │ │ │ │ │ ├── scan.hpp
│ │ │ │ │ │ │ ├── simd_functions.hpp
│ │ │ │ │ │ │ ├── transform.hpp
│ │ │ │ │ │ │ ├── type_traits.hpp
│ │ │ │ │ │ │ ├── utility.hpp
│ │ │ │ │ │ │ ├── vec_distance.hpp
│ │ │ │ │ │ │ ├── vec_math.hpp
│ │ │ │ │ │ │ ├── vec_traits.hpp
│ │ │ │ │ │ │ ├── warp.hpp
│ │ │ │ │ │ │ ├── warp_reduce.hpp
│ │ │ │ │ │ │ └── warp_shuffle.hpp
│ │ │ │ │ │ ├── cuda.hpp
│ │ │ │ │ │ ├── cuda.inl.hpp
│ │ │ │ │ │ ├── cuda_stream_accessor.hpp
│ │ │ │ │ │ ├── cuda_types.hpp
│ │ │ │ │ │ ├── cv_cpu_dispatch.h
│ │ │ │ │ │ ├── cv_cpu_helper.h
│ │ │ │ │ │ ├── cvdef.h
│ │ │ │ │ │ ├── cvstd.hpp
│ │ │ │ │ │ ├── cvstd.inl.hpp
│ │ │ │ │ │ ├── cvstd_wrapper.hpp
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ ├── async_promise.hpp
│ │ │ │ │ │ │ └── exception_ptr.hpp
│ │ │ │ │ │ ├── directx.hpp
│ │ │ │ │ │ ├── dualquaternion.hpp
│ │ │ │ │ │ ├── dualquaternion.inl.hpp
│ │ │ │ │ │ ├── eigen.hpp
│ │ │ │ │ │ ├── fast_math.hpp
│ │ │ │ │ │ ├── hal/
│ │ │ │ │ │ │ ├── hal.hpp
│ │ │ │ │ │ │ ├── interface.h
│ │ │ │ │ │ │ ├── intrin.hpp
│ │ │ │ │ │ │ ├── intrin_avx.hpp
│ │ │ │ │ │ │ ├── intrin_avx512.hpp
│ │ │ │ │ │ │ ├── intrin_cpp.hpp
│ │ │ │ │ │ │ ├── intrin_forward.hpp
│ │ │ │ │ │ │ ├── intrin_msa.hpp
│ │ │ │ │ │ │ ├── intrin_neon.hpp
│ │ │ │ │ │ │ ├── intrin_rvv.hpp
│ │ │ │ │ │ │ ├── intrin_rvv071.hpp
│ │ │ │ │ │ │ ├── intrin_sse.hpp
│ │ │ │ │ │ │ ├── intrin_sse_em.hpp
│ │ │ │ │ │ │ ├── intrin_vsx.hpp
│ │ │ │ │ │ │ ├── intrin_wasm.hpp
│ │ │ │ │ │ │ ├── msa_macros.h
│ │ │ │ │ │ │ └── simd_utils.impl.hpp
│ │ │ │ │ │ ├── mat.hpp
│ │ │ │ │ │ ├── mat.inl.hpp
│ │ │ │ │ │ ├── matx.hpp
│ │ │ │ │ │ ├── neon_utils.hpp
│ │ │ │ │ │ ├── ocl.hpp
│ │ │ │ │ │ ├── ocl_genbase.hpp
│ │ │ │ │ │ ├── opencl/
│ │ │ │ │ │ │ ├── ocl_defs.hpp
│ │ │ │ │ │ │ ├── opencl_info.hpp
│ │ │ │ │ │ │ ├── opencl_svm.hpp
│ │ │ │ │ │ │ └── runtime/
│ │ │ │ │ │ │ ├── autogenerated/
│ │ │ │ │ │ │ │ ├── opencl_clblas.hpp
│ │ │ │ │ │ │ │ ├── opencl_clfft.hpp
│ │ │ │ │ │ │ │ ├── opencl_core.hpp
│ │ │ │ │ │ │ │ ├── opencl_core_wrappers.hpp
│ │ │ │ │ │ │ │ ├── opencl_gl.hpp
│ │ │ │ │ │ │ │ └── opencl_gl_wrappers.hpp
│ │ │ │ │ │ │ ├── opencl_clblas.hpp
│ │ │ │ │ │ │ ├── opencl_clfft.hpp
│ │ │ │ │ │ │ ├── opencl_core.hpp
│ │ │ │ │ │ │ ├── opencl_core_wrappers.hpp
│ │ │ │ │ │ │ ├── opencl_gl.hpp
│ │ │ │ │ │ │ ├── opencl_gl_wrappers.hpp
│ │ │ │ │ │ │ ├── opencl_svm_20.hpp
│ │ │ │ │ │ │ ├── opencl_svm_definitions.hpp
│ │ │ │ │ │ │ └── opencl_svm_hsa_extension.hpp
│ │ │ │ │ │ ├── opengl.hpp
│ │ │ │ │ │ ├── operations.hpp
│ │ │ │ │ │ ├── optim.hpp
│ │ │ │ │ │ ├── ovx.hpp
│ │ │ │ │ │ ├── parallel/
│ │ │ │ │ │ │ ├── backend/
│ │ │ │ │ │ │ │ ├── parallel_for.openmp.hpp
│ │ │ │ │ │ │ │ └── parallel_for.tbb.hpp
│ │ │ │ │ │ │ └── parallel_backend.hpp
│ │ │ │ │ │ ├── persistence.hpp
│ │ │ │ │ │ ├── quaternion.hpp
│ │ │ │ │ │ ├── quaternion.inl.hpp
│ │ │ │ │ │ ├── saturate.hpp
│ │ │ │ │ │ ├── simd_intrinsics.hpp
│ │ │ │ │ │ ├── softfloat.hpp
│ │ │ │ │ │ ├── sse_utils.hpp
│ │ │ │ │ │ ├── traits.hpp
│ │ │ │ │ │ ├── types.hpp
│ │ │ │ │ │ ├── types_c.h
│ │ │ │ │ │ ├── utility.hpp
│ │ │ │ │ │ ├── utils/
│ │ │ │ │ │ │ ├── allocator_stats.hpp
│ │ │ │ │ │ │ ├── allocator_stats.impl.hpp
│ │ │ │ │ │ │ ├── filesystem.hpp
│ │ │ │ │ │ │ ├── instrumentation.hpp
│ │ │ │ │ │ │ ├── logger.defines.hpp
│ │ │ │ │ │ │ ├── logger.hpp
│ │ │ │ │ │ │ ├── logtag.hpp
│ │ │ │ │ │ │ ├── tls.hpp
│ │ │ │ │ │ │ └── trace.hpp
│ │ │ │ │ │ ├── va_intel.hpp
│ │ │ │ │ │ ├── version.hpp
│ │ │ │ │ │ └── vsx_utils.hpp
│ │ │ │ │ ├── core.hpp
│ │ │ │ │ ├── cvconfig.h
│ │ │ │ │ ├── dnn/
│ │ │ │ │ │ ├── all_layers.hpp
│ │ │ │ │ │ ├── dict.hpp
│ │ │ │ │ │ ├── dnn.hpp
│ │ │ │ │ │ ├── dnn.inl.hpp
│ │ │ │ │ │ ├── layer.details.hpp
│ │ │ │ │ │ ├── layer.hpp
│ │ │ │ │ │ ├── shape_utils.hpp
│ │ │ │ │ │ ├── utils/
│ │ │ │ │ │ │ └── inference_engine.hpp
│ │ │ │ │ │ └── version.hpp
│ │ │ │ │ ├── dnn.hpp
│ │ │ │ │ ├── features2d/
│ │ │ │ │ │ ├── features2d.hpp
│ │ │ │ │ │ └── hal/
│ │ │ │ │ │ └── interface.h
│ │ │ │ │ ├── features2d.hpp
│ │ │ │ │ ├── flann/
│ │ │ │ │ │ ├── all_indices.h
│ │ │ │ │ │ ├── allocator.h
│ │ │ │ │ │ ├── any.h
│ │ │ │ │ │ ├── autotuned_index.h
│ │ │ │ │ │ ├── composite_index.h
│ │ │ │ │ │ ├── config.h
│ │ │ │ │ │ ├── defines.h
│ │ │ │ │ │ ├── dist.h
│ │ │ │ │ │ ├── dummy.h
│ │ │ │ │ │ ├── dynamic_bitset.h
│ │ │ │ │ │ ├── flann.hpp
│ │ │ │ │ │ ├── flann_base.hpp
│ │ │ │ │ │ ├── general.h
│ │ │ │ │ │ ├── ground_truth.h
│ │ │ │ │ │ ├── hdf5.h
│ │ │ │ │ │ ├── heap.h
│ │ │ │ │ │ ├── hierarchical_clustering_index.h
│ │ │ │ │ │ ├── index_testing.h
│ │ │ │ │ │ ├── kdtree_index.h
│ │ │ │ │ │ ├── kdtree_single_index.h
│ │ │ │ │ │ ├── kmeans_index.h
│ │ │ │ │ │ ├── linear_index.h
│ │ │ │ │ │ ├── logger.h
│ │ │ │ │ │ ├── lsh_index.h
│ │ │ │ │ │ ├── lsh_table.h
│ │ │ │ │ │ ├── matrix.h
│ │ │ │ │ │ ├── miniflann.hpp
│ │ │ │ │ │ ├── nn_index.h
│ │ │ │ │ │ ├── object_factory.h
│ │ │ │ │ │ ├── params.h
│ │ │ │ │ │ ├── random.h
│ │ │ │ │ │ ├── result_set.h
│ │ │ │ │ │ ├── sampling.h
│ │ │ │ │ │ ├── saving.h
│ │ │ │ │ │ ├── simplex_downhill.h
│ │ │ │ │ │ └── timer.h
│ │ │ │ │ ├── flann.hpp
│ │ │ │ │ ├── gapi/
│ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ ├── cpu/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── gcpukernel.hpp
│ │ │ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ │ │ ├── stereo.hpp
│ │ │ │ │ │ │ └── video.hpp
│ │ │ │ │ │ ├── fluid/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── gfluidbuffer.hpp
│ │ │ │ │ │ │ ├── gfluidkernel.hpp
│ │ │ │ │ │ │ └── imgproc.hpp
│ │ │ │ │ │ ├── garg.hpp
│ │ │ │ │ │ ├── garray.hpp
│ │ │ │ │ │ ├── gasync_context.hpp
│ │ │ │ │ │ ├── gcall.hpp
│ │ │ │ │ │ ├── gcommon.hpp
│ │ │ │ │ │ ├── gcompiled.hpp
│ │ │ │ │ │ ├── gcompiled_async.hpp
│ │ │ │ │ │ ├── gcompoundkernel.hpp
│ │ │ │ │ │ ├── gcomputation.hpp
│ │ │ │ │ │ ├── gcomputation_async.hpp
│ │ │ │ │ │ ├── gframe.hpp
│ │ │ │ │ │ ├── gkernel.hpp
│ │ │ │ │ │ ├── gmat.hpp
│ │ │ │ │ │ ├── gmetaarg.hpp
│ │ │ │ │ │ ├── gopaque.hpp
│ │ │ │ │ │ ├── gproto.hpp
│ │ │ │ │ │ ├── gpu/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── ggpukernel.hpp
│ │ │ │ │ │ │ └── imgproc.hpp
│ │ │ │ │ │ ├── gscalar.hpp
│ │ │ │ │ │ ├── gstreaming.hpp
│ │ │ │ │ │ ├── gtransform.hpp
│ │ │ │ │ │ ├── gtype_traits.hpp
│ │ │ │ │ │ ├── gtyped.hpp
│ │ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ │ ├── infer/
│ │ │ │ │ │ │ ├── bindings_ie.hpp
│ │ │ │ │ │ │ ├── ie.hpp
│ │ │ │ │ │ │ ├── onnx.hpp
│ │ │ │ │ │ │ └── parsers.hpp
│ │ │ │ │ │ ├── infer.hpp
│ │ │ │ │ │ ├── media.hpp
│ │ │ │ │ │ ├── ocl/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── goclkernel.hpp
│ │ │ │ │ │ │ └── imgproc.hpp
│ │ │ │ │ │ ├── opencv_includes.hpp
│ │ │ │ │ │ ├── operators.hpp
│ │ │ │ │ │ ├── own/
│ │ │ │ │ │ │ ├── assert.hpp
│ │ │ │ │ │ │ ├── convert.hpp
│ │ │ │ │ │ │ ├── cvdefs.hpp
│ │ │ │ │ │ │ ├── exports.hpp
│ │ │ │ │ │ │ ├── mat.hpp
│ │ │ │ │ │ │ ├── saturate.hpp
│ │ │ │ │ │ │ ├── scalar.hpp
│ │ │ │ │ │ │ └── types.hpp
│ │ │ │ │ │ ├── plaidml/
│ │ │ │ │ │ │ ├── core.hpp
│ │ │ │ │ │ │ ├── gplaidmlkernel.hpp
│ │ │ │ │ │ │ └── plaidml.hpp
│ │ │ │ │ │ ├── python/
│ │ │ │ │ │ │ └── python.hpp
│ │ │ │ │ │ ├── render/
│ │ │ │ │ │ │ ├── render.hpp
│ │ │ │ │ │ │ └── render_types.hpp
│ │ │ │ │ │ ├── render.hpp
│ │ │ │ │ │ ├── rmat.hpp
│ │ │ │ │ │ ├── s11n/
│ │ │ │ │ │ │ └── base.hpp
│ │ │ │ │ │ ├── s11n.hpp
│ │ │ │ │ │ ├── stereo.hpp
│ │ │ │ │ │ ├── streaming/
│ │ │ │ │ │ │ ├── cap.hpp
│ │ │ │ │ │ │ ├── desync.hpp
│ │ │ │ │ │ │ ├── format.hpp
│ │ │ │ │ │ │ ├── meta.hpp
│ │ │ │ │ │ │ ├── source.hpp
│ │ │ │ │ │ │ └── sync.hpp
│ │ │ │ │ │ ├── util/
│ │ │ │ │ │ │ ├── any.hpp
│ │ │ │ │ │ │ ├── compiler_hints.hpp
│ │ │ │ │ │ │ ├── copy_through_move.hpp
│ │ │ │ │ │ │ ├── optional.hpp
│ │ │ │ │ │ │ ├── throw.hpp
│ │ │ │ │ │ │ ├── type_traits.hpp
│ │ │ │ │ │ │ ├── util.hpp
│ │ │ │ │ │ │ └── variant.hpp
│ │ │ │ │ │ └── video.hpp
│ │ │ │ │ ├── gapi.hpp
│ │ │ │ │ ├── highgui/
│ │ │ │ │ │ ├── highgui.hpp
│ │ │ │ │ │ └── highgui_c.h
│ │ │ │ │ ├── highgui.hpp
│ │ │ │ │ ├── imgcodecs/
│ │ │ │ │ │ ├── imgcodecs.hpp
│ │ │ │ │ │ ├── imgcodecs_c.h
│ │ │ │ │ │ ├── ios.h
│ │ │ │ │ │ ├── legacy/
│ │ │ │ │ │ │ └── constants_c.h
│ │ │ │ │ │ └── macosx.h
│ │ │ │ │ ├── imgcodecs.hpp
│ │ │ │ │ ├── imgproc/
│ │ │ │ │ │ ├── bindings.hpp
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ └── gcgraph.hpp
│ │ │ │ │ │ ├── hal/
│ │ │ │ │ │ │ ├── hal.hpp
│ │ │ │ │ │ │ └── interface.h
│ │ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ │ ├── imgproc_c.h
│ │ │ │ │ │ ├── segmentation.hpp
│ │ │ │ │ │ └── types_c.h
│ │ │ │ │ ├── imgproc.hpp
│ │ │ │ │ ├── ml/
│ │ │ │ │ │ ├── ml.hpp
│ │ │ │ │ │ └── ml.inl.hpp
│ │ │ │ │ ├── ml.hpp
│ │ │ │ │ ├── objdetect/
│ │ │ │ │ │ ├── detection_based_tracker.hpp
│ │ │ │ │ │ └── objdetect.hpp
│ │ │ │ │ ├── objdetect.hpp
│ │ │ │ │ ├── opencv.hpp
│ │ │ │ │ ├── opencv_modules.hpp
│ │ │ │ │ ├── photo/
│ │ │ │ │ │ ├── cuda.hpp
│ │ │ │ │ │ ├── legacy/
│ │ │ │ │ │ │ └── constants_c.h
│ │ │ │ │ │ └── photo.hpp
│ │ │ │ │ ├── photo.hpp
│ │ │ │ │ ├── stitching/
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ ├── autocalib.hpp
│ │ │ │ │ │ │ ├── blenders.hpp
│ │ │ │ │ │ │ ├── camera.hpp
│ │ │ │ │ │ │ ├── exposure_compensate.hpp
│ │ │ │ │ │ │ ├── matchers.hpp
│ │ │ │ │ │ │ ├── motion_estimators.hpp
│ │ │ │ │ │ │ ├── seam_finders.hpp
│ │ │ │ │ │ │ ├── timelapsers.hpp
│ │ │ │ │ │ │ ├── util.hpp
│ │ │ │ │ │ │ ├── util_inl.hpp
│ │ │ │ │ │ │ ├── warpers.hpp
│ │ │ │ │ │ │ └── warpers_inl.hpp
│ │ │ │ │ │ └── warpers.hpp
│ │ │ │ │ ├── stitching.hpp
│ │ │ │ │ ├── video/
│ │ │ │ │ │ ├── background_segm.hpp
│ │ │ │ │ │ ├── detail/
│ │ │ │ │ │ │ └── tracking.detail.hpp
│ │ │ │ │ │ ├── legacy/
│ │ │ │ │ │ │ └── constants_c.h
│ │ │ │ │ │ ├── tracking.hpp
│ │ │ │ │ │ └── video.hpp
│ │ │ │ │ ├── video.hpp
│ │ │ │ │ ├── videoio/
│ │ │ │ │ │ ├── cap_ios.h
│ │ │ │ │ │ ├── legacy/
│ │ │ │ │ │ │ └── constants_c.h
│ │ │ │ │ │ ├── registry.hpp
│ │ │ │ │ │ ├── videoio.hpp
│ │ │ │ │ │ └── videoio_c.h
│ │ │ │ │ └── videoio.hpp
│ │ │ │ └── lib64/
│ │ │ │ ├── cmake/
│ │ │ │ │ └── opencv4/
│ │ │ │ │ ├── OpenCVConfig-version.cmake
│ │ │ │ │ ├── OpenCVConfig.cmake
│ │ │ │ │ ├── OpenCVModules-release.cmake
│ │ │ │ │ └── OpenCVModules.cmake
│ │ │ │ ├── libopencv_calib3d.so.4.5.3
│ │ │ │ ├── libopencv_core.so.4.5.3
│ │ │ │ ├── libopencv_dnn.so.4.5.3
│ │ │ │ ├── libopencv_features2d.so.4.5.3
│ │ │ │ ├── libopencv_flann.so.4.5.3
│ │ │ │ ├── libopencv_gapi.so.4.5.3
│ │ │ │ ├── libopencv_highgui.so.4.5.3
│ │ │ │ ├── libopencv_imgcodecs.so.4.5.3
│ │ │ │ ├── libopencv_imgproc.so.4.5.3
│ │ │ │ ├── libopencv_ml.so.4.5.3
│ │ │ │ ├── libopencv_objdetect.so.4.5.3
│ │ │ │ ├── libopencv_photo.so.4.5.3
│ │ │ │ ├── libopencv_stitching.so.4.5.3
│ │ │ │ ├── libopencv_video.so.4.5.3
│ │ │ │ ├── libopencv_videoio.so.4.5.3
│ │ │ │ └── pkgconfig/
│ │ │ │ └── opencv4.pc
│ │ │ ├── protobuf/
│ │ │ │ ├── bin/
│ │ │ │ │ └── protoc
│ │ │ │ ├── include/
│ │ │ │ │ └── google/
│ │ │ │ │ └── protobuf/
│ │ │ │ │ ├── any.h
│ │ │ │ │ ├── any.pb.h
│ │ │ │ │ ├── any.proto
│ │ │ │ │ ├── api.pb.h
│ │ │ │ │ ├── api.proto
│ │ │ │ │ ├── arena.h
│ │ │ │ │ ├── arena_impl.h
│ │ │ │ │ ├── arenastring.h
│ │ │ │ │ ├── compiler/
│ │ │ │ │ │ ├── code_generator.h
│ │ │ │ │ │ ├── command_line_interface.h
│ │ │ │ │ │ ├── cpp/
│ │ │ │ │ │ │ └── cpp_generator.h
│ │ │ │ │ │ ├── csharp/
│ │ │ │ │ │ │ ├── csharp_generator.h
│ │ │ │ │ │ │ └── csharp_names.h
│ │ │ │ │ │ ├── importer.h
│ │ │ │ │ │ ├── java/
│ │ │ │ │ │ │ ├── java_generator.h
│ │ │ │ │ │ │ └── java_names.h
│ │ │ │ │ │ ├── js/
│ │ │ │ │ │ │ ├── js_generator.h
│ │ │ │ │ │ │ └── well_known_types_embed.h
│ │ │ │ │ │ ├── objectivec/
│ │ │ │ │ │ │ ├── objectivec_generator.h
│ │ │ │ │ │ │ └── objectivec_helpers.h
│ │ │ │ │ │ ├── parser.h
│ │ │ │ │ │ ├── php/
│ │ │ │ │ │ │ └── php_generator.h
│ │ │ │ │ │ ├── plugin.h
│ │ │ │ │ │ ├── plugin.pb.h
│ │ │ │ │ │ ├── plugin.proto
│ │ │ │ │ │ ├── python/
│ │ │ │ │ │ │ └── python_generator.h
│ │ │ │ │ │ └── ruby/
│ │ │ │ │ │ └── ruby_generator.h
│ │ │ │ │ ├── descriptor.h
│ │ │ │ │ ├── descriptor.pb.h
│ │ │ │ │ ├── descriptor.proto
│ │ │ │ │ ├── descriptor_database.h
│ │ │ │ │ ├── duration.pb.h
│ │ │ │ │ ├── duration.proto
│ │ │ │ │ ├── dynamic_message.h
│ │ │ │ │ ├── empty.pb.h
│ │ │ │ │ ├── empty.proto
│ │ │ │ │ ├── extension_set.h
│ │ │ │ │ ├── field_mask.pb.h
│ │ │ │ │ ├── field_mask.proto
│ │ │ │ │ ├── generated_enum_reflection.h
│ │ │ │ │ ├── generated_enum_util.h
│ │ │ │ │ ├── generated_message_reflection.h
│ │ │ │ │ ├── generated_message_table_driven.h
│ │ │ │ │ ├── generated_message_util.h
│ │ │ │ │ ├── has_bits.h
│ │ │ │ │ ├── implicit_weak_message.h
│ │ │ │ │ ├── inlined_string_field.h
│ │ │ │ │ ├── io/
│ │ │ │ │ │ ├── coded_stream.h
│ │ │ │ │ │ ├── gzip_stream.h
│ │ │ │ │ │ ├── printer.h
│ │ │ │ │ │ ├── strtod.h
│ │ │ │ │ │ ├── tokenizer.h
│ │ │ │ │ │ ├── zero_copy_stream.h
│ │ │ │ │ │ ├── zero_copy_stream_impl.h
│ │ │ │ │ │ └── zero_copy_stream_impl_lite.h
│ │ │ │ │ ├── map.h
│ │ │ │ │ ├── map_entry.h
│ │ │ │ │ ├── map_entry_lite.h
│ │ │ │ │ ├── map_field.h
│ │ │ │ │ ├── map_field_inl.h
│ │ │ │ │ ├── map_field_lite.h
│ │ │ │ │ ├── map_type_handler.h
│ │ │ │ │ ├── message.h
│ │ │ │ │ ├── message_lite.h
│ │ │ │ │ ├── metadata.h
│ │ │ │ │ ├── metadata_lite.h
│ │ │ │ │ ├── reflection.h
│ │ │ │ │ ├── reflection_ops.h
│ │ │ │ │ ├── repeated_field.h
│ │ │ │ │ ├── service.h
│ │ │ │ │ ├── source_context.pb.h
│ │ │ │ │ ├── source_context.proto
│ │ │ │ │ ├── struct.pb.h
│ │ │ │ │ ├── struct.proto
│ │ │ │ │ ├── stubs/
│ │ │ │ │ │ ├── bytestream.h
│ │ │ │ │ │ ├── callback.h
│ │ │ │ │ │ ├── casts.h
│ │ │ │ │ │ ├── common.h
│ │ │ │ │ │ ├── fastmem.h
│ │ │ │ │ │ ├── hash.h
│ │ │ │ │ │ ├── logging.h
│ │ │ │ │ │ ├── macros.h
│ │ │ │ │ │ ├── mutex.h
│ │ │ │ │ │ ├── once.h
│ │ │ │ │ │ ├── platform_macros.h
│ │ │ │ │ │ ├── port.h
│ │ │ │ │ │ ├── singleton.h
│ │ │ │ │ │ ├── status.h
│ │ │ │ │ │ ├── stl_util.h
│ │ │ │ │ │ ├── stringpiece.h
│ │ │ │ │ │ └── template_util.h
│ │ │ │ │ ├── text_format.h
│ │ │ │ │ ├── timestamp.pb.h
│ │ │ │ │ ├── timestamp.proto
│ │ │ │ │ ├── type.pb.h
│ │ │ │ │ ├── type.proto
│ │ │ │ │ ├── unknown_field_set.h
│ │ │ │ │ ├── util/
│ │ │ │ │ │ ├── delimited_message_util.h
│ │ │ │ │ │ ├── field_comparator.h
│ │ │ │ │ │ ├── field_mask_util.h
│ │ │ │ │ │ ├── json_util.h
│ │ │ │ │ │ ├── message_differencer.h
│ │ │ │ │ │ ├── time_util.h
│ │ │ │ │ │ ├── type_resolver.h
│ │ │ │ │ │ └── type_resolver_util.h
│ │ │ │ │ ├── wire_format.h
│ │ │ │ │ ├── wire_format_lite.h
│ │ │ │ │ ├── wire_format_lite_inl.h
│ │ │ │ │ ├── wrappers.pb.h
│ │ │ │ │ └── wrappers.proto
│ │ │ │ └── lib/
│ │ │ │ ├── libprotobuf-lite.a
│ │ │ │ ├── libprotobuf.a
│ │ │ │ ├── libprotoc.a
│ │ │ │ └── pkgconfig/
│ │ │ │ ├── protobuf-lite.pc
│ │ │ │ └── protobuf.pc
│ │ │ └── pybind11/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── LICENSE
│ │ │ ├── MANIFEST.in
│ │ │ ├── README.rst
│ │ │ ├── docs/
│ │ │ │ ├── Doxyfile
│ │ │ │ ├── Makefile
│ │ │ │ ├── _static/
│ │ │ │ │ └── css/
│ │ │ │ │ └── custom.css
│ │ │ │ ├── advanced/
│ │ │ │ │ ├── cast/
│ │ │ │ │ │ ├── chrono.rst
│ │ │ │ │ │ ├── custom.rst
│ │ │ │ │ │ ├── eigen.rst
│ │ │ │ │ │ ├── functional.rst
│ │ │ │ │ │ ├── index.rst
│ │ │ │ │ │ ├── overview.rst
│ │ │ │ │ │ ├── stl.rst
│ │ │ │ │ │ └── strings.rst
│ │ │ │ │ ├── classes.rst
│ │ │ │ │ ├── embedding.rst
│ │ │ │ │ ├── exceptions.rst
│ │ │ │ │ ├── functions.rst
│ │ │ │ │ ├── misc.rst
│ │ │ │ │ ├── pycpp/
│ │ │ │ │ │ ├── index.rst
│ │ │ │ │ │ ├── numpy.rst
│ │ │ │ │ │ ├── object.rst
│ │ │ │ │ │ └── utilities.rst
│ │ │ │ │ └── smart_ptrs.rst
│ │ │ │ ├── basics.rst
│ │ │ │ ├── benchmark.py
│ │ │ │ ├── benchmark.rst
│ │ │ │ ├── changelog.rst
│ │ │ │ ├── classes.rst
│ │ │ │ ├── cmake/
│ │ │ │ │ └── index.rst
│ │ │ │ ├── compiling.rst
│ │ │ │ ├── conf.py
│ │ │ │ ├── faq.rst
│ │ │ │ ├── index.rst
│ │ │ │ ├── installing.rst
│ │ │ │ ├── limitations.rst
│ │ │ │ ├── reference.rst
│ │ │ │ ├── release.rst
│ │ │ │ ├── requirements.txt
│ │ │ │ └── upgrade.rst
│ │ │ ├── include/
│ │ │ │ └── pybind11/
│ │ │ │ ├── attr.h
│ │ │ │ ├── buffer_info.h
│ │ │ │ ├── cast.h
│ │ │ │ ├── chrono.h
│ │ │ │ ├── common.h
│ │ │ │ ├── complex.h
│ │ │ │ ├── detail/
│ │ │ │ │ ├── class.h
│ │ │ │ │ ├── common.h
│ │ │ │ │ ├── descr.h
│ │ │ │ │ ├── init.h
│ │ │ │ │ ├── internals.h
│ │ │ │ │ ├── type_caster_base.h
│ │ │ │ │ └── typeid.h
│ │ │ │ ├── eigen/
│ │ │ │ │ ├── matrix.h
│ │ │ │ │ └── tensor.h
│ │ │ │ ├── eigen.h
│ │ │ │ ├── embed.h
│ │ │ │ ├── eval.h
│ │ │ │ ├── functional.h
│ │ │ │ ├── gil.h
│ │ │ │ ├── iostream.h
│ │ │ │ ├── numpy.h
│ │ │ │ ├── operators.h
│ │ │ │ ├── options.h
│ │ │ │ ├── pybind11.h
│ │ │ │ ├── pytypes.h
│ │ │ │ ├── stl/
│ │ │ │ │ └── filesystem.h
│ │ │ │ ├── stl.h
│ │ │ │ └── stl_bind.h
│ │ │ ├── noxfile.py
│ │ │ ├── pybind11/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ ├── _version.py
│ │ │ │ ├── commands.py
│ │ │ │ ├── py.typed
│ │ │ │ └── setup_helpers.py
│ │ │ ├── pyproject.toml
│ │ │ ├── setup.cfg
│ │ │ ├── setup.py
│ │ │ ├── tests/
│ │ │ │ ├── CMakeLists.txt
│ │ │ │ ├── conftest.py
│ │ │ │ ├── constructor_stats.h
│ │ │ │ ├── cross_module_gil_utils.cpp
│ │ │ │ ├── cross_module_interleaved_error_already_set.cpp
│ │ │ │ ├── eigen_tensor_avoid_stl_array.cpp
│ │ │ │ ├── env.py
│ │ │ │ ├── extra_python_package/
│ │ │ │ │ ├── pytest.ini
│ │ │ │ │ └── test_files.py
│ │ │ │ ├── extra_setuptools/
│ │ │ │ │ ├── pytest.ini
│ │ │ │ │ └── test_setuphelper.py
│ │ │ │ ├── local_bindings.h
│ │ │ │ ├── object.h
│ │ │ │ ├── pybind11_cross_module_tests.cpp
│ │ │ │ ├── pybind11_tests.cpp
│ │ │ │ ├── pybind11_tests.h
│ │ │ │ ├── pytest.ini
│ │ │ │ ├── requirements.txt
│ │ │ │ ├── test_async.cpp
│ │ │ │ ├── test_async.py
│ │ │ │ ├── test_buffers.cpp
│ │ │ │ ├── test_buffers.py
│ │ │ │ ├── test_builtin_casters.cpp
│ │ │ │ ├── test_builtin_casters.py
│ │ │ │ ├── test_call_policies.cpp
│ │ │ │ ├── test_call_policies.py
│ │ │ │ ├── test_callbacks.cpp
│ │ │ │ ├── test_callbacks.py
│ │ │ │ ├── test_chrono.cpp
│ │ │ │ ├── test_chrono.py
│ │ │ │ ├── test_class.cpp
│ │ │ │ ├── test_class.py
│ │ │ │ ├── test_cmake_build/
│ │ │ │ │ ├── CMakeLists.txt
│ │ │ │ │ ├── embed.cpp
│ │ │ │ │ ├── installed_embed/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── installed_function/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── installed_target/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── main.cpp
│ │ │ │ │ ├── subdirectory_embed/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── subdirectory_function/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ ├── subdirectory_target/
│ │ │ │ │ │ └── CMakeLists.txt
│ │ │ │ │ └── test.py
│ │ │ │ ├── test_const_name.cpp
│ │ │ │ ├── test_const_name.py
│ │ │ │ ├── test_constants_and_functions.cpp
│ │ │ │ ├── test_constants_and_functions.py
│ │ │ │ ├── test_copy_move.cpp
│ │ │ │ ├── test_copy_move.py
│ │ │ │ ├── test_custom_type_casters.cpp
│ │ │ │ ├── test_custom_type_casters.py
│ │ │ │ ├── test_custom_type_setup.cpp
│ │ │ │ ├── test_custom_type_setup.py
│ │ │ │ ├── test_docstring_options.cpp
│ │ │ │ ├── test_docstring_options.py
│ │ │ │ ├── test_eigen_matrix.cpp
│ │ │ │ ├── test_eigen_matrix.py
│ │ │ │ ├── test_eigen_tensor.cpp
│ │ │ │ ├── test_eigen_tensor.inl
│ │ │ │ ├── test_eigen_tensor.py
│ │ │ │ ├── test_embed/
│ │ │ │ │ ├── CMakeLists.txt
│ │ │ │ │ ├── catch.cpp
│ │ │ │ │ ├── external_module.cpp
│ │ │ │ │ ├── test_interpreter.cpp
│ │ │ │ │ ├── test_interpreter.py
│ │ │ │ │ └── test_trampoline.py
│ │ │ │ ├── test_enum.cpp
│ │ │ │ ├── test_enum.py
│ │ │ │ ├── test_eval.cpp
│ │ │ │ ├── test_eval.py
│ │ │ │ ├── test_eval_call.py
│ │ │ │ ├── test_exceptions.cpp
│ │ │ │ ├── test_exceptions.h
│ │ │ │ ├── test_exceptions.py
│ │ │ │ ├── test_factory_constructors.cpp
│ │ │ │ ├── test_factory_constructors.py
│ │ │ │ ├── test_gil_scoped.cpp
│ │ │ │ ├── test_gil_scoped.py
│ │ │ │ ├── test_iostream.cpp
│ │ │ │ ├── test_iostream.py
│ │ │ │ ├── test_kwargs_and_defaults.cpp
│ │ │ │ ├── test_kwargs_and_defaults.py
│ │ │ │ ├── test_local_bindings.cpp
│ │ │ │ ├── test_local_bindings.py
│ │ │ │ ├── test_methods_and_attributes.cpp
│ │ │ │ ├── test_methods_and_attributes.py
│ │ │ │ ├── test_modules.cpp
│ │ │ │ ├── test_modules.py
│ │ │ │ ├── test_multiple_inheritance.cpp
│ │ │ │ ├── test_multiple_inheritance.py
│ │ │ │ ├── test_numpy_array.cpp
│ │ │ │ ├── test_numpy_array.py
│ │ │ │ ├── test_numpy_dtypes.cpp
│ │ │ │ ├── test_numpy_dtypes.py
│ │ │ │ ├── test_numpy_vectorize.cpp
│ │ │ │ ├── test_numpy_vectorize.py
│ │ │ │ ├── test_opaque_types.cpp
│ │ │ │ ├── test_opaque_types.py
│ │ │ │ ├── test_operator_overloading.cpp
│ │ │ │ ├── test_operator_overloading.py
│ │ │ │ ├── test_pickling.cpp
│ │ │ │ ├── test_pickling.py
│ │ │ │ ├── test_pytypes.cpp
│ │ │ │ ├── test_pytypes.py
│ │ │ │ ├── test_sequences_and_iterators.cpp
│ │ │ │ ├── test_sequences_and_iterators.py
│ │ │ │ ├── test_smart_ptr.cpp
│ │ │ │ ├── test_smart_ptr.py
│ │ │ │ ├── test_stl.cpp
│ │ │ │ ├── test_stl.py
│ │ │ │ ├── test_stl_binders.cpp
│ │ │ │ ├── test_stl_binders.py
│ │ │ │ ├── test_tagbased_polymorphic.cpp
│ │ │ │ ├── test_tagbased_polymorphic.py
│ │ │ │ ├── test_thread.cpp
│ │ │ │ ├── test_thread.py
│ │ │ │ ├── test_union.cpp
│ │ │ │ ├── test_union.py
│ │ │ │ ├── test_virtual_functions.cpp
│ │ │ │ ├── test_virtual_functions.py
│ │ │ │ ├── valgrind-numpy-scipy.supp
│ │ │ │ └── valgrind-python.supp
│ │ │ └── tools/
│ │ │ ├── FindCatch.cmake
│ │ │ ├── FindEigen3.cmake
│ │ │ ├── FindPythonLibsNew.cmake
│ │ │ ├── JoinPaths.cmake
│ │ │ ├── check-style.sh
│ │ │ ├── cmake_uninstall.cmake.in
│ │ │ ├── codespell_ignore_lines_from_errors.py
│ │ │ ├── libsize.py
│ │ │ ├── make_changelog.py
│ │ │ ├── pybind11.pc.in
│ │ │ ├── pybind11Common.cmake
│ │ │ ├── pybind11Config.cmake.in
│ │ │ ├── pybind11NewTools.cmake
│ │ │ ├── pybind11Tools.cmake
│ │ │ ├── pyproject.toml
│ │ │ ├── setup_global.py.in
│ │ │ └── setup_main.py.in
│ │ ├── cvtable/
│ │ │ ├── cvtable.go
│ │ │ ├── cvtable_test.go
│ │ │ └── testdata/
│ │ │ └── cvtable.conf
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── point.go
│ │ ├── rect.go
│ │ ├── rect_test.go
│ │ └── vector/
│ │ ├── vector.go
│ │ └── vector_test.go
│ ├── grpc-gateway/
│ │ ├── date/
│ │ │ ├── date.pb.go
│ │ │ ├── date.pb.gw.go
│ │ │ ├── date.proto
│ │ │ ├── date.yaml
│ │ │ └── date_grpc.pb.go
│ │ ├── gateway_handler.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── grpc_gateway.go
│ │ ├── grpc_gateway_grpc.option.go
│ │ ├── grpc_gateway_http.option.go
│ │ ├── grpc_gateway_option.go
│ │ └── grpc_gateway_test.go
│ ├── logs/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── hook.go
│ │ ├── log.go
│ │ ├── log.option.go
│ │ ├── log.pb.go
│ │ ├── log.proto
│ │ ├── log.yaml
│ │ ├── log_option.go
│ │ ├── log_test.go
│ │ ├── logrus/
│ │ │ ├── formatter.go
│ │ │ ├── glog_formatter.go
│ │ │ ├── glog_formatter_test.go
│ │ │ ├── terminal_check_bsd.go
│ │ │ ├── terminal_check_js.go
│ │ │ ├── terminal_check_notappengine.go
│ │ │ ├── terminal_check_solaris.go
│ │ │ ├── terminal_check_unix.go
│ │ │ └── terminal_check_windows.go
│ │ └── slog_test.go
│ ├── middleware/
│ │ ├── api/
│ │ │ ├── tcloud/
│ │ │ │ └── v3.0/
│ │ │ │ ├── http.interceptor.error.go
│ │ │ │ ├── interceptor.error.go
│ │ │ │ ├── jsonpb.marshaler.go
│ │ │ │ ├── tcloud.pb.go
│ │ │ │ └── tcloud.proto
│ │ │ └── trivial/
│ │ │ ├── v1/
│ │ │ │ ├── api.pb.go
│ │ │ │ ├── api.proto
│ │ │ │ ├── http.interceptor.error.go
│ │ │ │ └── interceptor.error.go
│ │ │ └── v2/
│ │ │ ├── api.pb.go
│ │ │ ├── api.proto
│ │ │ ├── http.interceptor.error.go
│ │ │ └── interceptor.error.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── grpc-middleware/
│ │ │ ├── debug/
│ │ │ │ ├── in_output_printer_client.interceptor.go
│ │ │ │ ├── in_output_printer_server.interceptor.go
│ │ │ │ └── request_id_server.interceptor.go
│ │ │ ├── opentelemetry/
│ │ │ │ ├── metric_server.interceptor.go
│ │ │ │ ├── modular_client.interceptor.go
│ │ │ │ ├── modular_server.interceptor.go
│ │ │ │ ├── trace_client.interceptor.go
│ │ │ │ └── trace_server.interceptor.go
│ │ │ ├── ratelimit/
│ │ │ │ ├── ratelimit_qps_server.interceptor.go
│ │ │ │ └── ratelimit_server.interceptor.go
│ │ │ └── timer/
│ │ │ ├── timer_client.interceptor.go
│ │ │ └── timer_server.interceptor.go
│ │ ├── http-middleware/
│ │ │ ├── cors/
│ │ │ │ ├── cors.go
│ │ │ │ └── cors_test.go
│ │ │ ├── debug/
│ │ │ │ ├── in.output_printer.go
│ │ │ │ ├── in.output_printer_truncate.go
│ │ │ │ ├── recoverer.go
│ │ │ │ └── request_id.go
│ │ │ ├── http/
│ │ │ │ ├── clean_path.go
│ │ │ │ ├── strip_prefix.go
│ │ │ │ ├── strip_prefix_test.go
│ │ │ │ └── timeout.go
│ │ │ ├── opentelemetry/
│ │ │ │ ├── metric.interceptor.go
│ │ │ │ └── trace.interceptor.go
│ │ │ ├── ratelimiter/
│ │ │ │ ├── ratelimiter.go
│ │ │ │ └── ratelimiter_qps.go
│ │ │ └── timer/
│ │ │ └── timer_server.interceptor.go
│ │ ├── local.middleware.wrap.go
│ │ └── resource/
│ │ ├── middleware.handler.go
│ │ ├── monitor.metrics.go
│ │ └── monitor.resource.go
│ ├── mq/
│ │ ├── consumer.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── kafka/
│ │ │ ├── config.go
│ │ │ ├── config.option.go
│ │ │ ├── config_option.go
│ │ │ ├── kafka.go
│ │ │ ├── kafka.option.go
│ │ │ ├── kafka.pb.go
│ │ │ ├── kafka.proto
│ │ │ ├── kafka.yaml
│ │ │ ├── kafka_consumer.go
│ │ │ ├── kafka_message.go
│ │ │ ├── kafka_option.go
│ │ │ ├── kafka_producer.go
│ │ │ └── kafka_test.go
│ │ ├── message.go
│ │ └── producer.go
│ ├── opentelemetry/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── metric/
│ │ │ ├── api/
│ │ │ │ ├── api.go
│ │ │ │ ├── example_test.go
│ │ │ │ └── instrument.go
│ │ │ ├── meter.go
│ │ │ ├── meter.logging_exporter.go
│ │ │ ├── meter.option.go
│ │ │ ├── meter.pull.exporter.go
│ │ │ ├── meter.push.exporter.go
│ │ │ ├── meter_option.go
│ │ │ ├── otlp/
│ │ │ │ ├── otlp.metric.go
│ │ │ │ ├── otlp.metric.option.go
│ │ │ │ └── otlp.metric_option.go
│ │ │ ├── prometheus/
│ │ │ │ ├── prometheus.metric.go
│ │ │ │ ├── prometheus.metric.option.go
│ │ │ │ └── prometheus.metric_option.go
│ │ │ ├── report/
│ │ │ │ ├── dimension.go
│ │ │ │ └── report.go
│ │ │ └── stdout/
│ │ │ ├── stdout.metric.go
│ │ │ ├── stdout.metric.option.go
│ │ │ └── stdout.metric_option.go
│ │ ├── opentelemetry.go
│ │ ├── opentelemetry.option.go
│ │ ├── opentelemetry.pb.go
│ │ ├── opentelemetry.proto
│ │ ├── opentelemetry.yaml
│ │ ├── opentelemetry_option.go
│ │ ├── opentelemetry_test.go
│ │ ├── resource/
│ │ │ ├── resource.go
│ │ │ ├── resource.memory.go
│ │ │ ├── resource.stats.go
│ │ │ ├── resource_stats.option.go
│ │ │ └── resource_stats_option.go
│ │ └── tracer/
│ │ ├── otlp/
│ │ │ ├── otlp.trace.go
│ │ │ └── otlp.trace.option.go
│ │ ├── stdout/
│ │ │ ├── stdout.trace.go
│ │ │ ├── stdout.trace.option.go
│ │ │ └── stdout.trace_option.go
│ │ ├── tracer.exporter.go
│ │ ├── tracer.go
│ │ ├── tracer.logging_exporter.go
│ │ ├── tracer.option.go
│ │ └── tracer_option.go
│ ├── pool/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── instance/
│ │ │ ├── call.go
│ │ │ ├── error.go
│ │ │ ├── instance.go
│ │ │ ├── pool.instance.go
│ │ │ ├── pool.instance.option.go
│ │ │ ├── pool.instance_option.go
│ │ │ ├── pool.instance_test.go
│ │ │ └── thread.go
│ │ ├── task/
│ │ │ ├── batch_process.go
│ │ │ ├── batch_process_test.go
│ │ │ ├── pool.go
│ │ │ ├── pool.option.go
│ │ │ ├── pool_options.go
│ │ │ ├── pool_test.go
│ │ │ ├── worker.go
│ │ │ └── worker_test.go
│ │ └── taskqueue/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── pool.go
│ │ ├── pool.option.go
│ │ ├── pool_option.go
│ │ ├── pool_test.go
│ │ ├── queue/
│ │ │ ├── message.go
│ │ │ ├── queue.go
│ │ │ └── redis/
│ │ │ └── queue.redis.go
│ │ ├── redis.yaml
│ │ ├── registry.go
│ │ ├── task.go
│ │ ├── tasker_syncmap.go
│ │ ├── taskq.yaml
│ │ ├── taskqueue.pb.go
│ │ └── taskqueue.proto
│ ├── profile/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── profile.go
│ │ └── profile_test.go
│ ├── protobuf/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── jsonpb/
│ │ │ ├── jsonpb_marshal.go
│ │ │ └── jsonpb_unmarshal.go
│ │ └── prototext/
│ │ └── encode.go
│ ├── proxy/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── proxy.go
│ │ ├── proxy.option.go
│ │ ├── proxy_option.go
│ │ └── proxy_test.go
│ ├── resolver/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── dns/
│ │ │ ├── dns_resolver.go
│ │ │ ├── k8s-resolver/
│ │ │ │ ├── k8s_dns_resolver.go
│ │ │ │ ├── k8s_dns_resolver_test.go
│ │ │ │ ├── k8s_resolver.option.go
│ │ │ │ └── k8s_resolver_option.go
│ │ │ └── net-resolver/
│ │ │ └── net_dns_resolver.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── resolver.go
│ │ ├── resolver.pb.go
│ │ ├── resolver.proto
│ │ ├── resolver.yaml
│ │ ├── resolver_query.option.go
│ │ ├── resolver_query_option.go
│ │ ├── resolver_test.go
│ │ └── resolverquerymap_syncmap.go
│ ├── scheduler/
│ │ ├── backend/
│ │ │ └── backend.go
│ │ ├── broker/
│ │ │ ├── broker.go
│ │ │ └── memory/
│ │ │ └── memory.go
│ │ ├── dispatcher.go
│ │ ├── dispatcher_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── server.go
│ │ ├── server_test.go
│ │ ├── task/
│ │ │ ├── result.go
│ │ │ ├── task.go
│ │ │ └── validate.go
│ │ ├── types/
│ │ │ ├── task.pb.go
│ │ │ └── task.proto
│ │ └── worker.go
│ ├── storage/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── mount/
│ │ │ ├── mount.go
│ │ │ └── mount_test.go
│ │ └── s3/
│ │ ├── config.go
│ │ ├── config.option.go
│ │ ├── config_option.go
│ │ ├── s3.go
│ │ ├── s3.option.go
│ │ ├── s3.pb.go
│ │ ├── s3.proto
│ │ ├── s3.yaml
│ │ ├── s3_option.go
│ │ └── s3_test.go
│ ├── viper/
│ │ ├── code/
│ │ │ ├── error.template.pb.go
│ │ │ └── error.template.proto
│ │ ├── error.yaml
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── unmarshaler.go
│ │ ├── viper.go
│ │ └── viper_test.go
│ └── webserver/
│ ├── app/
│ │ ├── cmd.go
│ │ ├── flags.go
│ │ └── version.go
│ ├── config.go
│ ├── config.option.go
│ ├── config_option.go
│ ├── controller/
│ │ ├── healthz/
│ │ │ ├── checker.go
│ │ │ ├── healthz.go
│ │ │ └── healthz_test.go
│ │ ├── profiler/
│ │ │ └── profiler.go
│ │ └── static/
│ │ ├── static.go
│ │ └── static_test.go
│ ├── go.mod
│ ├── go.sum
│ ├── hooks.go
│ ├── symbolizer.go
│ ├── webserver.go
│ ├── webserver.pb.go
│ ├── webserver.proto
│ ├── webserver.proto.go
│ ├── webserver.yaml
│ ├── webserver_qps_limit.go
│ └── webserver_test.go
├── script/
│ ├── copyright.sh
│ ├── copyright.txt
│ ├── go_proto_gen.sh
│ └── tools/
│ ├── cat.sh
│ └── dmesg.sh
├── third_party/
│ ├── README.md
│ └── github.com/
│ └── grpc-ecosystem/
│ └── grpc-gateway/
│ └── google/
│ └── api/
│ ├── annotations.proto
│ └── http.proto
└── tutorial/
└── programming_paradigm/
├── control.inverse_test.go
├── decorator_test.go
├── error.handle_test.go
├── factory_test.go
├── function.options_test.go
├── interface.check_test.go
├── interface.program_test.go
├── map.reduce_test.go
├── pipeline_test.go
└── visitor_test.go
Showing preview only (3,044K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (18496 symbols across 1304 files)
FILE: go/archive/archive.go
type Archiver (line 29) | type Archiver interface
FILE: go/archive/option/file_info.go
type FileInfo (line 29) | type FileInfo struct
method String (line 34) | func (e *FileInfo) String() string {
type ExtractMsg (line 43) | type ExtractMsg struct
method String (line 48) | func (e *ExtractMsg) String() string {
FILE: go/archive/zip/zip.go
type Zip (line 40) | type Zip struct
method Extract (line 43) | func (z Zip) Extract(srcFile, destDir string) ([]*option.FileInfo, err...
method ExtractStream (line 70) | func (z Zip) ExtractStream(
method extractAndWriteFile (line 117) | func (z Zip) extractAndWriteFile(
FILE: go/archive/zip/zip_test.go
function TestExtractZip (line 30) | func TestExtractZip(t *testing.T) {
FILE: go/bytes/bytes.go
function Truncate (line 29) | func Truncate(s []byte, n int) []byte {
function Encode (line 41) | func Encode[T any](m T) []byte {
function Decode (line 56) | func Decode[T any](b []byte) T {
FILE: go/bytes/bytes_test.go
function TestEncodeAndDecode (line 12) | func TestEncodeAndDecode(t *testing.T) {
FILE: go/client/client.go
type Client (line 28) | type Client struct
method logf (line 43) | func (c *Client) logf(format string, args ...interface{}) {
function New (line 36) | func New(options ...ClientOption) *Client {
FILE: go/client/client.options.go
function WithClientOptionPath (line 24) | func WithClientOptionPath(path string) ClientOption {
FILE: go/client/client_options.go
type ClientOption (line 25) | type ClientOption interface
type EmptyClientOption (line 33) | type EmptyClientOption struct
method apply (line 35) | func (EmptyClientOption) apply(*Client) {}
type ClientOptionFunc (line 39) | type ClientOptionFunc
method apply (line 41) | func (f ClientOptionFunc) apply(do *Client) {
function _ClientOptionWithDefault (line 46) | func _ClientOptionWithDefault() ClientOption {
method ApplyOptions (line 51) | func (o *Client) ApplyOptions(options ...ClientOption) *Client {
FILE: go/client/client_test.go
function TestNew (line 31) | func TestNew(t *testing.T) {
FILE: go/container/heap/heap.go
constant closedMsg (line 31) | closedMsg = "heap is closed"
type LessFunc (line 35) | type LessFunc
type KeyFunc (line 39) | type KeyFunc
type heapItem (line 41) | type heapItem struct
type itemKeyValue (line 46) | type itemKeyValue struct
type heapData (line 53) | type heapData struct
method Less (line 75) | func (h *heapData) Less(i, j int) bool {
method Len (line 91) | func (h *heapData) Len() int { return len(h.queue) }
method Swap (line 95) | func (h *heapData) Swap(i, j int) {
method Push (line 104) | func (h *heapData) Push(kv interface{}) {
method Pop (line 112) | func (h *heapData) Pop() interface{} {
type Heap (line 126) | type Heap struct
method Close (line 141) | func (h *Heap) Close() {
method Add (line 150) | func (h *Heap) Add(obj interface{}) error {
method BulkAdd (line 170) | func (h *Heap) BulkAdd(list []interface{}) error {
method AddIfNotPresent (line 195) | func (h *Heap) AddIfNotPresent(obj interface{}) error {
method AddIfHeapOrder (line 210) | func (h *Heap) AddIfHeapOrder(obj interface{}) error {
method addIfNotPresentLocked (line 231) | func (h *Heap) addIfNotPresentLocked(key string, obj interface{}) {
method Update (line 240) | func (h *Heap) Update(obj interface{}) error {
method Delete (line 245) | func (h *Heap) Delete(obj interface{}) error {
method Pop (line 258) | func (h *Heap) Pop() (interface{}, error) {
method List (line 279) | func (h *Heap) List() []interface{} {
method ListKeys (line 291) | func (h *Heap) ListKeys() []string {
method Get (line 303) | func (h *Heap) Get(obj interface{}) (interface{}, bool) {
method GetByKey (line 309) | func (h *Heap) GetByKey(key string) (interface{}, bool) {
method IsClosed (line 320) | func (h *Heap) IsClosed() bool {
function NewHeap (line 330) | func NewHeap(keyFn KeyFunc, lessFn LessFunc) *Heap {
FILE: go/container/heap/heap_test.go
function testHeapObjectKeyFunc (line 31) | func testHeapObjectKeyFunc(obj interface{}) string {
type testHeapObject (line 35) | type testHeapObject struct
function mkHeapObj (line 40) | func mkHeapObj(name string, val interface{}) testHeapObject {
function compareInts (line 45) | func compareInts(val1 interface{}, val2 interface{}) bool {
function TestHeapBasic (line 52) | func TestHeapBasic(t *testing.T) {
function TestHeap_Get (line 91) | func TestHeap_Get(t *testing.T) {
function TestHeap_GetByKey (line 111) | func TestHeap_GetByKey(t *testing.T) {
type Student (line 129) | type Student struct
function testStudentObjectKeyFunc (line 135) | func testStudentObjectKeyFunc(obj interface{}) string {
function compareStudentScore (line 140) | func compareStudentScore(val1 interface{}, val2 interface{}) bool {
function TestMaxHeap (line 146) | func TestMaxHeap(t *testing.T) {
FILE: go/container/set/set.go
type Set (line 30) | type Set
function New (line 32) | func New[T comparable](items ...T) Set[T] {
method Insert (line 40) | func (s Set[T]) Insert(items ...T) Set[T] {
method Delete (line 49) | func (s Set[T]) Delete(items ...T) Set[T] {
method Has (line 57) | func (s Set[T]) Has(item T) bool {
method HasAll (line 63) | func (s Set[T]) HasAll(items ...T) bool {
method HasAny (line 73) | func (s Set[T]) HasAny(items ...T) bool {
method Difference (line 88) | func (s Set[T]) Difference(s2 Set[T]) Set[T] {
method Union (line 104) | func (s1 Set[T]) Union(s2 Set[T]) Set[T] {
method Intersection (line 120) | func (s1 Set[T]) Intersection(s2 Set[T]) Set[T] {
method IsSuperset (line 139) | func (s1 Set[T]) IsSuperset(s2 Set[T]) bool {
method Equal (line 151) | func (s1 Set[T]) Equal(s2 Set[T]) bool {
type sortableSliceOfT (line 155) | type sortableSliceOfT
method Len (line 157) | func (s sortableSliceOfT[T]) Len() int { return len(s) }
method Less (line 158) | func (s sortableSliceOfT[T]) Less(i, j int) bool { return lessT(s[i], s[...
method Swap (line 159) | func (s sortableSliceOfT[T]) Swap(i, j int) { s[i], s[j] = s[j], s[...
method List (line 162) | func (s Set[T]) List() []T {
method UnsortedList (line 172) | func (s Set[T]) UnsortedList() []T {
method PopAny (line 181) | func (s Set[T]) PopAny() (T, bool) {
method Len (line 191) | func (s Set[T]) Len() int {
type LesserT (line 195) | type LesserT interface
function lessT (line 199) | func lessT[T comparable](lhs, rhs T) bool {
FILE: go/container/set/set.interface.go
type Object (line 31) | type Object
method Insert (line 53) | func (s Object) Insert(items ...interface{}) Object {
method Delete (line 61) | func (s Object) Delete(items ...interface{}) Object {
method Has (line 69) | func (s Object) Has(item interface{}) bool {
method HasAll (line 75) | func (s Object) HasAll(items ...interface{}) bool {
method HasAny (line 85) | func (s Object) HasAny(items ...interface{}) bool {
method Difference (line 100) | func (s Object) Difference(s2 Object) Object {
method Union (line 116) | func (s1 Object) Union(s2 Object) Object {
method Intersection (line 132) | func (s1 Object) Intersection(s2 Object) Object {
method IsSuperset (line 151) | func (s1 Object) IsSuperset(s2 Object) bool {
method Equal (line 163) | func (s1 Object) Equal(s2 Object) bool {
method List (line 174) | func (s Object) List() []interface{} {
method UnsortedList (line 184) | func (s Object) UnsortedList() []interface{} {
method PopAny (line 193) | func (s Object) PopAny() (interface{}, bool) {
method Len (line 203) | func (s Object) Len() int {
function NewObject (line 34) | func NewObject(items ...interface{}) Object {
function KeySet (line 42) | func KeySet(theMap interface{}) Object {
type sortableSliceOfObject (line 167) | type sortableSliceOfObject
method Len (line 169) | func (s sortableSliceOfObject) Len() int { return len(s) }
method Less (line 170) | func (s sortableSliceOfObject) Less(i, j int) bool { return lessObject...
method Swap (line 171) | func (s sortableSliceOfObject) Swap(i, j int) { s[i], s[j] = s[j]...
type Lesser (line 207) | type Lesser interface
function lessObject (line 308) | func lessObject(lhs, rhs interface{}) bool {
FILE: go/container/set/set_interface_test.go
function TestSetInsert (line 30) | func TestSetInsert(t *testing.T) {
function TestSetEquals (line 58) | func TestSetEquals(t *testing.T) {
function TestSetUnion (line 74) | func TestSetUnion(t *testing.T) {
function TestSetIntersection (line 119) | func TestSetIntersection(t *testing.T) {
FILE: go/container/set/set_string.go
type Empty (line 29) | type Empty struct
type String (line 32) | type String
method Insert (line 54) | func (s String) Insert(items ...string) String {
method Delete (line 62) | func (s String) Delete(items ...string) String {
method Has (line 70) | func (s String) Has(item string) bool {
method HasAll (line 76) | func (s String) HasAll(items ...string) bool {
method HasAny (line 86) | func (s String) HasAny(items ...string) bool {
method Difference (line 101) | func (s String) Difference(s2 String) String {
method Union (line 117) | func (s1 String) Union(s2 String) String {
method Intersection (line 133) | func (s1 String) Intersection(s2 String) String {
method IsSuperset (line 152) | func (s1 String) IsSuperset(s2 String) bool {
method Equal (line 164) | func (s1 String) Equal(s2 String) bool {
method List (line 175) | func (s String) List() []string {
method UnsortedList (line 185) | func (s String) UnsortedList() []string {
method PopAny (line 194) | func (s String) PopAny() (string, bool) {
method Len (line 204) | func (s String) Len() int {
function NewString (line 35) | func NewString(items ...string) String {
function StringKeySet (line 43) | func StringKeySet(theMap interface{}) String {
type sortableSliceOfString (line 168) | type sortableSliceOfString
method Len (line 170) | func (s sortableSliceOfString) Len() int { return len(s) }
method Less (line 171) | func (s sortableSliceOfString) Less(i, j int) bool { return lessString...
method Swap (line 172) | func (s sortableSliceOfString) Swap(i, j int) { s[i], s[j] = s[j]...
function lessString (line 208) | func lessString(lhs, rhs string) bool {
FILE: go/container/set/set_string_test.go
function TestStringSetInsert (line 30) | func TestStringSetInsert(t *testing.T) {
function TestStringSetEquals (line 58) | func TestStringSetEquals(t *testing.T) {
function TestStringSetUnion (line 74) | func TestStringSetUnion(t *testing.T) {
function TestStringSetIntersection (line 119) | func TestStringSetIntersection(t *testing.T) {
FILE: go/container/set/set_test.go
function TestGenericSetNew (line 9) | func TestGenericSetNew(t *testing.T) {
function TestGenericSetInsert (line 15) | func TestGenericSetInsert(t *testing.T) {
function TestGenericSetEquals (line 43) | func TestGenericSetEquals(t *testing.T) {
function TestGenericSetUnion (line 59) | func TestGenericSetUnion(t *testing.T) {
FILE: go/container/workqueue/queue.go
type Interface (line 28) | type Interface interface
function NewQueue (line 37) | func NewQueue() *Type {
type Type (line 48) | type Type struct
method Add (line 91) | func (q *Type) Add(item interface{}) {
method Len (line 110) | func (q *Type) Len() int {
method Get (line 116) | func (q *Type) Get() (item interface{}, shutdown bool) {
method Done (line 138) | func (q *Type) Done(item interface{}) {
method ShutDown (line 153) | func (q *Type) ShutDown() {
method ShutDownWithDrain (line 167) | func (q *Type) ShutDownWithDrain() {
method isProcessing (line 177) | func (q *Type) isProcessing() bool {
method waitForProcessing (line 185) | func (q *Type) waitForProcessing() {
method setDrain (line 198) | func (q *Type) setDrain(shouldDrain bool) {
method shouldDrain (line 204) | func (q *Type) shouldDrain() bool {
method shutdown (line 210) | func (q *Type) shutdown() {
method ShuttingDown (line 217) | func (q *Type) ShuttingDown() bool {
type empty (line 69) | type empty struct
type t (line 70) | type t interface
type set (line 71) | type set
method has (line 73) | func (s set) has(item t) bool {
method insert (line 78) | func (s set) insert(item t) {
method delete (line 82) | func (s set) delete(item t) {
method len (line 86) | func (s set) len() int {
FILE: go/container/workqueue/queue_test.go
function TestBasic (line 32) | func TestBasic(t *testing.T) {
function TestReinsert (line 93) | func TestReinsert(t *testing.T) {
FILE: go/context/context.go
constant DefaultHTTPRequestIDKey (line 33) | DefaultHTTPRequestIDKey = "X-Request-ID"
constant DefaultHTTPTraceIDKey (line 34) | DefaultHTTPTraceIDKey = "X-Traceid"
function WithTimeout (line 37) | func WithTimeout(ctx context.Context, timeout time.Duration) (context.Co...
function ExtractStringFromContext (line 45) | func ExtractStringFromContext(ctx context.Context, key string) string {
function ExtractIntegerFromContext (line 53) | func ExtractIntegerFromContext(ctx context.Context, key string) (int64, ...
function ExtractFromContext (line 67) | func ExtractFromContext(ctx context.Context, key string) string {
function UpdateContext (line 84) | func UpdateContext(ctx context.Context, key string, values map[string]in...
function SetPairContext (line 96) | func SetPairContext(ctx context.Context, key, value string) context.Cont...
function AppendContext (line 100) | func AppendContext(ctx context.Context, key string, values ...string) co...
function WithContextRequestId (line 106) | func WithContextRequestId(ctx context.Context, id string) context.Context {
function ExtractRequestIDFromContext (line 110) | func ExtractRequestIDFromContext(ctx context.Context) string {
function ExtractTraceIDFromContext (line 119) | func ExtractTraceIDFromContext(ctx context.Context) string {
FILE: go/context/context_test.go
function withField (line 33) | func withField(ctx context.Context) {
function TestContext (line 38) | func TestContext(t *testing.T) {
function doA (line 45) | func doA(ctx context.Context) {
function doB (line 65) | func doB(ctx context.Context) {
function TestContextTimeout (line 85) | func TestContextTimeout(t *testing.T) {
function TestExtractIntegerFromContext (line 91) | func TestExtractIntegerFromContext(t *testing.T) {
function TestExtractStringFromContext (line 125) | func TestExtractStringFromContext(t *testing.T) {
FILE: go/crypto/aes/aes_cbc.go
function AesCbcEncrypt (line 34) | func AesCbcEncrypt(plainText, key []byte) ([]byte, error) {
function AesCbcDecrypt (line 56) | func AesCbcDecrypt(cipherText, key []byte) ([]byte, error) {
function pad (line 82) | func pad(plainText []byte, blockSize int) []byte {
function unpad (line 89) | func unpad(plainText []byte) ([]byte, error) {
FILE: go/crypto/aes/aes_cbc_test.go
function TestAesCbcEncryptDecrypt (line 37) | func TestAesCbcEncryptDecrypt(t *testing.T) {
function TestAesCbcDecrypt (line 67) | func TestAesCbcDecrypt(t *testing.T) {
FILE: go/crypto/md5/md5.go
function SumBytes (line 34) | func SumBytes(b []byte) string {
function SumString (line 40) | func SumString(s string) string {
function SumReader (line 44) | func SumReader(r io.Reader) (string, error) {
function SumReaderN (line 53) | func SumReaderN(r io.Reader, n int64) (string, error) {
function SumReaderAt (line 62) | func SumReaderAt(r io.ReaderAt, offset, length int64) (string, error) {
function SumFile (line 92) | func SumFile(fileName string) (string, error) {
function SumFileAt (line 102) | func SumFileAt(fileName string, offset int64, length int64) (string, err...
FILE: go/crypto/md5/md5_test.go
function TestMd5File (line 34) | func TestMd5File(t *testing.T) {
function TestMd5FileAt (line 57) | func TestMd5FileAt(t *testing.T) {
FILE: go/crypto/sha256/sha256.go
function SumBytes (line 34) | func SumBytes(b []byte) string {
function SumString (line 40) | func SumString(s string) string {
function SumReader (line 44) | func SumReader(r io.Reader) (string, error) {
function SumReaderN (line 53) | func SumReaderN(r io.Reader, n int64) (string, error) {
function SumReaderAt (line 62) | func SumReaderAt(r io.ReaderAt, offset, length int64) (string, error) {
function SumFile (line 92) | func SumFile(fileName string) (string, error) {
function SumFileAt (line 102) | func SumFileAt(fileName string, offset int64, length int64) (string, err...
FILE: go/crypto/sha256/sha256_test.go
function TestSha256File (line 34) | func TestSha256File(t *testing.T) {
function TestSha256FileAt (line 57) | func TestSha256FileAt(t *testing.T) {
FILE: go/encoding/base64/base64.go
function EncodeString (line 29) | func EncodeString(v string) string {
function DecodeString (line 33) | func DecodeString(v string) (string, error) {
function EncodeURL (line 42) | func EncodeURL(v string) string {
function DecodeURL (line 46) | func DecodeURL(v string) (string, error) {
FILE: go/encoding/base64/base64_test.go
function TestString (line 34) | func TestString(t *testing.T) {
function TestURL (line 76) | func TestURL(t *testing.T) {
function TestDecodeString (line 105) | func TestDecodeString(t *testing.T) {
function TestDecodeFile (line 136) | func TestDecodeFile(t *testing.T) {
FILE: go/encoding/hash/hash.go
function HashCode (line 26) | func HashCode(s string) uint32 {
FILE: go/encoding/hash/hash_test.go
function TestHashCode (line 31) | func TestHashCode(t *testing.T) {
FILE: go/encoding/jwt/jwt.go
function ParsePayload (line 42) | func ParsePayload(token string) (map[string]interface{}, error) {
function GetClaimString (line 76) | func GetClaimString(claims map[string]interface{}, key string) string {
function GetClaimFloat64 (line 89) | func GetClaimFloat64(claims map[string]interface{}, key string) float64 {
function padBase64 (line 101) | func padBase64(s string) string {
FILE: go/encoding/jwt/jwt_test.go
function TestParsePayload (line 28) | func TestParsePayload(t *testing.T) {
function TestGetClaimString (line 80) | func TestGetClaimString(t *testing.T) {
function TestGetClaimFloat64 (line 100) | func TestGetClaimFloat64(t *testing.T) {
FILE: go/encoding/protojson/decode.go
type Unmarshaler (line 29) | type Unmarshaler struct
function Unmarshal (line 34) | func Unmarshal(data []byte, pb proto.Message, options ...UnmarshalerOpti...
FILE: go/encoding/protojson/decode.option.go
function WithUnMashalAllowPartial (line 25) | func WithUnMashalAllowPartial(allowPartial bool) UnmarshalerOption {
function WithUnmashalDiscardUnknown (line 32) | func WithUnmashalDiscardUnknown(discardUnknown bool) UnmarshalerOption {
FILE: go/encoding/protojson/decode_option.go
type UnmarshalerOption (line 25) | type UnmarshalerOption interface
type EmptyUnmarshalerOption (line 33) | type EmptyUnmarshalerOption struct
method apply (line 35) | func (EmptyUnmarshalerOption) apply(*Unmarshaler) {}
type UnmarshalerOptionFunc (line 39) | type UnmarshalerOptionFunc
method apply (line 41) | func (f UnmarshalerOptionFunc) apply(do *Unmarshaler) {
function _UnmarshalerOptionWithDefault (line 46) | func _UnmarshalerOptionWithDefault() UnmarshalerOption {
method ApplyOptions (line 51) | func (o *Unmarshaler) ApplyOptions(options ...UnmarshalerOption) *Unmars...
FILE: go/encoding/protojson/encode.go
type Marshaler (line 29) | type Marshaler struct
function Marshal (line 34) | func Marshal(pb proto.Message, options ...MarshalerOption) ([]byte, erro...
FILE: go/encoding/protojson/encode.option.go
function WithMashalMultiline (line 24) | func WithMashalMultiline(multiline bool) MarshalerOption {
function WithMashalUseProtoNames (line 30) | func WithMashalUseProtoNames(useProtoNames bool) MarshalerOption {
function WithMashalUseEnumNumbers (line 36) | func WithMashalUseEnumNumbers(useEnumNumbers bool) MarshalerOption {
function WithMashalEmitUnpopulated (line 42) | func WithMashalEmitUnpopulated(emitUnpopulated bool) MarshalerOption {
FILE: go/encoding/protojson/encode_option.go
type MarshalerOption (line 25) | type MarshalerOption interface
type EmptyMarshalerOption (line 33) | type EmptyMarshalerOption struct
method apply (line 35) | func (EmptyMarshalerOption) apply(*Marshaler) {}
type MarshalerOptionFunc (line 39) | type MarshalerOptionFunc
method apply (line 41) | func (f MarshalerOptionFunc) apply(do *Marshaler) {
function _MarshalerOptionWithDefault (line 46) | func _MarshalerOptionWithDefault() MarshalerOption {
method ApplyOptions (line 51) | func (o *Marshaler) ApplyOptions(options ...MarshalerOption) *Marshaler {
FILE: go/encoding/protojson/protojson_test.go
function TestMarshal (line 32) | func TestMarshal(t *testing.T) {
FILE: go/encoding/protojson/testdata/date.pb.go
constant _ (line 40) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 42) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type DateRequest (line 45) | type DateRequest struct
method Reset (line 53) | func (x *DateRequest) Reset() {
method String (line 62) | func (x *DateRequest) String() string {
method ProtoMessage (line 66) | func (*DateRequest) ProtoMessage() {}
method ProtoReflect (line 68) | func (x *DateRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 81) | func (*DateRequest) Descriptor() ([]byte, []int) {
method GetRequestId (line 85) | func (x *DateRequest) GetRequestId() string {
type DateResponse (line 92) | type DateResponse struct
method Reset (line 101) | func (x *DateResponse) Reset() {
method String (line 110) | func (x *DateResponse) String() string {
method ProtoMessage (line 114) | func (*DateResponse) ProtoMessage() {}
method ProtoReflect (line 116) | func (x *DateResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 129) | func (*DateResponse) Descriptor() ([]byte, []int) {
method GetRequestId (line 133) | func (x *DateResponse) GetRequestId() string {
method GetDate (line 140) | func (x *DateResponse) GetDate() string {
function file_go_encoding_protojson_testdata_date_proto_rawDescGZIP (line 175) | func file_go_encoding_protojson_testdata_date_proto_rawDescGZIP() []byte {
function init (line 195) | func init() { file_go_encoding_protojson_testdata_date_proto_init() }
function file_go_encoding_protojson_testdata_date_proto_init (line 196) | func file_go_encoding_protojson_testdata_date_proto_init() {
FILE: go/errors/error.grpc.go
function FromError (line 35) | func FromError(err error) (s *status.Status, ok bool) {
function ErrorToCodeString (line 51) | func ErrorToCodeString(err error) string {
function ErrorToString (line 74) | func ErrorToString(err error) string {
function ErrorToCode (line 86) | func ErrorToCode(err error) codes.Code {
function Errorf (line 99) | func Errorf(code interface{}, format string, a ...interface{}) error {
function Errore (line 134) | func Errore(errlist ...error) error {
FILE: go/errors/errors.go
type Aggregate (line 28) | type Aggregate interface
function NewAggregate (line 39) | func NewAggregate(errlist []error) Aggregate {
type aggregate (line 59) | type aggregate
method Error (line 62) | func (agg aggregate) Error() string {
method Is (line 82) | func (agg aggregate) Is(target error) bool {
method visit (line 88) | func (agg aggregate) visit(f func(err error) bool) bool {
method Errors (line 112) | func (agg aggregate) Errors() []error {
FILE: go/errors/errors_test.go
function TestError (line 32) | func TestError(t *testing.T) {
function TestErrorIs (line 44) | func TestErrorIs(t *testing.T) {
function TestErrore (line 81) | func TestErrore(t *testing.T) {
FILE: go/errors/handler.go
function HandleError (line 50) | func HandleError(err error) {
function ErrorChain (line 61) | func ErrorChain(handlers ...func(err error, handled bool) (error, bool))...
FILE: go/filesystem/filesystem.go
type Filesystem (line 31) | type Filesystem interface
type File (line 51) | type File interface
FILE: go/filesystem/mountpoint.go
type DeviceNumber (line 50) | type DeviceNumber
method String (line 52) | func (num DeviceNumber) String() string {
function getNumberOfContainingDevice (line 58) | func getNumberOfContainingDevice(path string) (DeviceNumber, error) {
function filesystemLacksMainMountError (line 66) | func filesystemLacksMainMountError(deviceNumber DeviceNumber) error {
type Mount (line 74) | type Mount struct
function FindMount (line 83) | func FindMount(path string) (*Mount, error) {
function loadMountInfo (line 139) | func loadMountInfo() error {
function readMountInfo (line 155) | func readMountInfo(r io.Reader) error {
function parseMountInfoLine (line 207) | func parseMountInfoLine(line string) *Mount {
function newDeviceNumberFromString (line 244) | func newDeviceNumberFromString(str string) (DeviceNumber, error) {
function unescapeString (line 256) | func unescapeString(str string) string {
function getDeviceName (line 275) | func getDeviceName(num DeviceNumber) string {
type mountpointTreeNode (line 283) | type mountpointTreeNode struct
function addUncontainedSubtreesRecursive (line 289) | func addUncontainedSubtreesRecursive(dst map[string]bool,
function findMainMount (line 299) | func findMainMount(filesystemMounts []*Mount) *Mount {
FILE: go/flag/flag.go
constant usageFmt (line 35) | usageFmt = "Usage:\n %s\n"
type NamedFlagSets (line 39) | type NamedFlagSets struct
method FlagSet (line 50) | func (nfs *NamedFlagSets) FlagSet(name string) *pflag.FlagSet {
function PrintSections (line 68) | func PrintSections(w io.Writer, fss NamedFlagSets, cols int) {
function SetUsageAndHelpFunc (line 100) | func SetUsageAndHelpFunc(cmd *cobra.Command, fss NamedFlagSets, cols int) {
FILE: go/idgen/id_gen.go
constant Epoch (line 29) | Epoch int64 = 1704067200000
constant workerIDBits (line 32) | workerIDBits = 10
constant sequenceBits (line 33) | sequenceBits = 12
constant maxWorkerID (line 36) | maxWorkerID = -1 ^ (-1 << workerIDBits)
constant maxSequence (line 37) | maxSequence = -1 ^ (-1 << sequenceBits)
constant workerIDShift (line 40) | workerIDShift = sequenceBits
constant timestampShift (line 41) | timestampShift = sequenceBits + workerIDBits
type Generator (line 53) | type Generator struct
method NextID (line 86) | func (g *Generator) NextID() (uint64, error) {
method MustNextID (line 121) | func (g *Generator) MustNextID() uint64 {
method currentMillis (line 130) | func (g *Generator) currentMillis() int64 {
method waitNextMillis (line 135) | func (g *Generator) waitNextMillis(lastTimestamp int64) int64 {
function NewGenerator (line 62) | func NewGenerator(workerID int64) (*Generator, error) {
function MustNewGenerator (line 76) | func MustNewGenerator(workerID int64) *Generator {
function ParseID (line 144) | func ParseID(id uint64) (timestamp int64, workerID int64, sequence int64) {
function GetTimestamp (line 152) | func GetTimestamp(id uint64) time.Time {
function GetWorkerID (line 158) | func GetWorkerID(id uint64) int64 {
function GetSequence (line 164) | func GetSequence(id uint64) int64 {
function GenerateUint64FromUUID (line 170) | func GenerateUint64FromUUID() uint64 {
function UUIDToUint64XOR (line 176) | func UUIDToUint64XOR(id uuid.UUID) uint64 {
FILE: go/idgen/id_gen_test.go
function TestNewGenerator (line 10) | func TestNewGenerator(t *testing.T) {
function TestMustNewGenerator (line 51) | func TestMustNewGenerator(t *testing.T) {
function TestNextID (line 77) | func TestNextID(t *testing.T) {
function TestMustNextID (line 102) | func TestMustNextID(t *testing.T) {
function TestIDUniqueness (line 118) | func TestIDUniqueness(t *testing.T) {
function TestWorkerIDInGeneratedID (line 137) | func TestWorkerIDInGeneratedID(t *testing.T) {
function TestParseID (line 154) | func TestParseID(t *testing.T) {
function TestGetTimestamp (line 182) | func TestGetTimestamp(t *testing.T) {
function TestSequenceOverflow (line 199) | func TestSequenceOverflow(t *testing.T) {
function TestConcurrentGeneration (line 225) | func TestConcurrentGeneration(t *testing.T) {
function TestMultipleGenerators (line 279) | func TestMultipleGenerators(t *testing.T) {
function TestConcurrentSameWorker (line 318) | func TestConcurrentSameWorker(t *testing.T) {
function BenchmarkNextID (line 365) | func BenchmarkNextID(b *testing.B) {
function BenchmarkNextIDParallel (line 375) | func BenchmarkNextIDParallel(b *testing.B) {
function BenchmarkParseID (line 387) | func BenchmarkParseID(b *testing.B) {
function formatWorkerID (line 398) | func formatWorkerID(workerID int64) string {
FILE: go/idgen/wk_id_gen.go
type WorkerIDGenerator (line 13) | type WorkerIDGenerator struct
method GenerateWorkerID (line 22) | func (w *WorkerIDGenerator) GenerateWorkerID() (int64, error) {
method fromEnv (line 47) | func (w *WorkerIDGenerator) fromEnv() (int64, bool) {
method fromIP (line 65) | func (w *WorkerIDGenerator) fromIP() (int64, bool) {
method fromMAC (line 86) | func (w *WorkerIDGenerator) fromMAC() (int64, bool) {
method fromHostname (line 110) | func (w *WorkerIDGenerator) fromHostname() (int64, bool) {
method GetMachineInfo (line 123) | func (w *WorkerIDGenerator) GetMachineInfo() map[string]string {
method getIPAddresses (line 153) | func (w *WorkerIDGenerator) getIPAddresses() []string {
method getMACAddresses (line 172) | func (w *WorkerIDGenerator) getMACAddresses() []string {
function NewWorkerIDGenerator (line 16) | func NewWorkerIDGenerator() *WorkerIDGenerator {
function GenerateFromIP (line 189) | func GenerateFromIP(ip string) (int64, error) {
function GenerateFromMAC (line 206) | func GenerateFromMAC(mac string) (int64, error) {
function GenerateFromString (line 222) | func GenerateFromString(s string) int64 {
function AutoGenerator (line 230) | func AutoGenerator() (*Generator, error) {
function MustAutoGenerator (line 246) | func MustAutoGenerator() *Generator {
FILE: go/idgen/wk_id_gen_test.go
function TestGenerateWorkerID (line 9) | func TestGenerateWorkerID(t *testing.T) {
function TestFromEnv (line 25) | func TestFromEnv(t *testing.T) {
function TestGenerateFromIP (line 62) | func TestGenerateFromIP(t *testing.T) {
function TestGenerateFromMAC (line 97) | func TestGenerateFromMAC(t *testing.T) {
function TestGenerateFromString (line 131) | func TestGenerateFromString(t *testing.T) {
function TestGenerateFromStringConsistency (line 155) | func TestGenerateFromStringConsistency(t *testing.T) {
function TestGenerateFromStringUniqueness (line 171) | func TestGenerateFromStringUniqueness(t *testing.T) {
function TestAutoGenerator (line 200) | func TestAutoGenerator(t *testing.T) {
function TestMustAutoGenerator (line 224) | func TestMustAutoGenerator(t *testing.T) {
function TestGetMachineInfo (line 245) | func TestGetMachineInfo(t *testing.T) {
function TestWorkerIDRange (line 260) | func TestWorkerIDRange(t *testing.T) {
function TestEnvironmentPriority (line 280) | func TestEnvironmentPriority(t *testing.T) {
function BenchmarkGenerateWorkerID (line 301) | func BenchmarkGenerateWorkerID(b *testing.B) {
function BenchmarkGenerateFromString (line 311) | func BenchmarkGenerateFromString(b *testing.B) {
function BenchmarkGenerateFromIP (line 321) | func BenchmarkGenerateFromIP(b *testing.B) {
function BenchmarkAutoGenerator (line 331) | func BenchmarkAutoGenerator(b *testing.B) {
FILE: go/io/copy.go
type Mode (line 37) | type Mode
constant Content (line 41) | Content Mode = iota
constant Hardlink (line 43) | Hardlink
function CopyAll (line 46) | func CopyAll(src, dst string) (err error) {
function CopyDir (line 59) | func CopyDir(srcDir, dstDir string, copyMode Mode) (err error) {
function CopyRegular (line 77) | func CopyRegular(srcPath, dstPath string, fileInfo os.FileInfo) error {
function legacyCopy (line 102) | func legacyCopy(srcFile io.Reader, dstFile io.Writer) error {
function CopyFile (line 108) | func CopyFile(src, dst string) (err error) {
function copyFileContents (line 169) | func copyFileContents(src, dst string) (err error) {
FILE: go/io/copy_darwin.go
function CopyPath (line 26) | func CopyPath(srcPath, dstPath string, f os.FileInfo, copyMode Mode) err...
function doCopyWithFileClone (line 30) | func doCopyWithFileClone(srcFile, dstFile *os.File) error {
function doCopyWithFileRange (line 34) | func doCopyWithFileRange(srcFile, dstFile *os.File, fileinfo os.FileInfo...
FILE: go/io/copy_linux.go
function CopyPath (line 34) | func CopyPath(srcPath, dstPath string, f os.FileInfo, copyMode Mode) err...
function doCopyWithFileClone (line 108) | func doCopyWithFileClone(srcFile, dstFile *os.File) error {
function doCopyWithFileRange (line 112) | func doCopyWithFileRange(srcFile, dstFile *os.File, fileinfo os.FileInfo...
FILE: go/io/copy_test.go
function TestCopyDir (line 41) | func TestCopyDir(t *testing.T) {
function TestCopyFile (line 88) | func TestCopyFile(t *testing.T) {
function TestCopyAll (line 127) | func TestCopyAll(t *testing.T) {
function randomMode (line 154) | func randomMode(baseMode int) os.FileMode {
function populateSrcDir (line 161) | func populateSrcDir(t *testing.T, srcDir string, remainingDepth int) {
FILE: go/io/io.go
function ReadFileLines (line 35) | func ReadFileLines(filepath string) ([]string, error) {
function ReadLines (line 53) | func ReadLines(byteArray []byte) []string {
function ReadLineAt (line 67) | func ReadLineAt(readIndex int, byteArray []byte) ([]byte, int) {
function ReadFile (line 118) | func ReadFile(filePath string) ([]byte, error) {
function WriteFile (line 127) | func WriteFile(filePath string, content []byte, appended bool) error {
function WriteFileLines (line 148) | func WriteFileLines(filePath string, lines []string, appended bool) (err...
function WriteFileLine (line 172) | func WriteFileLine(filePath string, words []string, appended bool) (err ...
function WriteLine (line 193) | func WriteLine(buf *bytes.Buffer, words ...string) error {
function WriteBytesLine (line 215) | func WriteBytesLine(buf *bytes.Buffer, bytes []byte) error {
function WriteBytesAt (line 229) | func WriteBytesAt(filepath string, bytes []byte, offset int64) error {
function WriteReader (line 248) | func WriteReader(filepath string, r io.Reader) error {
function WriteReaderAt (line 260) | func WriteReaderAt(filepath string, r io.Reader, offset, length int64) e...
FILE: go/io/io_test.go
function TestWriteFile (line 38) | func TestWriteFile(t *testing.T) {
function TestWriteReadLine (line 63) | func TestWriteReadLine(t *testing.T) {
function TestWriteReadFileLine (line 109) | func TestWriteReadFileLine(t *testing.T) {
function TestWriteFileLines (line 165) | func TestWriteFileLines(t *testing.T) {
function TestWriteAtOneThread (line 214) | func TestWriteAtOneThread(t *testing.T) {
function TestWriteAtMutilThreads (line 255) | func TestWriteAtMutilThreads(t *testing.T) {
function TestWriteReaderAtOneThread (line 300) | func TestWriteReaderAtOneThread(t *testing.T) {
FILE: go/math/exp/exp.go
constant PRECISION (line 30) | PRECISION = 1e-6
function Max (line 32) | func Max[T constraints.Ordered](s ...T) T {
function Min (line 46) | func Min[T constraints.Ordered](s ...T) T {
function Value (line 60) | func Value[T constraints.Ordered](v, min, max T) T {
function Equal (line 71) | func Equal[T float32 | float64](a, b T) bool {
function Sum (line 75) | func Sum[T constraints.Ordered](t ...T) T {
FILE: go/math/exp/exp_test.go
function TestMax (line 31) | func TestMax(t *testing.T) {
function TestEqual (line 61) | func TestEqual(t *testing.T) {
FILE: go/math/math.go
function CountOne (line 26) | func CountOne[T constraints.Integer](n T) int32 {
FILE: go/math/math_test.go
function TestCountOne (line 31) | func TestCountOne(t *testing.T) {
FILE: go/math/rand/rand.go
function Int (line 38) | func Int() int {
function Int31n (line 45) | func Int31n(n int32) int32 {
function Uint32 (line 52) | func Uint32() uint32 {
function Int63n (line 59) | func Int63n(n int64) int64 {
function Intn (line 66) | func Intn(n int) int {
function Float32 (line 73) | func Float32() float32 {
function Float64 (line 80) | func Float64() float64 {
function Uint64 (line 87) | func Uint64() uint64 {
function Read (line 94) | func Read(p []byte) (n int, err error) {
function RangeInt (line 101) | func RangeInt(min, max int) (int, error) {
function RangeString (line 109) | func RangeString(n int) string {
FILE: go/math/rand/rand_test.go
function TestRand (line 36) | func TestRand(t *testing.T) {
function TestRangeInt (line 51) | func TestRangeInt(t *testing.T) {
function TestRead (line 81) | func TestRead(t *testing.T) {
function TestRangeString (line 107) | func TestRangeString(t *testing.T) {
FILE: go/net/grpc/example/data.pb.go
constant _ (line 20) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 22) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type NowRequest (line 25) | type NowRequest struct
method Reset (line 35) | func (x *NowRequest) Reset() {
method String (line 42) | func (x *NowRequest) String() string {
method ProtoMessage (line 46) | func (*NowRequest) ProtoMessage() {}
method ProtoReflect (line 48) | func (x *NowRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 61) | func (*NowRequest) Descriptor() ([]byte, []int) {
method GetRequestId (line 65) | func (x *NowRequest) GetRequestId() string {
type NowResponse (line 72) | type NowResponse struct
method Reset (line 80) | func (x *NowResponse) Reset() {
method String (line 87) | func (x *NowResponse) String() string {
method ProtoMessage (line 91) | func (*NowResponse) ProtoMessage() {}
method ProtoReflect (line 93) | func (x *NowResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 106) | func (*NowResponse) Descriptor() ([]byte, []int) {
method GetRequestId (line 110) | func (x *NowResponse) GetRequestId() string {
method GetDate (line 117) | func (x *NowResponse) GetDate() string {
type NowErrorRequest (line 124) | type NowErrorRequest struct
method Reset (line 131) | func (x *NowErrorRequest) Reset() {
method String (line 138) | func (x *NowErrorRequest) String() string {
method ProtoMessage (line 142) | func (*NowErrorRequest) ProtoMessage() {}
method ProtoReflect (line 144) | func (x *NowErrorRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 157) | func (*NowErrorRequest) Descriptor() ([]byte, []int) {
method GetRequestId (line 161) | func (x *NowErrorRequest) GetRequestId() string {
type NowErrorResponse (line 168) | type NowErrorResponse struct
method Reset (line 176) | func (x *NowErrorResponse) Reset() {
method String (line 183) | func (x *NowErrorResponse) String() string {
method ProtoMessage (line 187) | func (*NowErrorResponse) ProtoMessage() {}
method ProtoReflect (line 189) | func (x *NowErrorResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 202) | func (*NowErrorResponse) Descriptor() ([]byte, []int) {
method GetRequestId (line 206) | func (x *NowErrorResponse) GetRequestId() string {
method GetDate (line 213) | func (x *NowErrorResponse) GetDate() string {
constant file_go_net_grpc_example_data_proto_rawDesc (line 222) | file_go_net_grpc_example_data_proto_rawDesc = "" +
function file_go_net_grpc_example_data_proto_rawDescGZIP (line 249) | func file_go_net_grpc_example_data_proto_rawDescGZIP() []byte {
function init (line 275) | func init() { file_go_net_grpc_example_data_proto_init() }
function file_go_net_grpc_example_data_proto_init (line 276) | func file_go_net_grpc_example_data_proto_init() {
FILE: go/net/grpc/example/data.repository.go
type Repository (line 9) | type Repository struct
method Now (line 13) | func (r *Repository) Now(ctx context.Context, req *NowRequest) (resp *...
FILE: go/net/grpc/example/data.repository_test.go
function TestNow (line 16) | func TestNow(t *testing.T) {
FILE: go/net/grpc/example/data_grpc.pb.go
constant _ (line 19) | _ = grpc.SupportPackageIsVersion9
constant SeaDateService_Now_FullMethodName (line 22) | SeaDateService_Now_FullMethodName = "/sea.api.seadate.SeaDateServic...
constant SeaDateService_NowError_FullMethodName (line 23) | SeaDateService_NowError_FullMethodName = "/sea.api.seadate.SeaDateServic...
type SeaDateServiceClient (line 29) | type SeaDateServiceClient interface
type seaDateServiceClient (line 35) | type seaDateServiceClient struct
method Now (line 43) | func (c *seaDateServiceClient) Now(ctx context.Context, in *NowRequest...
method NowError (line 53) | func (c *seaDateServiceClient) NowError(ctx context.Context, in *NowEr...
function NewSeaDateServiceClient (line 39) | func NewSeaDateServiceClient(cc grpc.ClientConnInterface) SeaDateService...
type SeaDateServiceServer (line 66) | type SeaDateServiceServer interface
type UnimplementedSeaDateServiceServer (line 78) | type UnimplementedSeaDateServiceServer struct
method Now (line 80) | func (UnimplementedSeaDateServiceServer) Now(context.Context, *NowRequ...
method NowError (line 83) | func (UnimplementedSeaDateServiceServer) NowError(context.Context, *No...
method mustEmbedUnimplementedSeaDateServiceServer (line 86) | func (UnimplementedSeaDateServiceServer) mustEmbedUnimplementedSeaDate...
method testEmbeddedByValue (line 87) | func (UnimplementedSeaDateServiceServer) testEmbeddedByValue() ...
type UnsafeSeaDateServiceServer (line 92) | type UnsafeSeaDateServiceServer interface
function RegisterSeaDateServiceServer (line 96) | func RegisterSeaDateServiceServer(s grpc.ServiceRegistrar, srv SeaDateSe...
function _SeaDateService_Now_Handler (line 107) | func _SeaDateService_Now_Handler(srv interface{}, ctx context.Context, d...
function _SeaDateService_NowError_Handler (line 125) | func _SeaDateService_NowError_Handler(srv interface{}, ctx context.Conte...
FILE: go/net/grpc/grpc_client.go
constant defaultMaxMsgSize (line 38) | defaultMaxMsgSize = math.MaxInt32
constant defaultCallTimeout (line 40) | defaultCallTimeout = 3 * time.Second
constant defaultKeepaliveTime (line 42) | defaultKeepaliveTime = 10 * time.Second
constant defaultKeepaliveTimeout (line 44) | defaultKeepaliveTimeout = 3 * time.Second
type connPoolEntry (line 48) | type connPoolEntry struct
type GrpcClient (line 59) | type GrpcClient struct
method setDefaults (line 93) | func (g *GrpcClient) setDefaults() {
method buildDialOptions (line 109) | func (g *GrpcClient) buildDialOptions() []grpc.DialOption {
method Conn (line 121) | func (g *GrpcClient) Conn() *grpc.ClientConn {
method CallTimeout (line 126) | func (g *GrpcClient) CallTimeout() time.Duration {
method Close (line 131) | func (g *GrpcClient) Close() error {
type grpcClientOptions (line 65) | type grpcClientOptions struct
function NewGrpcClient (line 77) | func NewGrpcClient(addr string, options ...GrpcClientOption) (*GrpcClien...
function ClientDialOptions (line 139) | func ClientDialOptions(
function GetGrpcClientConn (line 192) | func GetGrpcClientConn(addr string, opts ...grpc.DialOption) (*grpc.Clie...
function isConnAvailable (line 236) | func isConnAvailable(state connectivity.State) bool {
function CloseGrpcClientConn (line 246) | func CloseGrpcClientConn(addr string) error {
function CloseAllGrpcClientConns (line 259) | func CloseAllGrpcClientConns() error {
FILE: go/net/grpc/grpc_client.option.go
function WithMaxMsgSize (line 27) | func WithMaxMsgSize(maxMsgSize int) GrpcClientOption {
function WithCallTimeout (line 34) | func WithCallTimeout(timeout time.Duration) GrpcClientOption {
function WithKeepaliveTime (line 41) | func WithKeepaliveTime(keepaliveTime time.Duration) GrpcClientOption {
function WithKeepaliveTimeout (line 48) | func WithKeepaliveTimeout(keepaliveTimeout time.Duration) GrpcClientOpti...
function WithDisablePrintMethods (line 55) | func WithDisablePrintMethods(methods ...string) GrpcClientOption {
FILE: go/net/grpc/grpc_client.repository.factory.go
type FactoryConfigFunc (line 34) | type FactoryConfigFunc
type FactoryConfig (line 36) | type FactoryConfig struct
method ApplyOptions (line 49) | func (fc *FactoryConfig[T]) ApplyOptions(configFuncs ...FactoryConfigFun...
method Validate (line 61) | func (fc FactoryConfig[T]) Validate() error {
type Repository (line 69) | type Repository struct
method NewConnect (line 84) | func (r *Repository[T]) NewConnect(ctx context.Context) (client T, conn ...
method Close (line 105) | func (r *Repository[T]) Close(conn *grpc.ClientConn) (err error) {
function newRepository (line 109) | func newRepository[T any](ctx context.Context, fc FactoryConfig[T]) (Rep...
type Factory (line 129) | type Factory struct
function NewFactory (line 133) | func NewFactory[T any](fc FactoryConfig[T], configFuncs ...FactoryConfig...
method NewClient (line 147) | func (f Factory[T]) NewClient(ctx context.Context) (Repository[T], error) {
FILE: go/net/grpc/grpc_client.repository.go
method Call (line 32) | func (r *Repository[T]) Call(ctx context.Context, f func(ctx context.Con...
FILE: go/net/grpc/grpc_client_option.go
type GrpcClientOption (line 25) | type GrpcClientOption interface
type EmptyGrpcClientOption (line 33) | type EmptyGrpcClientOption struct
method apply (line 35) | func (EmptyGrpcClientOption) apply(*GrpcClient) {}
type GrpcClientOptionFunc (line 39) | type GrpcClientOptionFunc
method apply (line 41) | func (f GrpcClientOptionFunc) apply(do *GrpcClient) {
method ApplyOptions (line 45) | func (o *GrpcClient) ApplyOptions(options ...GrpcClientOption) *GrpcClie...
FILE: go/net/grpc/grpc_client_test.go
function TestGetGrpcClientConn (line 31) | func TestGetGrpcClientConn(t *testing.T) {
function TestNewGrpcClient (line 45) | func TestNewGrpcClient(t *testing.T) {
FILE: go/net/grpc/grpc_stats.handler.go
type statHandler (line 31) | type statHandler struct
method TagRPC (line 37) | func (h *statHandler) TagRPC(ctx context.Context, info *stats.RPCTagIn...
method HandleRPC (line 42) | func (h *statHandler) HandleRPC(ctx context.Context, s stats.RPCStats) {
method TagConn (line 59) | func (s *statHandler) TagConn(ctx context.Context, info *stats.ConnTag...
method HandleConn (line 66) | func (s *statHandler) HandleConn(context.Context, stats.ConnStats) {
FILE: go/net/grpc/ip.go
function GetIPFromContext (line 36) | func GetIPFromContext(ctx context.Context) (net.IP, error) {
FILE: go/net/http/clone.go
function CloneURLValues (line 33) | func CloneURLValues(v url.Values) url.Values
function CloneURL (line 36) | func CloneURL(u *url.URL) *url.URL
function CloneMultipartForm (line 39) | func CloneMultipartForm(f *multipart.Form) *multipart.Form
function CloneMultipartFileHeader (line 42) | func CloneMultipartFileHeader(fh *multipart.FileHeader) *multipart.FileH...
function CloneOrMakeHeader (line 47) | func CloneOrMakeHeader(hdr http.Header) http.Header
FILE: go/net/http/example/data.pb.go
constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type NowRequest (line 24) | type NowRequest struct
method Reset (line 32) | func (x *NowRequest) Reset() {
method String (line 41) | func (x *NowRequest) String() string {
method ProtoMessage (line 45) | func (*NowRequest) ProtoMessage() {}
method ProtoReflect (line 47) | func (x *NowRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 60) | func (*NowRequest) Descriptor() ([]byte, []int) {
method GetRequestId (line 64) | func (x *NowRequest) GetRequestId() string {
type NowResponse (line 71) | type NowResponse struct
method Reset (line 80) | func (x *NowResponse) Reset() {
method String (line 89) | func (x *NowResponse) String() string {
method ProtoMessage (line 93) | func (*NowResponse) ProtoMessage() {}
method ProtoReflect (line 95) | func (x *NowResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 108) | func (*NowResponse) Descriptor() ([]byte, []int) {
method GetRequestId (line 112) | func (x *NowResponse) GetRequestId() string {
method GetDate (line 119) | func (x *NowResponse) GetDate() string {
function file_go_net_grpc_example_data_proto_rawDescGZIP (line 157) | func file_go_net_grpc_example_data_proto_rawDescGZIP() []byte {
function init (line 179) | func init() { file_go_net_grpc_example_data_proto_init() }
function file_go_net_grpc_example_data_proto_init (line 180) | func file_go_net_grpc_example_data_proto_init() {
FILE: go/net/http/example/http_client.repository_test.go
function TestNowPbJson (line 13) | func TestNowPbJson(t *testing.T) {
function TestNowPb (line 44) | func TestNowPb(t *testing.T) {
FILE: go/net/http/http_client.do.go
method get (line 33) | func (c *Client) get(ctx context.Context, url string) (*http.Response, e...
method post (line 37) | func (c *Client) post(ctx context.Context, url string, contentType strin...
method put (line 44) | func (c *Client) put(ctx context.Context, url string, contentType string...
method HttpDo (line 51) | func (c *Client) HttpDo(ctx context.Context, method string, url string, ...
method Do (line 77) | func (c *Client) Do(ctx context.Context, req *http.Request) (*http.Respo...
FILE: go/net/http/http_client.go
type Client (line 38) | type Client struct
method Get (line 174) | func (c *Client) Get(ctx context.Context, url string) ([]byte, error) {
method Post (line 189) | func (c *Client) Post(
method Put (line 199) | func (c *Client) Put(
method PostJson (line 209) | func (c *Client) PostJson(
method PostPb (line 219) | func (c *Client) PostPb(
method PostJsonWithAuthorize (line 229) | func (c *Client) PostJsonWithAuthorize(
method PostReader (line 240) | func (c *Client) PostReader(
method PutReader (line 250) | func (c *Client) PutReader(
method HttpReader (line 260) | func (c *Client) HttpReader(
method logf (line 284) | func (c *Client) logf(format string, args ...interface{}) {
function NewClient (line 86) | func NewClient(options ...ClientOption) (*Client, error) {
FILE: go/net/http/http_client.option.go
function WithTimeout (line 29) | func WithTimeout(timeout time.Duration) ClientOption {
function WithResonseHeaderTimeout (line 35) | func WithResonseHeaderTimeout(responseHeaderTimeout time.Duration) Clien...
function WithMaxIdleConns (line 42) | func WithMaxIdleConns(maxIdleConns int) ClientOption {
function WithIdleConnTimeout (line 48) | func WithIdleConnTimeout(idleConnTimeout time.Duration) ClientOption {
function WithDisableKeepAlives (line 54) | func WithDisableKeepAlives(disableKeepAlives bool) ClientOption {
function WithProxyURL (line 61) | func WithProxyURL(proxyURL string) ClientOption {
function WithTargetHost (line 69) | func WithTargetHost(target string) ClientOption {
function WithProxyHost (line 76) | func WithProxyHost(target string) ClientOption {
function WithLogger (line 83) | func WithLogger(l *log.Logger) ClientOption {
FILE: go/net/http/http_client.repository.factory.go
type FactoryConfigFunc (line 33) | type FactoryConfigFunc
type FactoryConfig (line 35) | type FactoryConfig struct
method ApplyOptions (line 44) | func (fc *FactoryConfig) ApplyOptions(configFuncs ...FactoryConfigFunc...
method Validate (line 56) | func (fc FactoryConfig) Validate() error {
type ProtoMessage (line 64) | type ProtoMessage interface
type Repository (line 68) | type Repository struct
function newRepository (line 79) | func newRepository[REQ any, RESP any](ctx context.Context, fc FactoryCon...
type Factory (line 92) | type Factory struct
function NewFactory (line 96) | func NewFactory[REQ any, RESP any](fc FactoryConfig, configFuncs ...Fact...
method NewClient (line 110) | func (f Factory[REQ, RESP]) NewClient(ctx context.Context) (*Repository[...
FILE: go/net/http/http_client.repository.go
method PostPbJson (line 36) | func (r *Repository[REQ, RESP]) PostPbJson(ctx context.Context, req *REQ...
method PostPbJsonWithUrl (line 40) | func (r *Repository[REQ, RESP]) PostPbJsonWithUrl(ctx context.Context, u...
method PostPb (line 94) | func (r *Repository[REQ, RESP]) PostPb(ctx context.Context, req *REQ) (r...
FILE: go/net/http/http_client_option.go
type ClientOption (line 25) | type ClientOption interface
type EmptyClientOption (line 33) | type EmptyClientOption struct
method apply (line 35) | func (EmptyClientOption) apply(*Client) {}
type ClientOptionFunc (line 39) | type ClientOptionFunc
method apply (line 41) | func (f ClientOptionFunc) apply(do *Client) {
function _ClientOptionWithDefault (line 46) | func _ClientOptionWithDefault() ClientOption {
method ApplyOptions (line 51) | func (o *Client) ApplyOptions(options ...ClientOption) *Client {
FILE: go/net/http/http_client_proxy.go
function RequestWithTargetHost (line 30) | func RequestWithTargetHost(req *http.Request, target string) error {
function NewClientWithTargetHost (line 45) | func NewClientWithTargetHost(target string, opts ...ClientOption) *Client {
FILE: go/net/http/http_client_test.go
function TestHttpClientGet (line 33) | func TestHttpClientGet(t *testing.T) {
function TestHttpClientGetWithProxy (line 67) | func TestHttpClientGetWithProxy(t *testing.T) {
function TestHttpClientPost (line 98) | func TestHttpClientPost(t *testing.T) {
FILE: go/net/http/http_error.go
function ErrorFromHttp (line 29) | func ErrorFromHttp(code int) error {
FILE: go/net/http/http_handler_chain.option.go
type HandlerChainOption (line 25) | type HandlerChainOption interface
type EmptyHandlerChainOption (line 33) | type EmptyHandlerChainOption struct
method apply (line 35) | func (EmptyHandlerChainOption) apply(*HandlerChain) {}
type HandlerChainOptionFunc (line 39) | type HandlerChainOptionFunc
method apply (line 41) | func (f HandlerChainOptionFunc) apply(do *HandlerChain) {
function _HandlerChainOptionWithDefault (line 46) | func _HandlerChainOptionWithDefault() HandlerChainOption {
method ApplyOptions (line 51) | func (o *HandlerChain) ApplyOptions(options ...HandlerChainOption) *Hand...
FILE: go/net/http/http_handler_interceptor.go
type HandlerInterceptor (line 30) | type HandlerInterceptor struct
function NewHandlerInterceptor (line 35) | func NewHandlerInterceptor(opts ...HandlerInterceptorOption) *HandlerInt...
type HandlerChain (line 41) | type HandlerChain struct
method WrapH (line 56) | func (c *HandlerChain) WrapH(next http.Handler) http.Handler {
function NewHandlerChain (line 49) | func NewHandlerChain(opts ...HandlerChainOption) *HandlerChain {
FILE: go/net/http/http_handler_interceptor.option.go
type HandlerInterceptorOption (line 25) | type HandlerInterceptorOption interface
type EmptyHandlerInterceptorOption (line 33) | type EmptyHandlerInterceptorOption struct
method apply (line 35) | func (EmptyHandlerInterceptorOption) apply(*HandlerInterceptor) {}
type HandlerInterceptorOptionFunc (line 39) | type HandlerInterceptorOptionFunc
method apply (line 41) | func (f HandlerInterceptorOptionFunc) apply(do *HandlerInterceptor) {
function _HandlerInterceptorOptionWithDefault (line 46) | func _HandlerInterceptorOptionWithDefault() HandlerInterceptorOption {
method ApplyOptions (line 51) | func (o *HandlerInterceptor) ApplyOptions(options ...HandlerInterceptorO...
FILE: go/net/http/http_host_context.go
type hostContextKey (line 32) | type hostContextKey struct
type Host (line 34) | type Host struct
function FromContextHost (line 41) | func FromContextHost(ctx context.Context) *Host {
function WithContextHost (line 46) | func WithContextHost(ctx context.Context, host *Host) context.Context {
function ParseTargetUrl (line 53) | func ParseTargetUrl(host string) (*url.URL, error) {
FILE: go/net/http/http_proxy_context.go
type proxyContextKey (line 32) | type proxyContextKey struct
type Proxy (line 34) | type Proxy struct
function FromContextProxy (line 41) | func FromContextProxy(ctx context.Context) *Proxy {
function WithContextProxy (line 46) | func WithContextProxy(ctx context.Context, proxy *Proxy) context.Context {
function ParseProxyUrl (line 53) | func ParseProxyUrl(proxy string) (*url.URL, error) {
FILE: go/net/http/http_request_id.go
constant DefaultHTTPRequestIDKey (line 33) | DefaultHTTPRequestIDKey = "X-Request-ID"
constant DefaultHTTPTraceIDKey (line 34) | DefaultHTTPTraceIDKey = "X-Traceid"
function ExtractRequestIdHTTPAndContext (line 37) | func ExtractRequestIdHTTPAndContext(r *http.Request) string {
function ExtractTraceIdHTTPAndContext (line 41) | func ExtractTraceIdHTTPAndContext(r *http.Request) string {
function ExtractHTTPAndContext (line 45) | func ExtractHTTPAndContext(r *http.Request, key string) string {
function ExtractFromHTTP (line 53) | func ExtractFromHTTP(r *http.Request, key string) string {
function SetPairContext (line 98) | func SetPairContext(r *http.Request, key, value string) *http.Request {
function SetRequestIdContext (line 105) | func SetRequestIdContext(r *http.Request, requestID string) *http.Request {
function SetTraceIdContext (line 109) | func SetTraceIdContext(r *http.Request, traceID string) *http.Request {
FILE: go/net/http/http_round_trip.go
type RoundTripFunc (line 26) | type RoundTripFunc
method RoundTrip (line 28) | func (f RoundTripFunc) RoundTrip(req *http.Request) (resp *http.Respon...
FILE: go/net/http/http_transport.host.go
function RequestWithContextTargetHost (line 31) | func RequestWithContextTargetHost(req *http.Request, target *Host) *http...
function TargetHostFuncFromContext (line 38) | func TargetHostFuncFromContext(req *http.Request) error {
function RoundTripperWithTarget (line 67) | func RoundTripperWithTarget(rt http.RoundTripper) http.RoundTripper {
FILE: go/net/http/http_transport.proxy.go
function RequestWithContextProxy (line 35) | func RequestWithContextProxy(req *http.Request, proxy *Proxy) *http.Requ...
function ProxyFuncFromContextOrEnvironment (line 42) | func ProxyFuncFromContextOrEnvironment(req *http.Request) (*url.URL, err...
FILE: go/net/http/ip.go
function GetIPFromRequest (line 33) | func GetIPFromRequest(r *http.Request) (net.IP, error) {
FILE: go/net/http/response_writer.go
type ResponseWriterWrapper (line 31) | type ResponseWriterWrapper struct
method Write (line 44) | func (rww *ResponseWriterWrapper) Write(buf []byte) (int, error) {
method Header (line 50) | func (rww *ResponseWriterWrapper) Header() http.Header {
method WriteHeader (line 55) | func (rww *ResponseWriterWrapper) WriteHeader(statusCode int) {
method BodyBytes (line 62) | func (rww *ResponseWriterWrapper) BodyBytes() []byte {
method StatusCode (line 67) | func (rww *ResponseWriterWrapper) StatusCode() int {
method String (line 72) | func (rww *ResponseWriterWrapper) String() string {
function NewResponseWriterWrapper (line 37) | func NewResponseWriterWrapper(w http.ResponseWriter) *ResponseWriterWrap...
FILE: go/net/ip.go
function scoreAddr (line 44) | func scoreAddr(iface net.Interface, addr net.Addr) (int, net.IP) {
function GetHostIP (line 69) | func GetHostIP() (net.IP, error) {
function GetLocalFirstIP (line 101) | func GetLocalFirstIP() (string, error) {
function GetLocalIPs (line 113) | func GetLocalIPs() ([]string, error) {
function GetLocalAddrs (line 130) | func GetLocalAddrs() ([]*net.IPNet, error) {
function IsIPv4 (line 148) | func IsIPv4(netIP net.IP) bool {
function IsIPv4String (line 152) | func IsIPv4String(ip string) bool {
function LookupHostIPv4 (line 157) | func LookupHostIPv4(host string) (addrs []string, err error) {
function LookupHostIPv4WithContext (line 161) | func LookupHostIPv4WithContext(ctx context.Context, host string) (addrs ...
function SplitHostIntPort (line 177) | func SplitHostIntPort(s string) (string, int, error) {
function ParseTarget (line 198) | func ParseTarget(target, defaultPort string) (host, port string, err err...
function GetServerName (line 227) | func GetServerName() string {
function GetServerId (line 237) | func GetServerId() uint32 {
FILE: go/net/ip_test.go
function TestGetLocalAddrs (line 32) | func TestGetLocalAddrs(t *testing.T) {
function TestGetLocalIPs (line 41) | func TestGetLocalIPs(t *testing.T) {
function TestGetLocalFirstIP (line 50) | func TestGetLocalFirstIP(t *testing.T) {
function TestGetHostIP (line 59) | func TestGetHostIP(t *testing.T) {
function TestIsIPv4String (line 68) | func TestIsIPv4String(t *testing.T) {
function TestLookupHost (line 74) | func TestLookupHost(t *testing.T) {
function TestLookupHostIPv4 (line 83) | func TestLookupHostIPv4(t *testing.T) {
function TestGetServerName (line 92) | func TestGetServerName(t *testing.T) {
FILE: go/net/mac.go
function GetLocalFirstMac (line 29) | func GetLocalFirstMac() (string, error) {
function GetLocalMacs (line 51) | func GetLocalMacs() ([]string, error) {
FILE: go/net/mac_test.go
function TestGetLocalMacs (line 30) | func TestGetLocalMacs(t *testing.T) {
function TestGetLocalFirstMac (line 39) | func TestGetLocalFirstMac(t *testing.T) {
FILE: go/net/parse.go
function ParseIP (line 31) | func ParseIP(s string) net.IP {
function parseIPv4 (line 44) | func parseIPv4(s string) net.IP {
function parseIPv6 (line 83) | func parseIPv6(s string) (ip net.IP) {
constant big (line 184) | big = 0xFFFFFF
function dtoi (line 188) | func dtoi(s string) (n int, i int, ok bool) {
function xtoi (line 204) | func xtoi(s string) (n int, i int, ok bool) {
FILE: go/net/resolver/build.go
type Address (line 35) | type Address struct
type State (line 54) | type State struct
type ClientConn (line 66) | type ClientConn interface
type ResolverBuildOptions (line 75) | type ResolverBuildOptions struct
type Builder (line 96) | type Builder interface
FILE: go/net/resolver/build.option.go
function WithBuildDialer (line 29) | func WithBuildDialer(dialer func(context.Context, string) (net.Conn, err...
FILE: go/net/resolver/build_option.go
type ResolverBuildOption (line 25) | type ResolverBuildOption interface
type EmptyResolverBuildOption (line 33) | type EmptyResolverBuildOption struct
method apply (line 35) | func (EmptyResolverBuildOption) apply(*ResolverBuildOptions) {}
type ResolverBuildOptionFunc (line 39) | type ResolverBuildOptionFunc
method apply (line 41) | func (f ResolverBuildOptionFunc) apply(do *ResolverBuildOptions) {
function _ResolverBuildOptionWithDefault (line 46) | func _ResolverBuildOptionWithDefault() ResolverBuildOption {
method ApplyOptions (line 51) | func (o *ResolverBuildOptions) ApplyOptions(options ...ResolverBuildOpti...
FILE: go/net/resolver/dns/dns_resolver.go
function init (line 48) | func init() {
constant defaultPort (line 53) | defaultPort = "443"
constant defaultDNSSvrPort (line 54) | defaultDNSSvrPort = "53"
function NewBuilder (line 86) | func NewBuilder(opts ...dnsBuilderOption) resolver.Builder {
type dnsBuilder (line 96) | type dnsBuilder struct
method Build (line 103) | func (b *dnsBuilder) Build(target resolver.Target, opts ...resolver.Re...
method Scheme (line 150) | func (b *dnsBuilder) Scheme() string {
type netResolver (line 154) | type netResolver interface
type deadResolver (line 161) | type deadResolver struct
method ResolveOne (line 165) | func (d deadResolver) ResolveOne(opts ...resolver.ResolveOneOption) (r...
method ResolveAll (line 185) | func (d deadResolver) ResolveAll(opts ...resolver.ResolveAllOption) ([...
method ResolveNow (line 217) | func (deadResolver) ResolveNow(opts ...resolver.ResolveNowOption) {}
method Close (line 219) | func (deadResolver) Close() {}
type dnsResolver (line 222) | type dnsResolver struct
method ResolveOne (line 242) | func (d *dnsResolver) ResolveOne(opts ...resolver.ResolveOneOption) (r...
method ResolveAll (line 262) | func (d *dnsResolver) ResolveAll(opts ...resolver.ResolveAllOption) ([...
method ResolveNow (line 300) | func (d *dnsResolver) ResolveNow(opts ...resolver.ResolveNowOption) {
method Close (line 308) | func (d *dnsResolver) Close() {
method watcher (line 313) | func (d *dnsResolver) watcher() {
method lookupSRV (line 354) | func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) {
method lookupHost (line 400) | func (d *dnsResolver) lookupHost() ([]resolver.Address, error) {
function handleDNSError (line 387) | func handleDNSError(err error, lookupType string) error {
function formatIP (line 421) | func formatIP(addr string) (addrIP string, ok bool) {
FILE: go/net/resolver/dns/dns_resolver_builder.option.go
function WithSyncInterval (line 28) | func WithSyncInterval(syncInterval time.Duration) dnsBuilderOption {
FILE: go/net/resolver/dns/dns_resolver_builder_option.go
type dnsBuilderOption (line 25) | type dnsBuilderOption interface
type EmptydnsBuilderOption (line 33) | type EmptydnsBuilderOption struct
method apply (line 35) | func (EmptydnsBuilderOption) apply(*dnsBuilder) {}
type dnsBuilderOptionFunc (line 39) | type dnsBuilderOptionFunc
method apply (line 41) | func (f dnsBuilderOptionFunc) apply(do *dnsBuilder) {
function _dnsBuilderOptionWithDefault (line 46) | func _dnsBuilderOptionWithDefault() dnsBuilderOption {
method ApplyOptions (line 51) | func (o *dnsBuilder) ApplyOptions(options ...dnsBuilderOption) *dnsBuild...
FILE: go/net/resolver/passthrough/passthrough.go
constant scheme (line 28) | scheme = "passthrough"
type passthroughBuilder (line 30) | type passthroughBuilder struct
method Build (line 32) | func (*passthroughBuilder) Build(target resolver.Target, opts ...resol...
method Scheme (line 41) | func (*passthroughBuilder) Scheme() string {
type passthroughResolver (line 45) | type passthroughResolver struct
method ResolveOne (line 49) | func (r *passthroughResolver) ResolveOne(opts ...resolver.ResolveOneOp...
method ResolveAll (line 53) | func (r *passthroughResolver) ResolveAll(opts ...resolver.ResolveAllOp...
method ResolveNow (line 57) | func (r *passthroughResolver) ResolveNow(opts ...resolver.ResolveNowOp...
method Close (line 59) | func (*passthroughResolver) Close() {}
function init (line 61) | func init() {
FILE: go/net/resolver/register.reslover.go
function Register (line 41) | func Register(b Builder) {
function Get (line 57) | func Get(scheme string) Builder {
function GetDefault (line 67) | func GetDefault() Builder {
function getResolver (line 77) | func getResolver(target string) Resolver {
function setResolver (line 87) | func setResolver(target string, r Resolver) {
function SetDefaultScheme (line 106) | func SetDefaultScheme(scheme string) {
function GetDefaultScheme (line 111) | func GetDefaultScheme() string {
FILE: go/net/resolver/resolve.all.option.go
function WithIPTypeForResolveAll (line 24) | func WithIPTypeForResolveAll(ipType Resolver_IPType) ResolveAllOptionFunc {
FILE: go/net/resolver/resolve.all_option.go
type ResolveAllOption (line 25) | type ResolveAllOption interface
type EmptyResolveAllOption (line 33) | type EmptyResolveAllOption struct
method apply (line 35) | func (EmptyResolveAllOption) apply(*ResolveAllOptions) {}
type ResolveAllOptionFunc (line 39) | type ResolveAllOptionFunc
method apply (line 41) | func (f ResolveAllOptionFunc) apply(do *ResolveAllOptions) {
function _ResolveAllOptionWithDefault (line 46) | func _ResolveAllOptionWithDefault() ResolveAllOption {
method ApplyOptions (line 51) | func (o *ResolveAllOptions) ApplyOptions(options ...ResolveAllOption) *R...
FILE: go/net/resolver/resolve.now_option.go
type ResolveNowOption (line 25) | type ResolveNowOption interface
type EmptyResolveNowOption (line 33) | type EmptyResolveNowOption struct
method apply (line 35) | func (EmptyResolveNowOption) apply(*ResolveNowOptions) {}
type ResolveNowOptionFunc (line 39) | type ResolveNowOptionFunc
method apply (line 41) | func (f ResolveNowOptionFunc) apply(do *ResolveNowOptions) {
function _ResolveNowOptionWithDefault (line 46) | func _ResolveNowOptionWithDefault() ResolveNowOption {
method ApplyOptions (line 51) | func (o *ResolveNowOptions) ApplyOptions(options ...ResolveNowOption) *R...
FILE: go/net/resolver/resolve.one.option.go
function WithPickMode (line 24) | func WithPickMode(mode Resolver_PickMode) ResolveOneOptionFunc {
function WithIPTypeForResolverOne (line 30) | func WithIPTypeForResolverOne(ipType Resolver_IPType) ResolveOneOptionFu...
FILE: go/net/resolver/resolve.one_option.go
type ResolveOneOption (line 25) | type ResolveOneOption interface
type EmptyResolveOneOption (line 33) | type EmptyResolveOneOption struct
method apply (line 35) | func (EmptyResolveOneOption) apply(*ResolveOneOptions) {}
type ResolveOneOptionFunc (line 39) | type ResolveOneOptionFunc
method apply (line 41) | func (f ResolveOneOptionFunc) apply(do *ResolveOneOptions) {
function _ResolveOneOptionWithDefault (line 46) | func _ResolveOneOptionWithDefault() ResolveOneOption {
method ApplyOptions (line 51) | func (o *ResolveOneOptions) ApplyOptions(options ...ResolveOneOption) *R...
FILE: go/net/resolver/resolve/resolve.go
function ResolveOne (line 33) | func ResolveOne(ctx context.Context, target string, opts ...resolver.Res...
function ResolveAll (line 41) | func ResolveAll(ctx context.Context, target string, opts ...resolver.Res...
FILE: go/net/resolver/resolver.go
type ResolveNowOptions (line 31) | type ResolveNowOptions struct
type Resolver (line 35) | type Resolver interface
type Resolver_PickMode (line 50) | type Resolver_PickMode
constant Resolver_pick_mode_random (line 53) | Resolver_pick_mode_random Resolver_PickMode = 0
constant Resolver_pick_mode_first (line 54) | Resolver_pick_mode_first Resolver_PickMode = 1
type Resolver_IPType (line 57) | type Resolver_IPType
constant Resolver_ip_type_all (line 60) | Resolver_ip_type_all Resolver_IPType = 0
constant Resolver_ip_type_v4 (line 61) | Resolver_ip_type_v4 Resolver_IPType = 1
constant Resolver_ip_type_v6 (line 62) | Resolver_ip_type_v6 Resolver_IPType = 2
type ResolveOneOptions (line 65) | type ResolveOneOptions struct
type ResolveAllOptions (line 70) | type ResolveAllOptions struct
function GetResolver (line 74) | func GetResolver(ctx context.Context, target string, opts ...ResolverBui...
FILE: go/net/resolver/resolver_test.go
function TestResolveOne (line 37) | func TestResolveOne(t *testing.T) {
function TestResolveAll (line 81) | func TestResolveAll(t *testing.T) {
FILE: go/net/resolver/target.go
type Target (line 46) | type Target struct
function ParseTarget (line 57) | func ParseTarget(target string) (Target, error) {
FILE: go/net/resolver/unix/unix.go
constant unixScheme (line 30) | unixScheme = "unix"
constant unixAbstractScheme (line 31) | unixAbstractScheme = "unix-abstract"
type builder (line 33) | type builder struct
method Build (line 37) | func (b *builder) Build(target resolver.Target, opts ...resolver.Resol...
method Scheme (line 55) | func (b *builder) Scheme() string {
type nopResolver (line 59) | type nopResolver struct
method ResolveOne (line 63) | func (*nopResolver) ResolveOne(opts ...resolver.ResolveOneOption) (res...
method ResolveAll (line 67) | func (*nopResolver) ResolveAll(opts ...resolver.ResolveAllOption) ([]r...
method ResolveNow (line 71) | func (*nopResolver) ResolveNow(opts ...resolver.ResolveNowOption) {}
method Close (line 73) | func (*nopResolver) Close() {}
function init (line 75) | func init() {
FILE: go/net/url/url.go
type Client (line 33) | type Client struct
method Encode (line 52) | func (c *Client) Encode(data interface{}) (string, error) {
method encode (line 71) | func (c *Client) encode(rv reflect.Value) (string, error) {
method build (line 80) | func (c *Client) build(
method appendKeyValue (line 157) | func (c *Client) appendKeyValue(key string, rv reflect.Value, parentKi...
function New (line 43) | func New(ctx context.Context, options ...ClientOption) (*Client, error) {
function isEmptyValue (line 181) | func isEmptyValue(v reflect.Value) bool {
function repackArrayQueryKey (line 205) | func repackArrayQueryKey(key string) string {
FILE: go/net/url/url.resolve.go
function ResolveWithTarget (line 31) | func ResolveWithTarget(ctx context.Context, u *url.URL, target string) (...
FILE: go/net/url/url_codec.go
type UrlCodec (line 26) | type UrlCodec interface
type DefaultUrlCodec (line 32) | type DefaultUrlCodec struct
method Escape (line 34) | func (u DefaultUrlCodec) Escape(s string) string {
method UnEscape (line 38) | func (u DefaultUrlCodec) UnEscape(s string) (string, error) {
FILE: go/net/url/url_option.go
type ClientOption (line 25) | type ClientOption interface
type EmptyClientOption (line 33) | type EmptyClientOption struct
method apply (line 35) | func (EmptyClientOption) apply(*Client) {}
type ClientOptionFunc (line 39) | type ClientOptionFunc
method apply (line 41) | func (f ClientOptionFunc) apply(do *Client) {
function _ClientOptionWithDefault (line 46) | func _ClientOptionWithDefault() ClientOption {
method ApplyOptions (line 51) | func (o *Client) ApplyOptions(options ...ClientOption) *Client {
FILE: go/net/url/url_test.go
function TestUrlEncode (line 32) | func TestUrlEncode(t *testing.T) {
FILE: go/net/url/value.go
type Value (line 54) | type Value interface
type boolValue (line 59) | type boolValue struct
method Encode (line 61) | func (e boolValue) Encode(value reflect.Value) string {
type intValue (line 68) | type intValue struct
method Encode (line 70) | func (e intValue) Encode(value reflect.Value) string {
type uintValue (line 74) | type uintValue struct
method Encode (line 76) | func (e uintValue) Encode(value reflect.Value) string {
type floatValue (line 80) | type floatValue struct
method Encode (line 82) | func (e floatValue) Encode(value reflect.Value) string {
type stringValue (line 86) | type stringValue struct
method Encode (line 88) | func (e stringValue) Encode(value reflect.Value) string {
function getEncoder (line 92) | func getEncoder(kind reflect.Kind) Value {
FILE: go/os/env.go
function GetEnvAsStringOrFallback (line 34) | func GetEnvAsStringOrFallback(key, defaultValue string) string {
function GetEnvAsIntOrFallback (line 43) | func GetEnvAsIntOrFallback(key string, defaultValue int) (int, error) {
function GetEnvAsFloat64OrFallback (line 56) | func GetEnvAsFloat64OrFallback(key string, defaultValue float64) (float6...
FILE: go/os/env_test.go
function TestGetEnvAsStringOrFallback (line 33) | func TestGetEnvAsStringOrFallback(t *testing.T) {
function TestUUID (line 49) | func TestUUID(t *testing.T) {
function TestGetEnvAsIntOrFallback (line 54) | func TestGetEnvAsIntOrFallback(t *testing.T) {
function TestGetEnvAsFloat64OrFallback (line 90) | func TestGetEnvAsFloat64OrFallback(t *testing.T) {
FILE: go/os/exec/exec.go
type CommandBuilder (line 35) | type CommandBuilder struct
method Exec (line 53) | func (c *CommandBuilder) Exec(cmdName string,
function NewCommandBuilder (line 43) | func NewCommandBuilder(
function Exec (line 60) | func Exec(
FILE: go/os/exec/exec.options.go
function WithTimeout (line 27) | func WithTimeout(timeout time.Duration) CommandBuilderOption {
FILE: go/os/exec/exec_options.go
type CommandBuilderOption (line 26) | type CommandBuilderOption interface
type EmptyCommandBuilderOption (line 34) | type EmptyCommandBuilderOption struct
method apply (line 36) | func (EmptyCommandBuilderOption) apply(*CommandBuilder) {}
type CommandBuilderOptionFunc (line 40) | type CommandBuilderOptionFunc
method apply (line 42) | func (f CommandBuilderOptionFunc) apply(do *CommandBuilder) {
function _CommandBuilderOptionWithDefault (line 47) | func _CommandBuilderOptionWithDefault() CommandBuilderOption {
method ApplyOptions (line 53) | func (o *CommandBuilder) ApplyOptions(
FILE: go/os/exec/exec_test.go
function TestExec (line 32) | func TestExec(t *testing.T) {
function TestExecTimeout (line 42) | func TestExecTimeout(t *testing.T) {
FILE: go/os/file.go
function PathExist (line 31) | func PathExist(path string) (bool, error) {
function IsDir (line 43) | func IsDir(path string) (bool, error) {
function IsHidden (line 52) | func IsHidden(path string) (bool, error) {
function MakeDirAll (line 75) | func MakeDirAll(name string) error {
function MakeDir (line 79) | func MakeDir(name string) error {
function MakeTempDirAll (line 85) | func MakeTempDirAll(name, pattern string) (string, error) {
function OpenAll (line 97) | func OpenAll(path string, flag int, perm os.FileMode) (*os.File, error) {
function OpenFile (line 118) | func OpenFile(path string, appended bool) (file *os.File, err error) {
function SameFile (line 130) | func SameFile(fi1, fi2 string) bool {
function SymLink (line 144) | func SymLink(oldname, newname string) error {
function ReadDirNames (line 197) | func ReadDirNames(path string, filterHiddenFile bool) ([]string, error) {
function ReadDirSubDirNames (line 230) | func ReadDirSubDirNames(path string, filterHiddenFile bool) ([]string, e...
function ReadDirFileNames (line 249) | func ReadDirFileNames(path string, filterHiddenFile bool) ([]string, err...
FILE: go/os/file_test.go
function TestOpenAll (line 37) | func TestOpenAll(t *testing.T) {
function TestSameFile (line 70) | func TestSameFile(t *testing.T) {
function TestSymLink (line 98) | func TestSymLink(t *testing.T) {
function TestPath (line 128) | func TestPath(t *testing.T) {
function TestReadDirNames (line 139) | func TestReadDirNames(t *testing.T) {
function TestReadSubDirs (line 150) | func TestReadSubDirs(t *testing.T) {
function TestReadDirFileNames (line 160) | func TestReadDirFileNames(t *testing.T) {
function TestMakeTempDirAll (line 171) | func TestMakeTempDirAll(t *testing.T) {
FILE: go/os/getwd.go
function Getwd (line 26) | func Getwd() (string, error) {
FILE: go/os/getwd_test.go
function TestGetwd (line 31) | func TestGetwd(t *testing.T) {
FILE: go/os/proc.go
function GetPidsByName (line 35) | func GetPidsByName(
function GetProcIdWithRand (line 62) | func GetProcIdWithRand() string {
function GetProcId (line 67) | func GetProcId() string {
FILE: go/os/proc_darwin.go
function ExistPid (line 27) | func ExistPid(pid int) bool {
FILE: go/os/proc_linux.go
function ExistPid (line 31) | func ExistPid(pid int) bool {
FILE: go/os/proc_test.go
function TestGetPidsByName (line 31) | func TestGetPidsByName(t *testing.T) {
function TestExistPid (line 41) | func TestExistPid(t *testing.T) {
FILE: go/os/remove_file.go
function RemoveBatch (line 31) | func RemoveBatch(filenames []string) error {
function RemoveWithGlob (line 43) | func RemoveWithGlob(pattern string) error {
FILE: go/os/term/term.go
function TerminalSize (line 34) | func TerminalSize(w io.Writer) (int, int, error) {
FILE: go/os/value.go
function GetValueOrFallback (line 3) | func GetValueOrFallback[T comparable](v, defaultValue T) T {
FILE: go/os/value_test.go
function TestGetOrFallback (line 31) | func TestGetOrFallback(t *testing.T) {
FILE: go/path/filepath/match.go
function Glob (line 29) | func Glob(pattern string) (matches []string, err error) {
FILE: go/path/filepath/path.go
function GetParentRelPath (line 29) | func GetParentRelPath(filePath string) string {
function GetParentRelDir (line 35) | func GetParentRelDir(filePath string) string {
function LastChar (line 40) | func LastChar(str string) uint8 {
function JoinPaths (line 50) | func JoinPaths(rootPath, relativePath string) (string, error) {
function CanonicalizePath (line 69) | func CanonicalizePath(path string) (string, error) {
FILE: go/path/filepath/path_test.go
function TestGetParentRelPath (line 33) | func TestGetParentRelPath(t *testing.T) {
function TestAbsPath (line 58) | func TestAbsPath(t *testing.T) {
function TestJoinPaths (line 85) | func TestJoinPaths(t *testing.T) {
FILE: go/reflect/array.go
function ArrayAllTagsVaules (line 28) | func ArrayAllTagsVaules(req interface{}, key string) []map[string]interf...
FILE: go/reflect/array_test.go
function TestPointerStructArrayAllTagsValues (line 30) | func TestPointerStructArrayAllTagsValues(t *testing.T) {
function TestStructArrayAllTagsValues (line 52) | func TestStructArrayAllTagsValues(t *testing.T) {
FILE: go/reflect/error.go
type ErrUnsupportedType (line 27) | type ErrUnsupportedType struct
method Error (line 37) | func (e ErrUnsupportedType) Error() string {
function NewErrUnsupportedType (line 32) | func NewErrUnsupportedType(valueType string) ErrUnsupportedType {
FILE: go/reflect/id.go
type IdRetriever (line 29) | type IdRetriever interface
function RetrieveId (line 33) | func RetrieveId(req interface{}, key string) string {
function TrySetId (line 46) | func TrySetId(req interface{}, key, id string) {
FILE: go/reflect/struct.go
function indirectStruct (line 36) | func indirectStruct(req interface{}) (reflect.Value, bool) {
function RetrieveStructField (line 51) | func RetrieveStructField(req interface{}, name string) string {
function TrySetStructFiled (line 70) | func TrySetStructFiled(req interface{}, name, value string) {
function AllFieldTags (line 86) | func AllFieldTags(req interface{}, key string) []string {
function NonzeroFieldTags (line 92) | func NonzeroFieldTags(req interface{}, key string) []string {
function fieldTags (line 99) | func fieldTags(req interface{}, key string, nonzero bool) []string {
function AllTagsValues (line 111) | func AllTagsValues(req interface{}, key string) map[string]interface{} {
function fieldTagsValues (line 118) | func fieldTagsValues(req interface{}, key string, nonzero bool) map[stri...
FILE: go/reflect/struct_test.go
function TestRetrieveStructField (line 32) | func TestRetrieveStructField(t *testing.T) {
function TestTrySetStructField (line 48) | func TestTrySetStructField(t *testing.T) {
function TestNonzeroFieldTags (line 64) | func TestNonzeroFieldTags(t *testing.T) {
function TestAllFieldTags (line 80) | func TestAllFieldTags(t *testing.T) {
function TestAllTagsValues (line 96) | func TestAllTagsValues(t *testing.T) {
FILE: go/reflect/truncate.go
constant DefaultTruncateThreshold (line 32) | DefaultTruncateThreshold = 1024
constant DefaultTruncatePrefix (line 34) | DefaultTruncatePrefix = 10
constant MaxTruncateDepth (line 36) | MaxTruncateDepth = 32
function TruncateBytes (line 39) | func TruncateBytes(v interface{}) interface{} {
function TruncateBytesWithThreshold (line 44) | func TruncateBytesWithThreshold(v interface{}, threshold, prefix int) in...
function TruncateBytesAndStrings (line 52) | func TruncateBytesAndStrings(v interface{}) interface{} {
function TruncateBytesAndStringsWithThreshold (line 57) | func TruncateBytesAndStringsWithThreshold(v interface{}, threshold, pref...
function Truncate (line 69) | func Truncate(v interface{}, f func(v interface{}) bool, threshold, pref...
function truncate (line 78) | func truncate(v reflect.Value, f func(v interface{}) bool, threshold, pr...
function truncateToLen (line 139) | func truncateToLen(oldValue reflect.Value, threshold, prefix int) {
function writeBytesLenToReflectValue (line 163) | func writeBytesLenToReflectValue(v reflect.Value, data []byte, prefix in...
function writeStringLenToReflectValue (line 181) | func writeStringLenToReflectValue(v reflect.Value, data string, prefix i...
function min (line 193) | func min(a, b int) int {
FILE: go/reflect/truncate_test.go
function TestTruncateBytes (line 35) | func TestTruncateBytes(t *testing.T) {
function TestTruncateBytesWithMaxArraySize (line 152) | func TestTruncateBytesWithMaxArraySize(t *testing.T) {
function TestTruncateBytesWithThreshold (line 199) | func TestTruncateBytesWithThreshold(t *testing.T) {
function TestTruncateBytesAndStrings (line 244) | func TestTruncateBytesAndStrings(t *testing.T) {
function TestTruncateWithMap (line 335) | func TestTruncateWithMap(t *testing.T) {
function TestTruncateWithCircularLikeStruct (line 390) | func TestTruncateWithCircularLikeStruct(t *testing.T) {
FILE: go/reflect/value.go
function IsZeroValue (line 76) | func IsZeroValue(v reflect.Value) bool {
function ReflectValue (line 118) | func ReflectValue(valueType string, value interface{}) (reflect.Value, e...
function reflectValue (line 130) | func reflectValue(valueType string, value interface{}) (reflect.Value, e...
function getBoolValue (line 195) | func getBoolValue(theType string, value interface{}) (bool, error) {
function getIntValue (line 204) | func getIntValue(theType string, value interface{}) (int64, error) {
function getUintValue (line 237) | func getUintValue(theType string, value interface{}) (uint64, error) {
function getFloatValue (line 275) | func getFloatValue(theType string, value interface{}) (float64, error) {
function getStringValue (line 295) | func getStringValue(theType string, value interface{}) (string, error) {
FILE: go/reflect/value_test.go
function TestReflectValue (line 30) | func TestReflectValue(t *testing.T) {
FILE: go/runtime/extern.go
function GetCallerWithSkip (line 33) | func GetCallerWithSkip(skip int) string {
function GetCaller (line 43) | func GetCaller() string {
function GetShortCaller (line 48) | func GetShortCaller() string {
function GetCallStackTrace (line 53) | func GetCallStackTrace() string {
FILE: go/runtime/extern_test.go
function TestGetCaller (line 30) | func TestGetCaller(t *testing.T) {
FILE: go/runtime/function.go
function NameOfFunction (line 29) | func NameOfFunction(f interface{}) string {
FILE: go/runtime/function_test.go
function testA (line 32) | func testA(a int) int {
function TestNameOfFunction (line 36) | func TestNameOfFunction(t *testing.T) {
FILE: go/runtime/goroutine.go
function GoroutineID (line 36) | func GoroutineID() uint64 {
function parseUintBytes (line 63) | func parseUintBytes(s []byte, base int, bitSize int) (n uint64, err erro...
function cutoff64 (line 150) | func cutoff64(base int) uint64 {
FILE: go/runtime/marshaler/jsonpb.marshaler.go
type JSONPb (line 33) | type JSONPb struct
method Marshal (line 90) | func (j *JSONPb) Marshal(v interface{}) ([]byte, error) {
method MarshaToStructpb (line 94) | func (j *JSONPb) MarshaToStructpb(v interface{}) (*structpb.Struct, er...
function NewDefaultJSONPb (line 45) | func NewDefaultJSONPb() *JSONPb {
function NewJSONPb (line 63) | func NewJSONPb(options ...JSONPbOption) *JSONPb {
FILE: go/runtime/marshaler/jsonpb.marshaler.option.go
function WithUseProtoNames (line 24) | func WithUseProtoNames(useProtoNames bool) JSONPbOption {
function WithUseEnumNumbers (line 30) | func WithUseEnumNumbers(useEnumNumbers bool) JSONPbOption {
function WithEmitUnpopulated (line 36) | func WithEmitUnpopulated(emitUnpopulated bool) JSONPbOption {
function WithDiscardUnknown (line 42) | func WithDiscardUnknown(discardUnknown bool) JSONPbOption {
function WithIndent (line 48) | func WithIndent(indent string) JSONPbOption {
function WithAllowPartial (line 54) | func WithAllowPartial(allowPartial bool) JSONPbOption {
FILE: go/runtime/marshaler/jsonpb.marshaler_option.go
type JSONPbOption (line 25) | type JSONPbOption interface
type EmptyJSONPbOption (line 33) | type EmptyJSONPbOption struct
method apply (line 35) | func (EmptyJSONPbOption) apply(*JSONPb) {}
type JSONPbOptionFunc (line 39) | type JSONPbOptionFunc
method apply (line 41) | func (f JSONPbOptionFunc) apply(do *JSONPb) {
function _JSONPbOptionWithDefault (line 46) | func _JSONPbOptionWithDefault() JSONPbOption {
method ApplyOptions (line 51) | func (o *JSONPb) ApplyOptions(options ...JSONPbOption) *JSONPb {
FILE: go/runtime/marshaler/proto.marshaler.go
type ProtoMarshaller (line 30) | type ProtoMarshaller struct
method ContentType (line 35) | func (*ProtoMarshaller) ContentType(_ interface{}) string {
FILE: go/runtime/meta.data.go
function GetMetadata (line 30) | func GetMetadata(ctx context.Context, key string) []string {
FILE: go/runtime/panic.go
function Recover (line 36) | func Recover() {
function logPanic (line 45) | func logPanic(r interface{}) {
function RecoverFromPanic (line 67) | func RecoverFromPanic(err *error) {
function Must (line 81) | func Must(err error) {
FILE: go/runtime/panic_test.go
function TestRecover (line 30) | func TestRecover(t *testing.T) {
function testRecoverFromPanic (line 35) | func testRecoverFromPanic() (err error) {
function TestRecoverFromPanic (line 40) | func TestRecoverFromPanic(t *testing.T) {
FILE: go/runtime/stack.go
function FormatStack (line 33) | func FormatStack() ([]byte, error) {
type prettyStack (line 38) | type prettyStack struct
method parse (line 41) | func (s prettyStack) parse(debugStack []byte) ([]byte, error) {
method decorateLine (line 82) | func (s prettyStack) decorateLine(line string, num int) (string, error) {
method decorateFuncCallLine (line 97) | func (s prettyStack) decorateFuncCallLine(line string, num int) (strin...
method decorateSourceLine (line 132) | func (s prettyStack) decorateSourceLine(line string, num int) (string,...
FILE: go/slices/slices.go
function Unique (line 29) | func Unique[S ~[]E, E comparable](s S) S {
function SliceIntersection (line 38) | func SliceIntersection[S ~[]E, E comparable](s1, s2 S) S {
function SliceDifference (line 56) | func SliceDifference[S ~[]E, E comparable](s1, s2 S) S {
function SliceWithCondition (line 75) | func SliceWithCondition[S ~[]E, E comparable](s1 S, cond func(e E) bool)...
function FirstOrDefaultZero (line 91) | func FirstOrDefaultZero[S ~[]E, E comparable](s S) E {
function RemoveEmpty (line 103) | func RemoveEmpty[S ~[]E, E comparable](s S) S {
FILE: go/slices/slices_test.go
function TestSliceIntersection (line 10) | func TestSliceIntersection(t *testing.T) {
function TestSliceDifference (line 42) | func TestSliceDifference(t *testing.T) {
function TestRemoveEmpty (line 68) | func TestRemoveEmpty(t *testing.T) {
function TestFirstOrDefaultZero (line 88) | func TestFirstOrDefaultZero(t *testing.T) {
FILE: go/strconv/atoi.go
function ParseUintOrFallback (line 28) | func ParseUintOrFallback(s string, base int, bitSize int, defaultValue u...
function ParseInt64Batch (line 37) | func ParseInt64Batch(m map[string]string) (map[string]int64, error) {
FILE: go/strconv/atoi_test.go
function TestParseInt64Batch (line 32) | func TestParseInt64Batch(t *testing.T) {
FILE: go/strconv/atonum.go
function ToFloat (line 29) | func ToFloat(str string) (float64, error) {
function ToInt (line 33) | func ToInt(str string) (int, error) {
function ToInt64 (line 37) | func ToInt64(str string) (int64, error) {
function ToUInt64 (line 41) | func ToUInt64(str string) (uint64, error) {
function ParseNumOrDefault (line 45) | func ParseNumOrDefault[T any](str string, _default T, convert func(strin...
function ParseNum (line 57) | func ParseNum[T any](str string, convert func(string) (T, error)) (T, er...
function ParseNums (line 65) | func ParseNums[T any](strs []string, convert func(string) (T, error)) ([...
FILE: go/strconv/atonum_test.go
function TestParseNumOrDefault (line 31) | func TestParseNumOrDefault(t *testing.T) {
function TestParseNum (line 53) | func TestParseNum(t *testing.T) {
function TestParseNums (line 81) | func TestParseNums(t *testing.T) {
FILE: go/strings/string_slice.go
function SliceUnique (line 30) | func SliceUnique(s ...string) []string {
function SliceIntersection (line 39) | func SliceIntersection(s1 []string, s2 []string) []string {
function SliceDifference (line 60) | func SliceDifference(s1 []string, s2 []string) []string {
function SliceWithCondition (line 82) | func SliceWithCondition(s1 []string, cond func(s2 string) bool) []string {
function RemoveEmpty (line 101) | func RemoveEmpty(s []string) []string {
function SliceContainsCaseInSensitive (line 113) | func SliceContainsCaseInSensitive(list []string, target string) bool {
function SliceContains (line 117) | func SliceContains(list []string, target string, caseSensitive bool) bool {
function Filter (line 157) | func Filter(ss []string, cond func(string) bool) []string {
FILE: go/strings/string_slice_test.go
function TestStringIntersection (line 32) | func TestStringIntersection(t *testing.T) {
function TestSliceDifference (line 64) | func TestSliceDifference(t *testing.T) {
function TestRemoveEmpty (line 90) | func TestRemoveEmpty(t *testing.T) {
function TestSliceContains (line 110) | func TestSliceContains(t *testing.T) {
function TestFilter (line 140) | func TestFilter(t *testing.T) {
FILE: go/strings/strings.go
function GetStringOrFallback (line 32) | func GetStringOrFallback(values ...string) string {
function Replace (line 93) | func Replace(s string, old string, news []interface{}, useQuote bool, n ...
function ReplaceAll (line 133) | func ReplaceAll(s, old string, news []interface{}, useQuote bool) string {
function SplitOmitEmpty (line 147) | func SplitOmitEmpty(s, sep string) []string {
function Split2 (line 161) | func Split2(s, sep string) (string, string, bool) {
function SplitToNums (line 169) | func SplitToNums[T any](s, sep string, convert func(string) (T, error)) ...
function EqualCaseInsensitive (line 174) | func EqualCaseInsensitive(src, dst string) bool {
function EmptyString (line 178) | func EmptyString(str string) bool {
FILE: go/strings/strings_test.go
function TestReplace (line 34) | func TestReplace(t *testing.T) {
function TestReplaceAll (line 69) | func TestReplaceAll(t *testing.T) {
function TestSplit (line 101) | func TestSplit(t *testing.T) {
function TestSplitToNums (line 131) | func TestSplitToNums(t *testing.T) {
function TestGetStringOrFallback (line 165) | func TestGetStringOrFallback(t *testing.T) {
function TestLastIndex (line 202) | func TestLastIndex(t *testing.T) {
FILE: go/sync/atomic/file_lock.go
type FileLock (line 33) | type FileLock
method TryLock (line 35) | func (m *FileLock) TryLock() error {
method TryUnLock (line 61) | func (m *FileLock) TryUnLock() error {
FILE: go/sync/atomic/file_lock_test.go
function TestTryLock (line 31) | func TestTryLock(t *testing.T) {
FILE: go/sync/cond.go
type Cond (line 34) | type Cond struct
method wait (line 49) | func (c *Cond) wait() {
method waitFor (line 57) | func (c *Cond) waitFor(timeout time.Duration) error {
method WaitForDo (line 70) | func (c *Cond) WaitForDo(timeout time.Duration, pred func() bool, do f...
method WaitUntil (line 90) | func (c *Cond) WaitUntil(pred func() bool) {
method WaitUntilDo (line 95) | func (c *Cond) WaitUntilDo(pred func() bool, do func() error) {
method SignalDo (line 106) | func (c *Cond) SignalDo(do func() error) {
method BroadcastDo (line 116) | func (c *Cond) BroadcastDo(do func() error) {
method Signal (line 126) | func (c *Cond) Signal() {
method Broadcast (line 136) | func (c *Cond) Broadcast() {
function NewCond (line 41) | func NewCond(l sync.Locker) *Cond {
type copyChecker (line 145) | type copyChecker
method check (line 147) | func (c *copyChecker) check() {
type noCopy (line 160) | type noCopy struct
method Lock (line 163) | func (*noCopy) Lock() {}
method Unlock (line 164) | func (*noCopy) Unlock() {}
FILE: go/sync/cond_test.go
function TestWaitForDo (line 34) | func TestWaitForDo(t *testing.T) {
function TestWaitUntilDo (line 76) | func TestWaitUntilDo(t *testing.T) {
function TestBroadCast (line 114) | func TestBroadCast(t *testing.T) {
FILE: go/syscall/disk.go
type DiskUsage (line 28) | type DiskUsage struct
method Free (line 45) | func (du *DiskUsage) Free() uint64 {
method Avail (line 50) | func (du *DiskUsage) Avail() uint64 {
method Size (line 55) | func (du *DiskUsage) Size() uint64 {
method Used (line 60) | func (du *DiskUsage) Used() uint64 {
method Usage (line 70) | func (du *DiskUsage) Usage() float32 {
function NewDiskUsage (line 34) | func NewDiskUsage(path string) (*DiskUsage, error) {
FILE: go/syscall/disk_test.go
function TestDiskUsage (line 32) | func TestDiskUsage(t *testing.T) {
FILE: go/syscall/memory_darwin.go
type MemoryUsage (line 3) | type MemoryUsage struct
method SysTotalMemory (line 6) | func (m MemoryUsage) SysTotalMemory() uint64 {
method SysFreeMemory (line 10) | func (m MemoryUsage) SysFreeMemory() uint64 {
method SysUsageMemory (line 14) | func (m MemoryUsage) SysUsageMemory() float64 {
FILE: go/syscall/memory_linux.go
type MemoryUsage (line 29) | type MemoryUsage struct
method SysTotalMemory (line 32) | func (m MemoryUsage) SysTotalMemory() uint64 {
method SysFreeMemory (line 42) | func (m MemoryUsage) SysFreeMemory() uint64 {
FILE: go/syscall/memory_linux_test.go
function TestSysTotalMemory (line 32) | func TestSysTotalMemory(t *testing.T) {
FILE: go/syscall/rlimit.go
function SetNumFiles (line 32) | func SetNumFiles(maxOpenFiles uint64) error {
function GetNumFiles (line 36) | func GetNumFiles() (uint64, uint64, error) {
function SetMaxNumFiles (line 53) | func SetMaxNumFiles() (uint64, error) {
FILE: go/syscall/rlimit_test.go
function TestGetNumFiles (line 30) | func TestGetNumFiles(t *testing.T) {
function TestSetMaxNumFiles (line 40) | func TestSetMaxNumFiles(t *testing.T) {
FILE: go/syscall/syscall.go
function KillBatch (line 30) | func KillBatch(pids []int, sig syscall.Signal) (errorPids []int, err err...
FILE: go/time/backoff.go
type Backoff (line 26) | type Backoff interface
FILE: go/time/exponential_backoff.go
constant DefaultInitialInterval (line 31) | DefaultInitialInterval = 500 * time.Millisecond
constant DefaultRandomizationFactor (line 32) | DefaultRandomizationFactor = 0.5
constant DefaultMultiplier (line 34) | DefaultMultiplier = 1.5
constant DefaultMaxInterval (line 35) | DefaultMaxInterval = 60 * time.Second
constant DefaultMinInterval (line 36) | DefaultMinInterval = DefaultInitialInterval
constant DefaultMaxElapsedTime (line 37) | DefaultMaxElapsedTime = 15 * time.Minute
constant DefaultMaxElapsedCount (line 38) | DefaultMaxElapsedCount = -1
type ExponentialBackOff (line 41) | type ExponentialBackOff struct
method Reset (line 76) | func (b *ExponentialBackOff) Reset() {
method ResetWithInterval (line 81) | func (b *ExponentialBackOff) ResetWithInterval(initialInterval time.Du...
method GetCurrentInterval (line 86) | func (b *ExponentialBackOff) GetCurrentInterval() time.Duration {
method PreBackOff (line 93) | func (b *ExponentialBackOff) PreBackOff() (time.Duration, bool) {
method NextBackOff (line 107) | func (b *ExponentialBackOff) NextBackOff() (time.Duration, bool) {
method GetElapsedTime (line 120) | func (b *ExponentialBackOff) GetElapsedTime() time.Duration {
method MaxElapsedTime (line 124) | func (b *ExponentialBackOff) MaxElapsedTime() time.Duration {
method validateAndGetNextInterval (line 128) | func (b *ExponentialBackOff) validateAndGetNextInterval() (time.Durati...
method incrementCurrentInterval (line 144) | func (b *ExponentialBackOff) incrementCurrentInterval() {
method decrementCurrentInterval (line 159) | func (b *ExponentialBackOff) decrementCurrentInterval() {
function NewExponentialBackOff (line 61) | func NewExponentialBackOff(opts ...ExponentialBackOffOption) *Exponentia...
function getRandomValueFromInterval (line 175) | func getRandomValueFromInterval(
FILE: go/time/exponential_backoff.options.go
function WithExponentialBackOffOptionInitialInterval (line 26) | func WithExponentialBackOffOptionInitialInterval(initialInterval time.Du...
function WithExponentialBackOffOptionRandomizationFactor (line 32) | func WithExponentialBackOffOptionRandomizationFactor(randomizationFactor...
function WithExponentialBackOffOptionMultiplier (line 38) | func WithExponentialBackOffOptionMultiplier(multiplier float64) Exponent...
function WithExponentialBackOffOptionMaxInterval (line 44) | func WithExponentialBackOffOptionMaxInterval(maxInterval time.Duration) ...
function WithExponentialBackOffOptionMinInterval (line 50) | func WithExponentialBackOffOptionMinInterval(minInterval time.Duration) ...
function WithExponentialBackOffOptionMaxElapsedTime (line 56) | func WithExponentialBackOffOptionMaxElapsedTime(maxElapsedTime time.Dura...
function WithExponentialBackOffOptionMaxElapsedCount (line 62) | func WithExponentialBackOffOptionMaxElapsedCount(maxElapsedCount int) Ex...
FILE: go/time/exponential_backoff_options.go
type ExponentialBackOffOption (line 25) | type ExponentialBackOffOption interface
type EmptyExponentialBackOffOption (line 33) | type EmptyExponentialBackOffOption struct
method apply (line 35) | func (EmptyExponentialBackOffOption) apply(*ExponentialBackOff) {}
type ExponentialBackOffOptionFunc (line 39) | type ExponentialBackOffOptionFunc
method apply (line 41) | func (f ExponentialBackOffOptionFunc) apply(do *ExponentialBackOff) {
function _ExponentialBackOffOptionWithDefault (line 46) | func _ExponentialBackOffOptionWithDefault() ExponentialBackOffOption {
method ApplyOptions (line 51) | func (o *ExponentialBackOff) ApplyOptions(options ...ExponentialBackOffO...
FILE: go/time/exponential_backoff_test.go
function TestExponentialBackOff (line 32) | func TestExponentialBackOff(t *testing.T) {
function TestExponentialBackOffMaxElaspedTimeFailOver (line 69) | func TestExponentialBackOffMaxElaspedTimeFailOver(t *testing.T) {
function TestDescExponentialBackOff (line 105) | func TestDescExponentialBackOff(t *testing.T) {
FILE: go/time/exponentialbackeoff_syncmap.go
type ExponentialBackOffMap (line 28) | type ExponentialBackOffMap
method Load (line 42) | func (m *ExponentialBackOffMap) Load(key string) (ExponentialBackOff, ...
method Store (line 51) | func (m *ExponentialBackOffMap) Store(key string, value ExponentialBac...
method LoadOrStore (line 58) | func (m *ExponentialBackOffMap) LoadOrStore(key string, value Exponent...
method LoadAndDelete (line 68) | func (m *ExponentialBackOffMap) LoadAndDelete(key string) (value Expon...
method Delete (line 77) | func (m *ExponentialBackOffMap) Delete(key string) {
method Range (line 91) | func (m *ExponentialBackOffMap) Range(f func(key string, value Exponen...
function _ (line 31) | func _() {
FILE: go/time/rate/rate.go
type Limiter (line 32) | type Limiter struct
method Burst (line 55) | func (lim *Limiter) Burst() int {
method Tokens (line 62) | func (lim *Limiter) Tokens() int {
method Bursting (line 67) | func (lim *Limiter) Bursting() int {
method Allow (line 74) | func (lim *Limiter) Allow() bool {
method AllowN (line 84) | func (lim *Limiter) AllowN(n int) bool {
method AllowWaitUntil (line 109) | func (lim *Limiter) AllowWaitUntil() bool {
method AllowFor (line 117) | func (lim *Limiter) AllowFor(timeout time.Duration) bool {
method AllowContext (line 134) | func (lim *Limiter) AllowContext(ctx context.Context) error {
method Put (line 144) | func (lim *Limiter) Put() {
method PutN (line 149) | func (lim *Limiter) PutN(n int) {
method WaitFor (line 160) | func (lim *Limiter) WaitFor(timeout time.Duration) error {
method WaitN (line 165) | func (lim *Limiter) WaitN(timeout time.Duration, n int) error {
method WaitContext (line 209) | func (lim *Limiter) WaitContext(ctx context.Context) error {
method WaitNContext (line 214) | func (lim *Limiter) WaitNContext(ctx context.Context, n int) error {
method SetBurst (line 241) | func (lim *Limiter) SetBurst(newBurst int) {
function NewLimiter (line 39) | func NewLimiter(b int) *Limiter {
FILE: go/time/rate/rate_method.go
type MethodLimiter (line 32) | type MethodLimiter struct
method AddLimiter (line 47) | func (m *MethodLimiter) AddLimiter(method string, limiter *Limiter) er...
method Allow (line 64) | func (m *MethodLimiter) Allow(method string) bool {
method AllowFor (line 76) | func (m *MethodLimiter) AllowFor(method string, timeout time.Duration)...
method Put (line 88) | func (m *MethodLimiter) Put(method string) {
function NewMethodLimiter (line 38) | func NewMethodLimiter(burst int) *MethodLimiter {
FILE: go/time/rate/rate_qps.go
type QPSLimiter (line 32) | type QPSLimiter struct
method SetQPS (line 53) | func (l *QPSLimiter) SetQPS(qps float64) {
method SetBurst (line 60) | func (l *QPSLimiter) SetBurst(burst int) {
method QPS (line 70) | func (l *QPSLimiter) QPS() float64 {
method Burst (line 77) | func (l *QPSLimiter) Burst() int {
method Tokens (line 84) | func (l *QPSLimiter) Tokens() float64 {
method refillTokens (line 93) | func (l *QPSLimiter) refillTokens() {
method Allow (line 108) | func (l *QPSLimiter) Allow() bool {
method AllowN (line 115) | func (l *QPSLimiter) AllowN(n int) bool {
method Wait (line 129) | func (l *QPSLimiter) Wait(ctx context.Context) error {
method WaitN (line 134) | func (l *QPSLimiter) WaitN(ctx context.Context, n int) error {
method AllowFor (line 178) | func (l *QPSLimiter) AllowFor(timeout time.Duration) bool {
method Put (line 192) | func (l *QPSLimiter) Put() {
method Reserve (line 197) | func (l *QPSLimiter) Reserve() *QPSReservation {
method ReserveN (line 202) | func (l *QPSLimiter) ReserveN(n int) *QPSReservation {
function NewQPSLimiter (line 43) | func NewQPSLimiter(qps float64, burst int) *QPSLimiter {
type QPSReservation (line 232) | type QPSReservation struct
method OK (line 240) | func (r *QPSReservation) OK() bool {
method Delay (line 245) | func (r *QPSReservation) Delay() time.Duration {
method Cancel (line 254) | func (r *QPSReservation) Cancel() {
FILE: go/time/rate/rate_qps_method.go
type MethodQPSLimiter (line 32) | type MethodQPSLimiter struct
method AddMethod (line 66) | func (m *MethodQPSLimiter) AddMethod(method string, qps float64, burst...
method SetMethodQPS (line 90) | func (m *MethodQPSLimiter) SetMethodQPS(method string, qps float64, bu...
method RemoveMethod (line 115) | func (m *MethodQPSLimiter) RemoveMethod(method string) {
method SetGlobalQPS (line 122) | func (m *MethodQPSLimiter) SetGlobalQPS(qps float64, burst int) {
method getLimiter (line 129) | func (m *MethodQPSLimiter) getLimiter(method string) *QPSLimiter {
method Allow (line 141) | func (m *MethodQPSLimiter) Allow(method string) bool {
method AllowN (line 146) | func (m *MethodQPSLimiter) AllowN(method string, n int) bool {
method AllowFor (line 151) | func (m *MethodQPSLimiter) AllowFor(method string, timeout time.Durati...
method Wait (line 156) | func (m *MethodQPSLimiter) Wait(ctx context.Context, method string) er...
method WaitN (line 161) | func (m *MethodQPSLimiter) WaitN(ctx context.Context, method string, n...
method Put (line 166) | func (m *MethodQPSLimiter) Put(method string) {
method GetMethodQPS (line 172) | func (m *MethodQPSLimiter) GetMethodQPS(method string) (qps float64, b...
method ListMethods (line 183) | func (m *MethodQPSLimiter) ListMethods() []string {
method Stats (line 202) | func (m *MethodQPSLimiter) Stats() []MethodQPSStats {
type MethodQPSConfig (line 39) | type MethodQPSConfig struct
function NewMethodQPSLimiter (line 47) | func NewMethodQPSLimiter(defaultQPS float64, defaultBurst int) *MethodQP...
function NewMethodQPSLimiterWithConfigs (line 55) | func NewMethodQPSLimiterWithConfigs(defaultQPS float64, defaultBurst int...
type MethodQPSStats (line 195) | type MethodQPSStats struct
FILE: go/time/rate/rate_qps_test.go
function TestQPSLimiter_Allow (line 34) | func TestQPSLimiter_Allow(t *testing.T) {
function TestQPSLimiter_Wait (line 59) | func TestQPSLimiter_Wait(t *testing.T) {
function TestQPSLimiter_WaitTimeout (line 83) | func TestQPSLimiter_WaitTimeout(t *testing.T) {
function TestQPSLimiter_Concurrent (line 99) | func TestQPSLimiter_Concurrent(t *testing.T) {
function TestMethodQPSLimiter_DifferentMethods (line 127) | func TestMethodQPSLimiter_DifferentMethods(t *testing.T) {
function TestMethodQPSLimiter_SetMethodQPS (line 173) | func TestMethodQPSLimiter_SetMethodQPS(t *testing.T) {
function TestMethodQPSLimiter_Stats (line 197) | func TestMethodQPSLimiter_Stats(t *testing.T) {
function TestMethodQPSLimiter_WithConfigs (line 223) | func TestMethodQPSLimiter_WithConfigs(t *testing.T) {
function BenchmarkQPSLimiter_Allow (line 255) | func BenchmarkQPSLimiter_Allow(b *testing.B) {
function BenchmarkMethodQPSLimiter_Allow (line 266) | func BenchmarkMethodQPSLimiter_Allow(b *testing.B) {
FILE: go/time/rate/rate_test.go
function TestLimitAllow (line 34) | func TestLimitAllow(t *testing.T) {
function TestLimitAllowFor (line 82) | func TestLimitAllowFor(t *testing.T) {
FILE: go/time/time.go
constant DayFormat (line 27) | DayFormat = "20060102"
constant TimeMillFormat (line 28) | TimeMillFormat = "20060102150405.000"
constant ShortTimeFormat (line 29) | ShortTimeFormat = "20060102150405"
constant ShortDashTimeFormat (line 30) | ShortDashTimeFormat = "2006-01-02-15:04:05"
constant DefaultTimeFormat (line 31) | DefaultTimeFormat = "2006-01-02 15:04:05"
constant DefaultTimeMillFormat (line 32) | DefaultTimeMillFormat = "2006-01-02 15:04:05.000"
function Now (line 35) | func Now() time.Time {
function NowString (line 40) | func NowString(layout string) string {
function BeginningOfDay (line 49) | func BeginningOfDay(days int) time.Time {
function BeginningOfDayString (line 56) | func BeginningOfDayString(days int, layout string) string {
function EndOfDay (line 67) | func EndOfDay(days int) time.Time {
function EndOfDayString (line 74) | func EndOfDayString(days int, layout string) string {
function TruncateToUTC (line 104) | func TruncateToUTC(t time.Time, d time.Duration) time.Time {
function TruncateToUTCString (line 124) | func TruncateToUTCString(t time.Time, d time.Duration, layout string) st...
FILE: go/time/time_counter.go
type TimeCounter (line 30) | type TimeCounter struct
method Tick (line 48) | func (t *TimeCounter) Tick(msg string) {
method Elapse (line 55) | func (t *TimeCounter) Elapse() time.Duration {
method String (line 67) | func (t *TimeCounter) String() string {
method Summary (line 80) | func (t *TimeCounter) Summary(f func(idx int, msg string, cost time.Du...
method Reset (line 97) | func (t *TimeCounter) Reset() {
function New (line 36) | func New(effect bool) *TimeCounter {
FILE: go/time/time_counter_test.go
function TestAll (line 32) | func TestAll(t *testing.T) {
FILE: go/time/time_test.go
function TestNowString (line 31) | func TestNowString(t *testing.T) {
function TestBeginningOfDayString (line 36) | func TestBeginningOfDayString(t *testing.T) {
function TestEndOfDayString (line 41) | func TestEndOfDayString(t *testing.T) {
function TestTruncateToUTCString (line 46) | func TestTruncateToUTCString(t *testing.T) {
function TestNowFormat (line 55) | func TestNowFormat(t *testing.T) {
FILE: go/time/wait.go
function UntilWithContxt (line 41) | func UntilWithContxt(
function JitterUntilWithContext (line 47) | func JitterUntilWithContext(
function RetryWithContext (line 65) | func RetryWithContext(
function BackOffUntilWithContext (line 83) | func BackOffUntilWithContext(
function CallWithTimeout (line 157) | func CallWithTimeout(ctx context.Context, timeout time.Duration, f func(...
FILE: go/time/wait_test.go
function TestBackOffUntilWithContext (line 33) | func TestBackOffUntilWithContext(t *testing.T) {
function TestRetryWithContext (line 107) | func TestRetryWithContext(t *testing.T) {
FILE: go/unsafe/unsafe.go
function BytesPointer (line 26) | func BytesPointer(data []byte) unsafe.Pointer {
FILE: go/utils/compare.go
type Comparable (line 29) | type Comparable interface
type Comparator (line 33) | type Comparator interface
function CheckComparableTypes (line 37) | func CheckComparableTypes(objs ...interface{}) bool {
function CheckComparableType (line 47) | func CheckComparableType(a interface{}) bool {
function Equal (line 59) | func Equal(a, b interface{}) (bool, error) {
function DeepEqual (line 84) | func DeepEqual(a, b interface{}) bool {
function Compare (line 88) | func Compare(a, b interface{}, compare Comparator) int {
FILE: go/utils/generics_get.go
function GetValueOrFallback (line 24) | func GetValueOrFallback[T comparable] (v, defaultValue T) T {
function Pointer (line 33) | func Pointer[T any](v T) *T {
FILE: go/utils/generics_get_test.go
function TestGetValueOrFallback (line 30) | func TestGetValueOrFallback(t *testing.T) {
FILE: pkg/binlog/binlog.archive.go
constant ArchiveTaskScheme (line 36) | ArchiveTaskScheme = "ArchiveTaskTask"
type ArchiveTaskArgs (line 39) | type ArchiveTaskArgs struct
type ArchiveTask (line 44) | type ArchiveTask struct
method Scheme (line 48) | func (t ArchiveTask) Scheme() string {
method TaskHandler (line 52) | func (t ArchiveTask) TaskHandler(ctx context.Context, msg *queue_.Mess...
FILE: pkg/binlog/binlog.go
type MessageDecoderFunc (line 44) | type MessageDecoderFunc
type MessageKeyDecodeFunc (line 45) | type MessageKeyDecodeFunc
type BinlogOptions (line 47) | type BinlogOptions struct
type Channel (line 63) | type Channel struct
type BinlogService (line 67) | type BinlogService struct
method rotateCallback (line 121) | func (srv *BinlogService) rotateCallback(ctx context.Context, path str...
method logger (line 155) | func (srv *BinlogService) logger() logrus.FieldLogger {
method Run (line 159) | func (srv *BinlogService) Run(ctx context.Context) error {
method work (line 172) | func (srv *BinlogService) work(ctx context.Context, msgCh <-chan *ds_....
method flush (line 277) | func (srv *BinlogService) flush(ctx context.Context, consumer mq_.Cons...
method Serve (line 299) | func (srv *BinlogService) Serve(ctx context.Context) error {
method Shutdown (line 331) | func (srv *BinlogService) Shutdown() {
function defaultBinlogServiceOptions (line 81) | func defaultBinlogServiceOptions() BinlogOptions {
function NewBinlogService (line 99) | func NewBinlogService(dataStore ds_.DataStore, taskq *taskq_.Pool, consu...
FILE: pkg/binlog/binlog.option.go
function WitRootPath (line 26) | func WitRootPath(rootPath string) BinlogServiceOption {
function WithPrefixName (line 32) | func WithPrefixName(prefixName string) BinlogServiceOption {
function WithSufffixName (line 38) | func WithSufffixName(suffixName string) BinlogServiceOption {
function WithFlushBatchSize (line 44) | func WithFlushBatchSize(batch int) BinlogServiceOption {
function WithFlushInterval (line 50) | func WithFlushInterval(flushInterval time.Duration) BinlogServiceOption {
function WithRotateInterval (line 56) | func WithRotateInterval(rotateInterval time.Duration) BinlogServiceOption {
function WithRotateSize (line 62) | func WithRotateSize(rotateSize int64) BinlogServiceOption {
function WithMessageDecoderFunc (line 68) | func WithMessageDecoderFunc(f MessageDecoderFunc) BinlogServiceOption {
function WithMessageKeyDecodeFunc (line 74) | func WithMessageKeyDecodeFunc(f MessageKeyDecodeFunc) BinlogServiceOption {
FILE: pkg/binlog/binlog.pb.go
constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type BinlogType (line 24) | type BinlogType
method Enum (line 43) | func (x BinlogType) Enum() *BinlogType {
method String (line 49) | func (x BinlogType) String() string {
method Descriptor (line 53) | func (BinlogType) Descriptor() protoreflect.EnumDescriptor {
method Type (line 57) | func (BinlogType) Type() protoreflect.EnumType {
method Number (line 61) | func (x BinlogType) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 66) | func (BinlogType) EnumDescriptor() ([]byte, []int) {
constant BinlogType_BinlogType_DB (line 27) | BinlogType_BinlogType_DB BinlogType = 0
constant BinlogType_BinlogType_File (line 28) | BinlogType_BinlogType_File BinlogType = 1
type Binlog (line 70) | type Binlog struct
method Reset (line 84) | func (x *Binlog) Reset() {
method String (line 93) | func (x *Binlog) String() string {
method ProtoMessage (line 97) | func (*Binlog) ProtoMessage() {}
method ProtoReflect (line 99) | func (x *Binlog) ProtoReflect() protoreflect.Message {
method Descriptor (line 112) | func (*Binlog) Descriptor() ([]byte, []int) {
method GetEnabled (line 116) | func (x *Binlog) GetEnabled() bool {
method GetBinlogType (line 123) | func (x *Binlog) GetBinlogType() BinlogType {
method GetFlushBatchSize (line 130) | func (x *Binlog) GetFlushBatchSize() int64 {
method GetMaxFlushInterval (line 137) | func (x *Binlog) GetMaxFlushInterval() *duration.Duration {
method GetFlushTimeout (line 144) | func (x *Binlog) GetFlushTimeout() *duration.Duration {
method GetDbLog (line 151) | func (x *Binlog) GetDbLog() *Binlog_DBLog {
method GetFileLog (line 158) | func (x *Binlog) GetFileLog() *Binlog_FileLog {
type Binlog_DBLog (line 165) | type Binlog_DBLog struct
method Reset (line 171) | func (x *Binlog_DBLog) Reset() {
method String (line 180) | func (x *Binlog_DBLog) String() string {
method ProtoMessage (line 184) | func (*Binlog_DBLog) ProtoMessage() {}
method ProtoReflect (line 186) | func (x *Binlog_DBLog) ProtoReflect() protoreflect.Message {
method Descriptor (line 199) | func (*Binlog_DBLog) Descriptor() ([]byte, []int) {
type Binlog_FileLog (line 203) | type Binlog_FileLog struct
method Reset (line 215) | func (x *Binlog_FileLog) Reset() {
method String (line 224) | func (x *Binlog_FileLog) String() string {
method ProtoMessage (line 228) | func (*Binlog_FileLog) ProtoMessage() {}
method ProtoReflect (line 230) | func (x *Binlog_FileLog) ProtoReflect() protoreflect.Message {
method Descriptor (line 243) | func (*Binlog_FileLog) Descriptor() ([]byte, []int) {
method GetFilepath (line 247) | func (x *Binlog_FileLog) GetFilepath() string {
method GetMaxAge (line 254) | func (x *Binlog_FileLog) GetMaxAge() *duration.Duration {
method GetMaxCount (line 261) | func (x *Binlog_FileLog) GetMaxCount() int64 {
method GetRotateInterval (line 268) | func (x *Binlog_FileLog) GetRotateInterval() *duration.Duration {
method GetRotateSize (line 275) | func (x *Binlog_FileLog) GetRotateSize() int64 {
function file_pkg_binlog_binlog_proto_rawDescGZIP (line 342) | func file_pkg_binlog_binlog_proto_rawDescGZIP() []byte {
function init (line 373) | func init() { file_pkg_binlog_binlog_proto_init() }
function file_pkg_binlog_binlog_proto_init (line 374) | func file_pkg_binlog_binlog_proto_init() {
FILE: pkg/binlog/binlog_option.go
type BinlogServiceOption (line 25) | type BinlogServiceOption interface
type EmptyBinlogServiceOption (line 33) | type EmptyBinlogServiceOption struct
method apply (line 35) | func (EmptyBinlogServiceOption) apply(*BinlogService) {}
type BinlogServiceOptionFunc (line 39) | type BinlogServiceOptionFunc
method apply (line 41) | func (f BinlogServiceOptionFunc) apply(do *BinlogService) {
function _BinlogServiceOptionWithDefault (line 46) | func _BinlogServiceOptionWithDefault() BinlogServiceOption {
method ApplyOptions (line 51) | func (o *BinlogService) ApplyOptions(options ...BinlogServiceOption) *Bi...
FILE: pkg/binlog/binlog_test.go
type TaskTable (line 43) | type TaskTable struct
function TestProducer (line 61) | func TestProducer(t *testing.T) {
function TestNewBinlog (line 114) | func TestNewBinlog(t *testing.T) {
FILE: pkg/binlog/config.go
type Config (line 40) | type Config struct
method Complete (line 121) | func (c *Config) Complete() CompletedConfig {
method loadViper (line 133) | func (c *Config) loadViper() error {
type completedConfig (line 48) | type completedConfig struct
method New (line 58) | func (c *completedConfig) New(ctx context.Context, taskq *taskq_.Pool,...
method install (line 80) | func (c *completedConfig) install(ctx context.Context, taskq *taskq_.P...
type CompletedConfig (line 53) | type CompletedConfig struct
function NewConfig (line 141) | func NewConfig(options ...ConfigOption) *Config {
FILE: pkg/binlog/config.option.go
function WithViper (line 28) | func WithViper(v *viper.Viper) ConfigOption {
FILE: pkg/binlog/config_option.go
type ConfigOption (line 25) | type ConfigOption interface
type EmptyConfigOption (line 33) | type EmptyConfigOption struct
method apply (line 35) | func (EmptyConfigOption) apply(*Config) {}
type ConfigOptionFunc (line 39) | type ConfigOptionFunc
method apply (line 41) | func (f ConfigOptionFunc) apply(do *Config) {
function _ConfigOptionWithDefault (line 46) | func _ConfigOptionWithDefault() ConfigOption {
method ApplyOptions (line 51) | func (o *Config) ApplyOptions(options ...ConfigOption) *Config {
FILE: pkg/binlog/datastore/data.store.go
type DataStore (line 28) | type DataStore interface
FILE: pkg/binlog/datastore/dbstore/db.store.go
type DBDataStore (line 35) | type DBDataStore struct
method WriteData (line 51) | func (s *DBDataStore) WriteData(ctx context.Context, arg interface{}, ...
function NewDBDataStore (line 41) | func NewDBDataStore(db *sqlx.DB) (*DBDataStore, error) {
FILE: pkg/binlog/datastore/filestore/file.store.go
type FileDataStore (line 36) | type FileDataStore struct
method WriteData (line 57) | func (s *FileDataStore) WriteData(ctx context.Context, arg interface{}...
method getOrCreate (line 67) | func (s *FileDataStore) getOrCreate(ctx context.Context, key string) *...
function NewFileDataStore (line 44) | func NewFileDataStore(filedir string, options ...rotate_.RotateFilerOpti...
FILE: pkg/binlog/datastore/message.go
type MessageKey (line 29) | type MessageKey struct
method Equual (line 38) | func (m MessageKey) Equual(s MessageKey) bool {
type Message (line 56) | type Message struct
type MsgType (line 61) | type MsgType
constant MsgType_Insert (line 64) | MsgType_Insert MsgType = 0
constant MsgType_Delete (line 65) | MsgType_Delete MsgType = 1
constant MsgType_Update (line 66) | MsgType_Update MsgType = 2
constant MsgType_Get (line 67) | MsgType_Get MsgType = 3
FILE: pkg/config/config.go
type Config (line 33) | type Config struct
type completedConfig (line 42) | type completedConfig struct
type CompletedConfig (line 48) | type CompletedConfig struct
method Validate (line 54) | func (c *completedConfig[T]) Validate() error {
method Complete (line 59) | func (c *Config[T]) Complete() CompletedConfig[T] {
method loadViper (line 76) | func (c *Config[T]) loadViper() error {
method New (line 84) | func (c completedConfig[T]) New() (T, error) {
function NewConfig (line 93) | func NewConfig[T proto.Message](value T, options ...ConfigOption[T]) *Co...
FILE: pkg/config/config.option.go
function WithViper (line 29) | func WithViper[T proto.Message](v *viper.Viper) ConfigOption[T] {
FILE: pkg/config/config_option.go
type ConfigOption (line 27) | type ConfigOption interface
type EmptyConfigOption (line 35) | type EmptyConfigOption struct
method apply (line 37) | func (EmptyConfigOption[T]) apply(*Config[T]) {}
type ConfigOptionFunc (line 41) | type ConfigOptionFunc
method apply (line 43) | func (f ConfigOptionFunc[T]) apply(do *Config[T]) {
function _ConfigOptionWithDefault (line 48) | func _ConfigOptionWithDefault[T proto.Message]() ConfigOption[T] {
method ApplyOptions (line 53) | func (o *Config[T]) ApplyOptions(options ...ConfigOption[T]) *Config[T] {
FILE: pkg/crontab/config.go
type Config (line 34) | type Config struct
method Complete (line 89) | func (c *Config) Complete() CompletedConfig {
method loadViper (line 101) | func (c *Config) loadViper() error {
type completedConfig (line 44) | type completedConfig struct
method New (line 55) | func (c *completedConfig) New(ctx context.Context) (*CrontabSerivce, e...
method install (line 76) | func (c *completedConfig) install(ctx context.Context) (*CrontabSerivc...
method Validate (line 83) | func (c *completedConfig) Validate() error {
type CompletedConfig (line 50) | type CompletedConfig struct
function NewConfig (line 110) | func NewConfig(options ...ConfigOption) *Config {
FILE: pkg/crontab/config.option.go
function WithViper (line 28) | func WithViper(v *viper.Viper) ConfigOption {
FILE: pkg/crontab/config_option.go
type ConfigOption (line 25) | type ConfigOption interface
type EmptyConfigOption (line 33) | type EmptyConfigOption struct
method apply (line 35) | func (EmptyConfigOption) apply(*Config) {}
type ConfigOptionFunc (line 39) | type ConfigOptionFunc
method apply (line 41) | func (f ConfigOptionFunc) apply(do *Config) {
function _ConfigOptionWithDefault (line 46) | func _ConfigOptionWithDefault() ConfigOption {
method ApplyOptions (line 51) | func (o *Config) ApplyOptions(options ...ConfigOption) *Config {
FILE: pkg/crontab/crontab.go
type CrontabSerivce (line 39) | type CrontabSerivce struct
method Register (line 59) | func (c *CrontabSerivce) Register(f func(context.Context, *logrus.Entr...
method Run (line 64) | func (c *CrontabSerivce) Run(ctx context.Context) error {
method Serve (line 78) | func (c *CrontabSerivce) Serve(ctx context.Context) error {
method Shutdown (line 110) | func (c *CrontabSerivce) Shutdown() {
method getLogger (line 119) | func (c *CrontabSerivce) getLogger() *logrus.Entry {
method check (line 123) | func (c *CrontabSerivce) check(ctx context.Context) error {
function NewCrontabSerivce (line 49) | func NewCrontabSerivce(
FILE: pkg/crontab/crontab.pb.go
constant _ (line 40) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 42) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Crontab (line 45) | type Crontab struct
method Reset (line 54) | func (x *Crontab) Reset() {
method String (line 63) | func (x *Crontab) String() string {
method ProtoMessage (line 67) | func (*Crontab) ProtoMessage() {}
method ProtoReflect (line 69) | func (x *Crontab) ProtoReflect() protoreflect.Message {
method Descriptor (line 82) | func (*Crontab) Descriptor() ([]byte, []int) {
method GetEnabled (line 86) | func (x *Crontab) GetEnabled() bool {
method GetCheckInterval (line 93) | func (x *Crontab) GetCheckInterval() *duration.Duration {
function file_pkg_crontab_crontab_proto_rawDescGZIP (line 125) | func file_pkg_crontab_crontab_proto_rawDescGZIP() []byte {
function init (line 146) | func init() { file_pkg_crontab_crontab_proto_init() }
function file_pkg_crontab_crontab_proto_init (line 147) | func file_pkg_crontab_crontab_proto_init() {
FILE: pkg/crontab/crontab_test.go
function TestCrontabSerivce (line 36) | func TestCrontabSerivce(t *testing.T) {
FILE: pkg/database/mysql/config.go
type Config (line 33) | type Config struct
method Complete (line 98) | func (c *Config) Complete() CompletedConfig {
method loadViper (line 110) | func (c *Config) loadViper() error {
type completedConfig (line 41) | type completedConfig struct
method New (line 51) | func (c *completedConfig) New(ctx context.Context) (*sqlx.DB, error) {
method install (line 73) | func (c *completedConfig) install(ctx context.Context) (*sqlx.DB, erro...
type CompletedConfig (line 46) | type CompletedConfig struct
function NewConfig (line 118) | func NewConfig(options ...ConfigOption) *Config {
FILE: pkg/database/mysql/config.option.go
function WithViper (line 28) | func WithViper(v *viper.Viper) ConfigOption {
FILE: pkg/database/mysql/config_option.go
type ConfigOption (line 25) | type ConfigOption interface
type EmptyConfigOption (line 33) | type EmptyConfigOption struct
method apply (line 35) | func (EmptyConfigOption) apply(*Config) {}
type ConfigOptionFunc (line 39) | type ConfigOptionFunc
method apply (line 41) | func (f ConfigOptionFunc) apply(do *Config) {
function _ConfigOptionWithDefault (line 46) | func _ConfigOptionWithDefault() ConfigOption {
method ApplyOptions (line 51) | func (o *Config) ApplyOptions(options ...ConfigOption) *Config {
FILE: pkg/database/mysql/mysql.go
constant DefaultMaxConns (line 44) | DefaultMaxConns = 100
constant DefaultMaxIdleConns (line 45) | DefaultMaxIdleConns = 10
type DBConfig (line 48) | type DBConfig struct
type DB (line 55) | type DB struct
method GetDatabase (line 128) | func (d *DB) GetDatabase() (*sqlx.DB, error) {
method GetDatabaseUntil (line 189) | func (d *DB) GetDatabaseUntil(
method Close (line 214) | func (d *DB) Close() error {
function NewDB (line 72) | func NewDB(conf DBConfig, opts ...DBOption) *DB {
function GetDB (line 84) | func GetDB() *sqlx.DB {
function GetTheDB (line 88) | func GetTheDB(conf DBConfig) (*sqlx.DB, error) {
function CloseDB (line 99) | func CloseDB() error {
function CloseTheDB (line 107) | func CloseTheDB(conf DBConfig) error {
FILE: pkg/database/mysql/mysql.option.go
function WithMaxConnections (line 28) | func WithMaxConnections(maxConns int) DBOption {
function WithMaxIdleConnections (line 34) | func WithMaxIdleConnections(maxIdleConns int) DBOption {
function WithDialTimeout (line 40) | func WithDialTimeout(dialTimeout time.Duration) DBOption {
function WithReadTimeout (line 46) | func WithReadTimeout(readTimeout time.Duration) DBOption {
function WithWriteTimeout (line 52) | func WithWriteTimeout(writeTimeout time.Duration) DBOption {
function WithConnMaxLifetime (line 58) | func WithConnMaxLifetime(connMaxLifetime time.Duration) DBOption {
function WithInterpolateParams (line 64) | func WithInterpolateParams(enabled bool) DBOption {
FILE: pkg/database/mysql/mysql.pb.go
constant _ (line 40) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 42) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Mysql (line 45) | type Mysql struct
method Reset (line 67) | func (x *Mysql) Reset() {
method String (line 76) | func (x *Mysql) String() string {
method ProtoMessage (line 80) | func (*Mysql) ProtoMessage() {}
method ProtoReflect (line 82) | func (x *Mysql) ProtoReflect() protoreflect.Message {
method Descriptor (line 95) | func (*Mysql) Descriptor() ([]byte, []int) {
method GetEnabled (line 99) | func (x *Mysql) GetEnabled() bool {
method GetAddress (line 106) | func (x *Mysql) GetAddress() string {
method GetUsername (line 113) | func (x *Mysql) GetUsername() string {
method GetPassword (line 120) | func (x *Mysql) GetPassword() string {
method GetDbName (line 127) | func (x *Mysql) GetDbName() string {
method GetMaxConnections (line 134) | func (x *Mysql) GetMaxConnections() int32 {
method GetMaxIdleConnections (line 141) | func (x *Mysql) GetMaxIdleConnections() int32 {
method GetDialTimeout (line 148) | func (x *Mysql) GetDialTimeout() *duration.Duration {
method GetReadTimeout (line 155) | func (x *Mysql) GetReadTimeout() *duration.Duration {
method GetWriteTimeout (line 162) | func (x *Mysql) GetWriteTimeout() *duration.Duration {
method GetMaxLifeTime (line 169) | func (x *Mysql) GetMaxLifeTime() *duration.Duration {
method GetMaxWaitDuration (line 176) | func (x *Mysql) GetMaxWaitDuration() *duration.Duration {
method GetFailAfterDuration (line 183) | func (x *Mysql) GetFailAfterDuration() *duration.Duration {
method GetInterpolateParams (line 190) | func (x *Mysql) GetInterpolateParams() bool {
function file_pkg_database_mysql_mysql_proto_rawDescGZIP (line 259) | func file_pkg_database_mysql_mysql_proto_rawDescGZIP() []byte {
function init (line 285) | func init() { file_pkg_database_mysql_mysql_proto_init() }
function file_pkg_database_mysql_mysql_proto_init (line 286) | func file_pkg_database_mysql_mysql_proto_init() {
FILE: pkg/database/mysql/mysql_operate_test.go
type TaskTable (line 36) | type TaskTable struct
type Tasks (line 54) | type Tasks
method String (line 56) | func (t Tasks) String() string {
function TestInsert (line 67) | func TestInsert(t *testing.T) {
function TestInsertNewBatch (line 138) | func TestInsertNewBatch(t *testing.T) {
function TestInsertBatch (line 207) | func TestInsertBatch(t *testing.T) {
function TestDeleteBatch (line 312) | func TestDeleteBatch(t *testing.T) {
FILE: pkg/database/mysql/mysql_options.go
type DBOption (line 25) | type DBOption interface
type EmptyDBOption (line 33) | type EmptyDBOption struct
method apply (line 35) | func (EmptyDBOption) apply(*DB) {}
type DBOptionFunc (line 39) | type DBOptionFunc
method apply (line 41) | func (f DBOptionFunc) apply(do *DB) {
function _DBOptionWithDefault (line 46) | func _DBOptionWithDefault() DBOption {
method ApplyOptions (line 51) | func (o *DB) ApplyOptions(options ...DBOption) *DB {
FILE: pkg/database/mysql/mysql_test.go
function TestGetDataBase (line 34) | func TestGetDataBase(t *testing.T) {
function TestGetDatabaseUntil (line 71) | func TestGetDatabaseUntil(t *testing.T) {
function TestNew (line 106) | func TestNew(t *testing.T) {
function TestGetTheDBAndClose (line 119) | func TestGetTheDBAndClose(t *testing.T) {
FILE: pkg/database/mysql/mysql_transaction.go
type TxDao (line 33) | type TxDao struct
method Begin (line 37) | func (d *TxDao) Begin(ctx context.Context, db *sqlx.DB, opts *sql.TxOp...
method Commit (line 52) | func (d *TxDao) Commit() error {
method Rollback (line 65) | func (d *TxDao) Rollback() error {
function TxPipelined (line 77) | func TxPipelined(ctx context.Context, db *sqlx.DB, fn func(*sqlx.Tx) err...
FILE: pkg/database/mysql/sql.go
constant dbTag (line 33) | dbTag = "db"
type SqlCompare (line 35) | type SqlCompare
constant SqlCompareEqual (line 38) | SqlCompareEqual SqlCompare = "="
constant SqlCompareNotEqual (line 39) | SqlCompareNotEqual SqlCompare = "!="
constant SqlCompareGreater (line 40) | SqlCompareGreater SqlCompare = ">"
constant SqlCompareLessThan (line 41) | SqlCompareLessThan SqlCompare = "<"
constant SqlCompareGreatEqual (line 42) | SqlCompareGreatEqual SqlCompare = ">="
constant SqlCompareLessEqual (line 43) | SqlCompareLessEqual SqlCompare = "<="
constant SqlCompareLike (line 44) | SqlCompareLike SqlCompare = "LIKE"
constant SqlCompareIn (line 45) | SqlCompareIn SqlCompare = "IN"
type SqlOperator (line 48) | type SqlOperator
constant SqlOperatorAnd (line 51) | SqlOperatorAnd SqlOperator = "AND"
constant SqlOperatorOr (line 52) | SqlOperatorOr SqlOperator = "OR"
constant SqlOperatorNot (line 53) | SqlOperatorNot SqlOperator = "NOT"
function NonzeroCondition (line 57) | func NonzeroCondition(cmp SqlCompare, oper SqlOperator, arg interface{})...
function NonzeroFields (line 67) | func NonzeroFields(arg interface{}) []string {
function ConditionWithEqualAnd (line 71) | func ConditionWithEqualAnd(condFields ...string) string {
function OrderCondition (line 76) | func OrderCondition(orders map[string]bool) string {
function InCondition (line 98) | func InCondition(cond string, values ...string) string {
function NamedInCondition (line 113) | func NamedInCondition(oper SqlOperator, cols []string, arg interface{}) ...
function JoinNamedColumnsValues (line 128) | func JoinNamedColumnsValues(cols ...string) string {
function JoinNamedColumnsValuesWithOperator (line 133) | func JoinNamedColumnsValuesWithOperator(cmp SqlCompare, oper SqlOperator...
function namedTableColumnsValues (line 143) | func namedTableColumnsValues(cmp SqlCompare, cols ...string) []string {
function JoinNamedColumnsValuesBatch (line 181) | func JoinNamedColumnsValuesBatch(cols []string, batch int) string {
function BuildNamedInsertSql (line 195) | func BuildNamedInsertSql(table string, cols []string, batch int) string {
function TransferToNamedColumnsValuesBatch (line 210) | func TransferToNamedColumnsValuesBatch(req []map[string]interface{}) map...
function BuildNamedColumnsValuesBatch (line 223) | func BuildNamedColumnsValuesBatch(req interface{}) map[string]interface{} {
FILE: pkg/database/mysql/sql_exec.go
function ExecContext (line 54) | func ExecContext(
function SelectNamedContext (line 89) | func SelectNamedContext(
function GetCountContext (line 120) | func GetCountContext(ctx context.Context, query string, arg interface{},...
function NamedExecContext (line 149) | func NamedExecContext(
function PrepareNamedContext (line 168) | func PrepareNamedContext(ctx context.Context,
FILE: pkg/database/mysql/sql_test.go
function TestJoinNamedColumnsValuesWithOperator (line 31) | func TestJoinNamedColumnsValuesWithOperator(t *testing.T) {
function TestInCondition (line 52) | func TestInCondition(t *testing.T) {
function TestNamedInCondition (line 75) | func TestNamedInCondition(t *testing.T) {
function TestOrderCondition (line 110) | func TestOrderCondition(t *testing.T) {
function TestJoinNamedColumnsValuesBatch (line 137) | func TestJoinNamedColumnsValuesBatch(t *testing.T) {
FILE: pkg/database/mysql/sql_type.go
type SQLDB (line 30) | type SQLDB
method Store (line 38) | func (m *SQLDB) Store(value *sqlx.DB) {
method Load (line 42) | func (m *SQLDB) Load() *sqlx.DB {
FILE: pkg/database/redis/command.get.values.go
function GetValue (line 31) | func GetValue(ctx context.Context, db *redis.Client, key string) ([]stri...
function GetValues (line 81) | func GetValues(ctx context.Context, db *redis.Client, keys ...string) ([...
FILE: pkg/database/redis/command.hset.go
function HSetStruct (line 34) | func HSetStruct(ctx context.Context, db *redis.Client, key string, arg i...
FILE: pkg/database/redis/config.go
type Config (line 33) | type Config struct
method Complete (line 98) | func (c *Config) Complete() CompletedConfig {
method loadViper (line 110) | func (c *Config) loadViper() error {
type completedConfig (line 41) | type completedConfig struct
method New (line 51) | func (c *completedConfig) New(ctx context.Context) (*redis.Client, err...
method install (line 73) | func (c *completedConfig) install(ctx context.Context) (*redis.Client,...
type CompletedConfig (line 46) | type CompletedConfig struct
function NewConfig (line 118) | func NewConfig(options ...ConfigOption) *Config {
FILE: pkg/database/redis/config.option.go
function WithViper (line 28) | func WithViper(v *viper.Viper) ConfigOption {
FILE: pkg/database/redis/config_option.go
type ConfigOption (line 25) | type ConfigOption interface
type EmptyConfigOption (line 33) | type EmptyConfigOption struct
method apply (line 35) | func (EmptyConfigOption) apply(*Config) {}
type ConfigOptionFunc (line 39) | type ConfigOptionFunc
method apply (line 41) | func (f ConfigOptionFunc) apply(do *Config) {
function _ConfigOptionWithDefault (line 46) | func _ConfigOptionWithDefault() ConfigOption {
method ApplyOptions (line 51) | func (o *Config) ApplyOptions(options ...ConfigOption) *Config {
FILE: pkg/database/redis/redis.go
constant DefaultMinIdleConns (line 38) | DefaultMinIdleConns = 10
constant DefaultPoolSize (line 39) | DefaultPoolSize = 10
constant DefaultDialTimeout (line 40) | DefaultDialTimeout = 5 * time.Second
constant DefaultReadTimeout (line 41) | DefaultReadTimeout = 5 * time.Second
constant DefaultWriteTimeout (line 42) | DefaultWriteTimeout = 5 * time.Second
constant DefaultMasterName (line 43) | DefaultMasterName = "mymaster"
type DBConfig (line 46) | type DBConfig struct
type RedisClient (line 53) | type RedisClient struct
method GetRedis (line 87) | func (r *RedisClient) GetRedis(ctx context.Context) (*redis.Client, er...
method GetDatabaseUntil (line 134) | func (r *RedisClient) GetDatabaseUntil(
method Close (line 158) | func (r *RedisClient) Close() error {
function NewRedisClient (line 67) | func NewRedisClient(conf DBConfig, opts ...RedisOption) *RedisClient {
function GetDB (line 83) | func GetDB() *redis.Client {
FILE: pkg/database/redis/redis.options.go
function WithPoolSize (line 26) | func WithPoolSize(poolSize int) RedisOption {
function WithMinIdleConnections (line 32) | func WithMinIdleConnections(minIdleConns int) RedisOption {
function WithDialTimeout (line 38) | func WithDialTimeout(dialTimeout time.Duration) RedisOption {
function WithReadTimeout (line 44) | func WithReadTimeout(readTimeout time.Duration) RedisOption {
function WithWriteTimeout (line 50) | func WithWriteTimeout(writeTimeout time.Duration) RedisOption {
function WithMasterName (line 56) | func WithMasterName(masterName string) RedisOption {
FILE: pkg/database/redis/redis.pb.go
constant _ (line 40) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 42) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Redis (line 46) | type Redis struct
method Reset (line 127) | func (x *Redis) Reset() {
method String (line 136) | func (x *Redis) String() string {
method ProtoMessage (line 140) | func (*Redis) ProtoMessage() {}
method ProtoReflect (line 142) | func (x *Redis) ProtoReflect() protoreflect.Message {
method Descriptor (line 155) | func (*Redis) Descriptor() ([]byte, []int) {
method GetEnabled (line 159) | func (x *Redis) GetEnabled() bool {
method GetAddresses (line 166) | func (x *Redis) GetAddresses() []string {
method GetDb (line 173) | func (x *Redis) GetDb() int64 {
method GetUsername (line 180) | func (x *Redis) GetUsername() string {
method GetPassword (line 187) | func (x *Redis) GetPassword() string {
method GetMaxRetries (line 194) | func (x *Redis) GetMaxRetries() int64 {
method GetMinRetryBackoff (line 201) | func (x *Redis) GetMinRetryBackoff() *duration.Duration {
method GetMaxRetryBackoff (line 208) | func (x *Redis) GetMaxRetryBackoff() *duration.Duration {
method GetDialTimeout (line 215) | func (x *Redis) GetDialTimeout() *duration.Duration {
method GetReadTimeout (line 222) | func (x *Redis) GetReadTimeout() *duration.Duration {
method GetWriteTimeout (line 229) | func (x *Redis) GetWriteTimeout() *duration.Duration {
method GetPoolSize (line 236) | func (x *Redis) GetPoolSize() int64 {
method GetMinIdleConns (line 243) | func (x *Redis) GetMinIdleConns() int64 {
method GetMaxConnAge (line 250) | func (x *Redis) GetMaxConnAge() *duration.Duration {
method GetPoolTimeout (line 257) | func (x *Redis) GetPoolTimeout() *duration.Duration {
method GetIdleTimeout (line 264) | func (x *Redis) GetIdleTimeout() *duration.Duration {
method GetIdleCheckFrequency (line 271) | func (x *Redis) GetIdleCheckFrequency() *duration.Duration {
method GetMaxRedirects (line 278) | func (x *Redis) GetMaxRedirects() int64 {
method GetReadOnly (line 285) | func (x *Redis) GetReadOnly() bool {
method GetRouteByLatency (line 292) | func (x *Redis) GetRouteByLatency() bool {
method GetRouteRandomly (line 299) | func (x *Redis) GetRouteRandomly() bool {
method GetMasterName (line 306) | func (x *Redis) GetMasterName() string {
method GetMaxWaitDuration (line 313) | func (x *Redis) GetMaxWaitDuration() *duration.Duration {
method GetFailAfterDuration (line 320) | func (x *Redis) GetFailAfterDuration() *duration.Duration {
function file_pkg_database_redis_redis_proto_rawDescGZIP (line 419) | func file_pkg_database_redis_redis_proto_rawDescGZIP() []byte {
function init (line 450) | func init() { file_pkg_database_redis_redis_proto_init() }
function file_pkg_database_redis_redis_proto_init (line 451) | func file_pkg_database_redis_redis_proto_init() {
FILE: pkg/database/redis/redis_benchmark_test.go
function BenchmarkSet (line 37) | func BenchmarkSet(t *testing.B) {
function BenchmarkParallelSet (line 61) | func BenchmarkParallelSet(t *testing.B) {
FILE: pkg/database/redis/redis_hset_test.go
function TestHSetStruct (line 32) | func TestHSetStruct(t *testing.T) {
function TestHKeys (line 64) | func TestHKeys(t *testing.T) {
function TestHGetAll (line 93) | func TestHGetAll(t *testing.T) {
function TestHGet (line 122) | func TestHGet(t *testing.T) {
function TestHExists (line 154) | func TestHExists(t *testing.T) {
function TestHIncrBy (line 190) | func TestHIncrBy(t *testing.T) {
function TestHLen (line 226) | func TestHLen(t *testing.T) {
function TestHMGet (line 259) | func TestHMGet(t *testing.T) {
function TestHMSet (line 296) | func TestHMSet(t *testing.T) {
function TestHSetNX (line 342) | func TestHSetNX(t *testing.T) {
function TestHVals (line 393) | func TestHVals(t *testing.T) {
FILE: pkg/database/redis/redis_key_delete_test.go
function TestDeletePrefixKeys (line 39) | func TestDeletePrefixKeys(t *testing.T) {
FILE: pkg/database/redis/redis_key_test.go
function TestExpire (line 31) | func TestExpire(t *testing.T) {
function TestExpireAt (line 57) | func TestExpireAt(t *testing.T) {
function TestPExpire (line 87) | func TestPExpire(t *testing.T) {
function TestDump (line 113) | func TestDump(t *testing.T) {
FILE: pkg/database/redis/redis_list_test.go
function TestRPush (line 31) | func TestRPush(t *testing.T) {
function TestRPushX (line 63) | func TestRPushX(t *testing.T) {
function TestLLen (line 94) | func TestLLen(t *testing.T) {
function TestLRange (line 124) | func TestLRange(t *testing.T) {
function TestLIndex (line 159) | func TestLIndex(t *testing.T) {
function TestLInsertBefore (line 190) | func TestLInsertBefore(t *testing.T) {
function TestLPush (line 224) | func TestLPush(t *testing.T) {
function TestLTrim (line 255) | func TestLTrim(t *testing.T) {
function TestBLPop (line 289) | func TestBLPop(t *testing.T) {
FILE: pkg/database/redis/redis_options.go
type RedisOption (line 25) | type RedisOption interface
type EmptyRedisOption (line 33) | type EmptyRedisOption struct
method apply (line 35) | func (EmptyRedisOption) apply(*RedisClient) {}
type RedisOptionFunc (line 39) | type RedisOptionFunc
method apply (line 41) | func (f RedisOptionFunc) apply(do *RedisClient) {
function _RedisOptionWithDefault (line 46) | func _RedisOptionWithDefault() RedisOption {
method ApplyOptions (line 52) | func (o *RedisClient) ApplyOptions(options ...RedisOption) *RedisClient {
FILE: pkg/database/redis/redis_set_test.go
function TestSAdd (line 30) | func TestSAdd(t *testing.T) {
function TestSCard (line 65) | func TestSCard(t *testing.T) {
function TestSDiff (line 93) | func TestSDiff(t *testing.T) {
function TestSDiffStore (line 116) | func TestSDiffStore(t *testing.T) {
function TestSInter (line 142) | func TestSInter(t *testing.T) {
function TestSMembers (line 165) | func TestSMembers(t *testing.T) {
function TestSInterStore (line 191) | func TestSInterStore(t *testing.T) {
function TestSRem (line 218) | func TestSRem(t *testing.T) {
function TestSMIsMember (line 246) | func TestSMIsMember(t *testing.T) {
function TestSPop (line 273) | func TestSPop(t *testing.T) {
function TestSRandMember (line 297) | func TestSRandMember(t *testing.T) {
function TestSRandMemberN (line 321) | func TestSRandMemberN(t *testing.T) {
function TestSUnion (line 346) | func TestSUnion(t *testing.T) {
function TestSMove (line 370) | func TestSMove(t *testing.T) {
function TestSUnionStore (line 398) | func TestSUnionStore(t *testing.T) {
function TestSScan (line 424) | func TestSScan(t *testing.T) {
FILE: pkg/database/redis/redis_string_test.go
function TestGetDataBase (line 37) | func TestGetDataBase(t *testing.T) {
function GetDBOrDie (line 78) | func GetDBOrDie() *redis.Client {
function TestNew (line 96) | func TestNew(t *testing.T) {
function TestSet (line 108) | func TestSet(t *testing.T) {
function TestGetValues (line 152) | func TestGetValues(t *testing.T) {
function TestGetRange (line 173) | func TestGetRange(t *testing.T) {
FILE: pkg/database/redis/redis_transaction_test.go
function TestTxPipelined (line 33) | func TestTxPipelined(t *testing.T) {
FILE: pkg/database/redis/redis_type.go
constant TypeString (line 31) | TypeString = "string"
constant TypeHash (line 32) | TypeHash = "hash"
constant TypeList (line 33) | TypeList = "list"
constant TypeSet (line 34) | TypeSet = "set"
constant TypeZSet (line 35) | TypeZSet = "zset"
constant TypeOther (line 36) | TypeOther = "other"
type RedisDB (line 39) | type RedisDB
method Store (line 47) | func (m *RedisDB) Store(value *redis.Client) {
method Load (line 51) | func (m *RedisDB) Load() *redis.Client {
FILE: pkg/database/redis/redis_zset_test.go
function TestZAdd (line 32) | func TestZAdd(t *testing.T) {
function TestZCard (line 77) | func TestZCard(t *testing.T) {
function TestZRange (line 104) | func TestZRange(t *testing.T) {
function TestZRangeByScore (line 136) | func TestZRangeByScore(t *testing.T) {
FILE: pkg/discovery/consul/discovery.go
type ServiceRegistryServer (line 38) | type ServiceRegistryServer struct
method Run (line 92) | func (srv *ServiceRegistryServer) Run(ctx context.Context) error {
method Serve (line 107) | func (srv *ServiceRegistryServer) Serve(ctx context.Context) error {
method Shutdown (line 150) | func (srv *ServiceRegistryServer) Shutdown() {
method Register (line 159) | func (srv *ServiceRegistryServer) Register() error {
method UnRegister (line 186) | func (srv *ServiceRegistryServer) UnRegister() error {
method logger (line 197) | func (srv *ServiceRegistryServer) logger() logrus.FieldLogger {
function NewServiceRegistry (line 55) | func NewServiceRegistry(
FILE: pkg/discovery/etcd/config.go
type Config (line 32) | type Config struct
method Complete (line 102) | func (c *Config) Complete() CompletedConfig {
method loadViper (line 114) | func (c *Config) loadViper() error {
type completedConfig (line 40) | type completedConfig struct
method New (line 50) | func (c *completedConfig) New(ctx context.Context, createCallbackFunc,...
method install (line 72) | func (c *completedConfig) install(ctx context.Context, createCallbackF...
type CompletedConfig (line 45) | type CompletedConfig struct
function NewConfig (line 122) | func NewConfig(options ...ConfigOption) *Config {
FILE: pkg/discovery/etcd/config.option.go
function WithViper (line 28) | func WithViper(v *viper.Viper) ConfigOption {
FILE: pkg/discovery/etcd/config_option.go
type ConfigOption (line 25) | type ConfigOption interface
type EmptyConfigOption (line 33) | type EmptyConfigOption struct
method apply (line 35) | func (EmptyConfigOption) apply(*Config) {}
type ConfigOptionFunc (line 39) | type ConfigOptionFunc
method apply (line 41) | func (f ConfigOptionFunc) apply(do *Config) {
function _ConfigOptionWithDefault (line 46) | func _ConfigOptionWithDefault() ConfigOption {
method ApplyOptions (line 51) | func (o *Config) ApplyOptions(options ...ConfigOption) *Config {
FILE: pkg/discovery/etcd/etcd.go
type EventCallbackFunc (line 38) | type EventCallbackFunc
constant DefaultDialTimeout (line 47) | DefaultDialTimeout = 5 * time.Second
constant DefaultLockTTL (line 48) | DefaultLockTTL = 15 * time.Second
type EtcdConfig (line 51) | type EtcdConfig struct
type EtcdKVOptions (line 57) | type EtcdKVOptions struct
type EtcdKV (line 71) | type EtcdKV struct
method GetKV (line 108) | func (d *EtcdKV) GetKV(ctx context.Context) (*clientv3.Client, error) {
method GetKVUntil (line 146) | func (d *EtcdKV) GetKVUntil(
method Watch (line 171) | func (d *EtcdKV) Watch(ctx context.Context) {
method Close (line 178) | func (d *EtcdKV) Close() error {
method Lock (line 185) | func (d *EtcdKV) Lock(ctx context.Context, opts ...EtcdKVOption) error {
method Unlock (line 216) | func (d *EtcdKV) Unlock(ctx context.Context) error {
method TxPipelined (line 228) | func (d *EtcdKV) TxPipelined(ctx context.Context, cmps []clientv3.Cmp,...
function NewEtcdKV (line 81) | func NewEtcdKV(conf EtcdConfig, opts ...EtcdKVOption) *EtcdKV {
function GetKV (line 96) | func GetKV() *clientv3.Client {
function CloseKV (line 100) | func CloseKV() error {
FILE: pkg/discovery/etcd/etcd.option.go
function WithDialTimeout (line 28) | func WithDialTimeout(dialTimeout time.Duration) EtcdKVOption {
function WithMaxCallRecvMsgSize (line 34) | func WithMaxCallRecvMsgSize(msgSize int) EtcdKVOption {
function WithMaxCallSendMsgSize (line 40) | func WithMaxCallSendMsgSize(msgSize int) EtcdKVOption {
function WithAutoSyncInterval (line 46) | func WithAutoSyncInterval(autoSyncInterval time.Duration) EtcdKVOption {
function WithWatchPaths (line 52) | func WithWatchPaths(paths []string) EtcdKVOption {
function WithWatchCreateCallbackFunc (line 58) | func WithWatchCreateCallbackFunc(f EventCallbackFunc) EtcdKVOption {
function WithWatchDeleteCallbackFunc (line 64) | func WithWatchDeleteCallbackFunc(f EventCallbackFunc) EtcdKVOption {
function WithLockTTL (line 70) | func WithLockTTL(ttl time.Duration) EtcdKVOption {
function WithLockPrefixPath (line 76) | func WithLockPrefixPath(prefix string) EtcdKVOption {
function WithLockKey (line 82) | func WithLockKey(key string) EtcdKVOption {
FILE: pkg/discovery/etcd/etcd.pb.go
constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Etcd (line 24) | type Etcd struct
method Reset (line 51) | func (x *Etcd) Reset() {
method String (line 60) | func (x *Etcd) String() string {
method ProtoMessage (line 64) | func (*Etcd) ProtoMessage() {}
method ProtoReflect (line 66) | func (x *Etcd) ProtoReflect() protoreflect.Message {
method Descriptor (line 79) | func (*Etcd) Descriptor() ([]byte, []int) {
method GetEnabled (line 83) | func (x *Etcd) GetEnabled() bool {
method GetAddresses (line 90) | func (x *Etcd) GetAddresses() []string {
method GetUsername (line 97) | func (x *Etcd) GetUsername() string {
method GetPassword (line 104) | func (x *Etcd) GetPassword() string {
method GetMaxCallSendMsgSize (line 111) | func (x *Etcd) GetMaxCallSendMsgSize() int32 {
method GetMaxCallRecvMsgSize (line 118) | func (x *Etcd) GetMaxCallRecvMsgSize() int32 {
method GetAutoSyncInterval (line 125) | func (x *Etcd) GetAutoSyncInterval() *durationpb.Duration {
method GetDialTimeout (line 132) | func (x *Etcd) GetDialTimeout() *durationpb.Duration {
method GetMaxWaitDuration (line 139) | func (x *Etcd) GetMaxWaitDuration() *durationpb.Duration {
method GetFailAfterDuration (line 146) | func (x *Etcd) GetFailAfterDuration() *durationpb.Duration {
method GetWatchPaths (line 153) | func (x *Etcd) GetWatchPaths() []string {
function file_pkg_discovery_etcd_etcd_proto_rawDescGZIP (line 213) | func file_pkg_discovery_etcd_etcd_proto_rawDescGZIP() []byte {
function init (line 237) | func init() { file_pkg_discovery_etcd_etcd_proto_init() }
function file_pkg_discovery_etcd_etcd_proto_init (line 238) | func file_pkg_discovery_etcd_etcd_proto_init() {
FILE: pkg/discovery/etcd/etcd.watch.go
function Watch (line 10) | func Watch(ctx context.Context, kv *clientv3.Client, key string, createC...
FILE: pkg/discovery/etcd/etcd_options.go
type EtcdKVOption (line 25) | type EtcdKVOption interface
type EmptyEtcdKVOption (line 33) | type EmptyEtcdKVOption struct
method apply (line 35) | func (EmptyEtcdKVOption) apply(*EtcdKV) {}
type EtcdKVOptionFunc (line 39) | type EtcdKVOptionFunc
method apply (line 41) | func (f EtcdKVOptionFunc) apply(do *EtcdKV) {
function _EtcdKVOptionWithDefault (line 46) | func _EtcdKVOptionWithDefault() EtcdKVOption {
method ApplyOptions (line 51) | func (o *EtcdKV) ApplyOptions(options ...EtcdKVOption) *EtcdKV {
FILE: pkg/discovery/etcd/etcd_test.go
function TestGetKV (line 37) | func TestGetKV(t *testing.T) {
function TestGetKVUntil (line 62) | func TestGetKVUntil(t *testing.T) {
function CreateCallback (line 88) | func CreateCallback(ctx context.Context, key, value string) {
function DeleteCallback (line 92) | func DeleteCallback(ctx context.Context, key, value string) {
function InstallEtcd (line 96) | func InstallEtcd(ctx context.Context) (*etcd_.EtcdKV, error) {
function TestNew (line 110) | func TestNew(t *testing.T) {
function TestTxPipelined (line 138) | func TestTxPipelined(t *testing.T) {
FILE: pkg/discovery/etcd/etcd_type.go
type ETCDKV (line 30) | type ETCDKV
method Store (line 38) | func (m *ETCDKV) Store(value *clientv3.Client) {
method Load (line 42) | func (m *ETCDKV) Load() *clientv3.Client {
FILE: pkg/file-cleanup/config.go
type Config (line 35) | type Config struct
method Complete (line 102) | func (c *Config) Complete(options ...ConfigOption) CompletedConfig {
method loadViper (line 116) | func (c *Config) loadViper() error {
type completedConfig (line 46) | type completedConfig struct
method New (line 57) | func (c *completedConfig) New(ctx context.Context) (*disk_.DiskCleaner...
method install (line 78) | func (c *completedConfig) install(ctx context.Context) (*disk_.DiskCle...
method Validate (line 96) | func (c *completedConfig) Validate() error {
type CompletedConfig (line 52) | type CompletedConfig struct
function NewConfig (line 125) | func NewConfig(options ...ConfigOption) *Config {
FILE: pkg/file-cleanup/config.option.go
function WithViper (line 29) | func WithViper(v *viper.Viper) ConfigOption {
function WithDiskUsageCallBack (line 35) | func WithDiskUsageCallBack(f func(diskPath string, diskUsage float32)) C...
function WithCleanPostCallBack (line 41) | func WithCleanPostCallBack(f func(file string, err error)) ConfigOption {
FILE: pkg/file-cleanup/config_option.go
type ConfigOption (line 25) | type ConfigOption interface
type EmptyConfigOption (line 33) | type EmptyConfigOption struct
method apply (line 35) | func (EmptyConfigOption) apply(*Config) {}
type ConfigOptionFunc (line 39) | type ConfigOptionFunc
method apply (line 41) | func (f ConfigOptionFunc) apply(do *Config) {
function _ConfigOptionWithDefault (line 46) | func _ConfigOptionWithDefault() ConfigOption {
method ApplyOptions (line 51) | func (o *Config) ApplyOptions(options ...ConfigOption) *Config {
FILE: pkg/file-cleanup/disk/disk_cleaner.go
function init (line 46) | func init() {
constant DefaultCheckInterval (line 51) | DefaultCheckInterval time.Duration = time.Minute
constant DefaultbaseExpired (line 52) | DefaultbaseExpired time.Duration = 72 * time.Hour
constant DefalutRandomizationFactor (line 53) | DefalutRandomizationFactor = 0.1
constant DefalutMultiplier (line 54) | DefalutMultiplier = 0.8
constant DefalutMinInterval (line 55) | DefalutMinInterval = time.Minute
type DiskCleanerConfig (line 58) | type DiskCleanerConfig struct
type DiskCleanerSerivce (line 67) | type DiskCleanerSerivce struct
method getLogger (line 156) | func (s *DiskCleanerSerivce) getLogger() *logrus.Entry {
method Run (line 161) | func (s *DiskCleanerSerivce) Run(ctx context.Context) error {
method Serve (line 175) | func (s *DiskCleanerSerivce) Serve(ctx context.Context) error {
method clean (line 207) | func (s *DiskCleanerSerivce) clean(ctx context.Context) error {
method Shutdown (line 280) | func (s *DiskCleanerSerivce) Shutdown() {
function checkAndCanoicalzePaths (line 81) | func checkAndCanoicalzePaths(paths ...string) ([]string, bool) {
function NewDiskCleanerSerivce (line 102) | func NewDiskCleanerSerivce(
FILE: pkg/file-cleanup/disk/disk_cleaner.option.go
function WithDiskCheckInterval (line 28) | func WithDiskCheckInterval(interval time.Duration) DiskCleanerConfigOpti...
function WithDiskBaseExpired (line 34) | func WithDiskBaseExpired(expired time.Duration) DiskCleanerConfigOption {
function WithDiskMinExpired (line 40) | func WithDiskMinExpired(expired time.Duration) DiskCleanerConfigOption {
function WithDiskUsageCallBack (line 46) | func WithDiskUsageCallBack(f func(diskPath string, diskUsage float32)) D...
function WithCleanPostCallBack (line 52) | func WithCleanPostCallBack(f func(file string, err error)) DiskCleanerCo...
FILE: pkg/file-cleanup/disk/disk_cleaner.pb.go
constant _ (line 40) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 42) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type DiskCleaner (line 45) | type DiskCleaner struct
method Reset (line 63) | func (x *DiskCleaner) Reset() {
method String (line 72) | func (x *DiskCleaner) String() string {
method ProtoMessage (line 76) | func (*DiskCleaner) ProtoMessage() {}
method ProtoReflect (line 78) | func (x *DiskCleaner) ProtoReflect() protoreflect.Message {
method Descriptor (line 91) | func (*DiskCleaner) Descriptor() ([]byte, []int) {
method GetEnabled (line 95) | func (x *DiskCleaner) GetEnabled() bool {
method GetDiskUsage (line 102) | func (x *DiskCleaner) GetDiskUsage() float32 {
method GetPaths (line 109) | func (x *DiskCleaner) GetPaths() []string {
method GetExts (line 116) | func (x *DiskCleaner) GetExts() []string {
method GetCheckInterval (line 123) | func (x *DiskCleaner) GetCheckInterval() *duration.Duration {
method GetBaseExpired (line 130) | func (x *DiskCleaner) GetBaseExpired() *duration.Duration {
method GetMinExpired (line 137) | func (x *DiskCleaner) GetMinExpired() *duration.Duration {
function file_pkg_file_cleanup_disk_disk_cleaner_proto_rawDescGZIP (line 183) | func file_pkg_file_cleanup_disk_disk_cleaner_proto_rawDescGZIP() []byte {
function init (line 206) | func init() { file_pkg_file_cleanup_disk_disk_cleaner_proto_init() }
function file_pkg_file_cleanup_disk_disk_cleaner_proto_init (line 207) | func file_pkg_file_cleanup_disk_disk_cleaner_proto_init() {
FILE: pkg/file-cleanup/disk/disk_cleaner_option.go
type DiskCleanerConfigOption (line 25) | type DiskCleanerConfigOption interface
type EmptyDiskCleanerConfigOption (line 33) | type EmptyDiskCleanerConfigOption struct
method apply (line 35) | func (EmptyDiskCleanerConfigOption) apply(*DiskCleanerConfig) {}
type DiskCleanerConfigOptionFunc (line 39) | type DiskCleanerConfigOptionFunc
method apply (line 41) | func (f DiskCleanerConfigOptionFunc) apply(do *DiskCleanerConfig) {
function _DiskCleanerConfigOptionWithDefault (line 46) | func _DiskCleanerConfigOptionWithDefault() DiskCleanerConfigOption {
method ApplyOptions (line 51) | func (o *DiskCleanerConfig) ApplyOptions(options ...DiskCleanerConfigOpt...
FILE: pkg/file-cleanup/disk_cleaner_test.go
function diskUsageCallBack (line 35) | func diskUsageCallBack(diskPath string, diskUsage float32) {
function TestDiskCleanerSerivce (line 39) | func TestDiskCleanerSerivce(t *testing.T) {
FILE: pkg/file-cleanup/file_cleaner.go
type FileCleaner (line 33) | type FileCleaner struct
function FileCleanup (line 42) | func FileCleanup(pattern string, options ...FileCleanerOption) error {
type RotatedFiles (line 99) | type RotatedFiles
method Len (line 101) | func (f RotatedFiles) Len() int {
method Swap (line 105) | func (f RotatedFiles) Swap(i, j int) {
method Less (line 109) | func (f RotatedFiles) Less(i, j int) bool {
FILE: pkg/file-cleanup/file_cleaner.option.go
function WithMaxAge (line 28) | func WithMaxAge(maxAge time.Duration) FileCleanerOption {
function WithMaxCount (line 34) | func WithMaxCount(maxCount int64) FileCleanerOption {
FILE: pkg/file-cleanup/file_cleaner_option.go
type FileCleanerOption (line 25) | type FileCleanerOption interface
type EmptyFileCleanerOption (line 33) | type EmptyFileCleanerOption struct
method apply (line 35) | func (EmptyFileCleanerOption) apply(*FileCleaner) {}
type FileCleanerOptionFunc (line 39) | type FileCleanerOptionFunc
method apply (line 41) | func (f FileCleanerOptionFunc) apply(do *FileCleaner) {
function _FileCleanerOptionWithDefault (line 46) | func _FileCleanerOptionWithDefault() FileCleanerOption {
method ApplyOptions (line 51) | func (o *FileCleaner) ApplyOptions(options ...FileCleanerOption) *FileCl...
FILE: pkg/file-cleanup/file_cleaner_test.go
function TestFileCleanupWithMaxAge (line 31) | func TestFileCleanupWithMaxAge(t *testing.T) {
FILE: pkg/file-rotate/rotate_file.go
type EventCallbackFunc (line 43) | type EventCallbackFunc
type RotateFiler (line 45) | type RotateFiler struct
method Write (line 111) | func (f *RotateFiler) Write(p []byte) (file *os.File, n int, err error) {
method WriteBytesLine (line 124) | func (f *RotateFiler) WriteBytesLine(p [][]byte) (file *os.File, n int...
method generateRotateFilename (line 134) | func (f *RotateFiler) generateRotateFilename() string {
method watch (line 142) | func (f *RotateFiler) watch() {
method getWriterNolock (line 158) | func (f *RotateFiler) getWriterNolock(length int64) (io.Writer, error) {
method generateNextSeqFilename (line 231) | func (f *RotateFiler) generateNextSeqFilename(filePath string) (string...
method getCurSeqFilename (line 259) | func (f *RotateFiler) getCurSeqFilename(globPath string) (string, erro...
method extractSeq (line 274) | func (f *RotateFiler) extractSeq(filePath string) uint64 {
function NewRotateFiler (line 71) | func NewRotateFiler(filedir string, options ...RotateFilerOption) (*Rota...
function globFromFileTimeLayout (line 99) | func globFromFileTimeLayout(filePath string) string {
FILE: pkg/file-rotate/rotate_file.option.go
function WithPrefixName (line 28) | func WithPrefixName(prefixName string) RotateFilerOption {
function WithFileTimeLayout (line 34) | func WithFileTimeLayout(fileTimeLayout string) RotateFilerOption {
function WithSuffixName (line 40) | func WithSuffixName(subfixName string) RotateFilerOption {
function WithMaxAge (line 46) | func WithMaxAge(maxAge time.Duration) RotateFilerOption {
function WithMaxCount (line 52) | func WithMaxCount(maxCount int64) RotateFilerOption {
function WithRotateSize (line 58) | func WithRotateSize(rotateSize int64) RotateFilerOption {
function WithRotateInterval (line 64) | func WithRotateInterval(rotateInterval time.Duration) RotateFilerOption {
function WithRotateCallback (line 70) | func WithRotateCallback(callback EventCallbackFunc) RotateFilerOption {
FILE: pkg/file-rotate/rotate_file_option.go
type RotateFilerOption (line 25) | type RotateFilerOption interface
type EmptyRotateFilerOption (line 33) | type EmptyRotateFilerOption struct
method apply (line 35) | func (EmptyRotateFilerOption) apply(*RotateFiler) {}
type RotateFilerOptionFunc (line 39) | type RotateFilerOptionFunc
method apply (line 41) | func (f RotateFilerOptionFunc) apply(do *RotateFiler) {
function _RotateFilerOptionWithDefault (line 46) | func _RotateFilerOptionWithDefault() RotateFilerOption {
method ApplyOptions (line 51) | func (o *RotateFiler) ApplyOptions(options ...RotateFilerOption) *Rotate...
FILE: pkg/file-rotate/rotate_file_test.go
function getWdOrDie (line 37) | func getWdOrDie() string {
function TestRotateFileWithInterval (line 46) | func TestRotateFileWithInterval(t *testing.T) {
function TestRotateFileWithIntervalAndSize (line 66) | func TestRotateFileWithIntervalAndSize(t *testing.T) {
function TestRotateFileWithSize (line 87) | func TestRotateFileWithSize(t *testing.T) {
function TestRotateMaxCount (line 114) | func TestRotateMaxCount(t *testing.T) {
function TestRegex (line 135) | func TestRegex(t *testing.T) {
FILE: pkg/file-transfer/config.go
type Config (line 32) | type Config struct
method Complete (line 83) | func (c *Config) Complete() CompletedConfig {
method loadViper (line 95) | func (c *Config) loadViper() error {
type completedConfig (line 40) | type completedConfig struct
method New (line 50) | func (c *completedConfig) New(ctx context.Context) (*FileTransfer, err...
method install (line 71) | func (c *completedConfig) install(ctx context.Context) (*FileTransfer,...
type CompletedConfig (line 45) | type CompletedConfig struct
function NewConfig (line 103) | func NewConfig(options ...ConfigOption) *Config {
FILE: pkg/file-transfer/config.option.go
function WithViper (line 28) | func WithViper(v *viper.Viper) ConfigOption {
FILE: pkg/file-transfer/config_option.go
type ConfigOption (line 25) | type ConfigOption interface
type EmptyConfigOption (line 33) | type EmptyConfigOption struct
method apply (line 35) | func (EmptyConfigOption) apply(*Config) {}
type ConfigOptionFunc (line 39) | type ConfigOptionFunc
method apply (line 41) | func (f ConfigOptionFunc) apply(do *Config) {
function _ConfigOptionWithDefault (line 46) | func _ConfigOptionWithDefault() ConfigOption {
method ApplyOptions (line 51) | func (o *Config) ApplyOptions(options ...ConfigOption) *Config {
FILE: pkg/file-transfer/file.transfer.go
type FileTransferOptions (line 35) | type FileTransferOptions struct
function defaultFileTransferOptions (line 47) | func defaultFileTransferOptions() FileTransferOptions {
type FileTransfer (line 51) | type FileTransfer struct
method getProxy (line 62) | func (f *FileTransfer) getProxy() *Ft_Proxy {
method Download (line 77) | func (f *FileTransfer) Download(ctx context.Context, downloadUrl strin...
method Upload (line 121) | func (f *FileTransfer) Upload(ctx context.Context, uploadUrl string, b...
function NewFileTransfer (line 55) | func NewFileTransfer(opts ...FileTransferOption) *FileTransfer {
FILE: pkg/file-transfer/file.transfer.option.go
function WithDownloadTimeout (line 26) | func WithDownloadTimeout(downloadTimeout time.Duration) FileTransferOpti...
function WithLoadBalanceMode (line 32) | func WithLoadBalanceMode(mode Ft_LoadBalanceMode) FileTransferOption {
function WithProxies (line 38) | func WithProxies(proxies []*Ft_Proxy) FileTransferOption {
function WithRetryTimes (line 44) | func WithRetryTimes(retryTimes int) FileTransferOption {
function WithRetryInterval (line 50) | func WithRetryInterval(retryInterval time.Duration) FileTransferOption {
FILE: pkg/file-transfer/file.transfer_option.go
type FileTransferOption (line 25) | type FileTransferOption interface
type EmptyFileTransferOption (line 33) | type EmptyFileTransferOption struct
method apply (line 35) | func (EmptyFileTransferOption) apply(*FileTransfer) {}
type FileTransferOptionFunc (line 39) | type FileTransferOptionFunc
method apply (line 41) | func (f FileTransferOptionFunc) apply(do *FileTransfer) {
function _FileTransferOptionWithDefault (line 46) | func _FileTransferOptionWithDefault() FileTransferOption {
method ApplyOptions (line 51) | func (o *FileTransfer) ApplyOptions(options ...FileTransferOption) *File...
FILE: pkg/file-transfer/file.transfer_test.go
function TestDownload (line 33) | func TestDownload(t *testing.T) {
function TestDownloadByProxy (line 62) | func TestDownloadByProxy(t *testing.T) {
FILE: pkg/file-transfer/ft.pb.go
constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Ft_LoadBalanceMode (line 24) | type Ft_LoadBalanceMode
method Enum (line 43) | func (x Ft_LoadBalanceMode) Enum() *Ft_LoadBalanceMode {
method String (line 49) | func (x Ft_LoadBalanceMode) String() string {
method Descriptor (line 53) | func (Ft_LoadBalanceMode) Descriptor() protoreflect.EnumDescriptor {
method Type (line 57) | func (Ft_LoadBalanceMode) Type() protoreflect.EnumType {
method Number (line 61) | func (x Ft_LoadBalanceMode) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 66) | func (Ft_LoadBalanceMode) EnumDescriptor() ([]byte, []int) {
constant Ft_load_balance_mode_first (line 27) | Ft_load_balance_mode_first Ft_LoadBalanceMode = 0
constant Ft_load_balance_mode_random (line 28) | Ft_load_balance_mode_random Ft_LoadBalanceMode = 1
type Ft (line 70) | type Ft struct
method Reset (line 85) | func (x *Ft) Reset() {
method String (line 94) | func (x *Ft) String() string {
method ProtoMessage (line 98) | func (*Ft) ProtoMessage() {}
method ProtoReflect (line 100) | func (x *Ft) ProtoReflect() protoreflect.Message {
method Descriptor (line 113) | func (*Ft) Descriptor() ([]byte, []int) {
method GetEnabled (line 117) | func (x *Ft) GetEnabled() bool {
method GetDownloadTimeout (line 124) | func (x *Ft) GetDownloadTimeout() *duration.Duration {
method GetUploadTimeout (line 131) | func (x *Ft) GetUploadTimeout() *duration.Duration {
method GetRetryTimes (line 138) | func (x *Ft) GetRetryTimes() uint32 {
method GetRetryInterval (line 145) | func (x *Ft) GetRetryInterval() *duration.Duration {
method GetLoadBalanceMode (line 152) | func (x *Ft) GetLoadBalanceMode() Ft_LoadBalanceMode {
method GetProxies (line 159) | func (x *Ft) GetProxies() []*Ft_Proxy {
type Ft_Proxy (line 166) | type Ft_Proxy struct
method Reset (line 179) | func (x *Ft_Proxy) Reset() {
method String (line 188) | func (x *Ft_Proxy) String() string {
method ProtoMessage (line 192) | func (*Ft_Proxy) ProtoMessage() {}
method ProtoReflect (line 194) | func (x *Ft_Proxy) ProtoReflect() protoreflect.Message {
method Descriptor (line 207) | func (*Ft_Proxy) Descriptor() ([]byte, []int) {
method GetTargetHost (line 211) | func (x *Ft_Proxy) GetTargetHost() string {
method GetProxyUrl (line 218) | func (x *Ft_Proxy) GetProxyUrl() string {
method GetProxyHost (line 225) | func (x *Ft_Proxy) GetProxyHost() string {
function file_pkg_file_transfer_ft_proto_rawDescGZIP (line 288) | func file_pkg_file_transfer_ft_proto_rawDescGZIP() []byte {
function init (line 316) | func init() { file_pkg_file_transfer_ft_proto_init() }
function file_pkg_file_transfer_ft_proto_init (line 317) | func file_pkg_file_transfer_ft_proto_init() {
FILE: pkg/file-transfer/upload/upload.svr.go
type UploadPartInput (line 37) | type UploadPartInput struct
constant tmpFileSuffix (line 44) | tmpFileSuffix = "_.tmp"
function UploadFile (line 46) | func UploadFile(
function UploadMultipart (line 103) | func UploadMultipart(
function CompleteMultipartUpload (line 169) | func CompleteMultipartUpload(
FILE: pkg/file-transfer/upload/upload.svr_test.go
function TestUploadMultipart (line 33) | func TestUploadMultipart(t *testing.T) {
function TestCompleteMultipartUpload (line 57) | func TestCompleteMultipartUpload(t *testing.T) {
FILE: pkg/fsnotify/config.go
type Config (line 32) | type Config struct
method Complete (line 83) | func (c *Config) Complete() CompletedConfig {
method loadViper (line 95) | func (c *Config) loadViper() error {
type completedConfig (line 40) | type completedConfig struct
method New (line 50) | func (c *completedConfig) New(ctx context.Context) (*FsnotifyService, ...
method install (line 71) | func (c *completedConfig) install(ctx context.Context) (*FsnotifyServi...
type CompletedConfig (line 45) | type CompletedConfig struct
function NewConfig (line 103) | func NewConfig(options ...ConfigOption) *Config {
FILE: pkg/fsnotify/config.option.go
function WithViper (line 28) | func WithViper(v *viper.Viper) ConfigOption {
FILE: pkg/fsnotify/config_option.go
type ConfigOption (line 25) | type ConfigOption interface
type EmptyConfigOption (line 33) | type EmptyConfigOption struct
method apply (line 35) | func (EmptyConfigOption) apply(*Config) {}
type ConfigOptionFunc (line 39) | type ConfigOptionFunc
method apply (line 41) | func (f ConfigOptionFunc) apply(do *Config) {
function _ConfigOptionWithDefault (line 46) | func _ConfigOptionWithDefault() ConfigOption {
method ApplyOptions (line 51) | func (o *Config) ApplyOptions(options ...ConfigOption) *Config {
FILE: pkg/fsnotify/fsnotify.go
type EventCallbackFunc (line 17) | type EventCallbackFunc
type FsnotifyOptions (line 19) | type FsnotifyOptions struct
type FsnotifyService (line 25) | type FsnotifyService struct
method logger (line 65) | func (srv *FsnotifyService) logger() logrus.FieldLogger {
method Run (line 69) | func (srv *FsnotifyService) Run(ctx context.Context) error {
method Serve (line 82) | func (srv *FsnotifyService) Serve(ctx context.Context) error {
method AddWatchPath (line 154) | func (srv *FsnotifyService) AddWatchPath(unWatch bool, path string) er...
method Add (line 180) | func (srv *FsnotifyService) Add(unWatch bool, path string) (err error) {
method AddWatchPaths (line 196) | func (srv *FsnotifyService) AddWatchPaths(unWatch bool, paths ...strin...
method Shutdown (line 207) | func (srv *FsnotifyService) Shutdown() {
function NewFsnotifyService (line 36) | func NewFsnotifyService(paths []string, opts ...FsnotifyOption) (*Fsnoti...
FILE: pkg/fsnotify/fsnotify.option.go
function WithCreateCallbackFunc (line 24) | func WithCreateCallbackFunc(fn EventCallbackFunc) FsnotifyOption {
function WithWriteCallbackFunc (line 30) | func WithWriteCallbackFunc(fn EventCallbackFunc) FsnotifyOption {
function WithRemoveCallbackFunc (line 36) | func WithRemoveCallbackFunc(fn EventCallbackFunc) FsnotifyOption {
FILE: pkg/fsnotify/fsnotify.pb.go
constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Fsnotify (line 24) | type Fsnotify struct
method Reset (line 33) | func (x *Fsnotify) Reset() {
method String (line 42) | func (x *Fsnotify) String() string {
method ProtoMessage (line 46) | func (*Fsnotify) ProtoMessage() {}
method ProtoReflect (line 48) | func (x *Fsnotify) ProtoReflect() protoreflect.Message {
method Descriptor (line 61) | func (*Fsnotify) Descriptor() ([]byte, []int) {
method GetEnabled (line 65) | func (x *Fsnotify) GetEnabled() bool {
method GetFilePaths (line 72) | func (x *Fsnotify) GetFilePaths() []string {
function file_pkg_fsnotify_fsnotify_proto_rawDescGZIP (line 102) | func file_pkg_fsnotify_fsnotify_proto_rawDescGZIP() []byte {
function init (line 121) | func init() { file_pkg_fsnotify_fsnotify_proto_init() }
function file_pkg_fsnotify_fsnotify_proto_init (line 122) | func file_pkg_fsnotify_fsnotify_proto_init() {
FILE: pkg/fsnotify/fsnotify_option.go
type FsnotifyOption (line 25) | type FsnotifyOption interface
type EmptyFsnotifyOption (line 33) | type EmptyFsnotifyOption struct
method apply (line 35) | func (EmptyFsnotifyOption) apply(*FsnotifyService) {}
type FsnotifyOptionFunc (line 39) | type FsnotifyOptionFunc
method apply (line 41) | func (f FsnotifyOptionFunc) apply(do *FsnotifyService) {
function _FsnotifyOptionWithDefault (line 46) | func _FsnotifyOptionWithDefault() FsnotifyOption {
method ApplyOptions (line 51) | func (o *FsnotifyService) ApplyOptions(options ...FsnotifyOption) *Fsnot...
FILE: pkg/fsnotify/fsnotify_test.go
function TestFsnotify (line 11) | func TestFsnotify(t *testing.T) {
FILE: pkg/gocv/cgo/api/openapi-spec/gocv/gocv.magick.pb.go
constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type OrientationType (line 24) | type OrientationType
method Enum (line 64) | func (x OrientationType) Enum() *OrientationType {
method String (line 70) | func (x OrientationType) String() string {
method Descriptor (line 74) | func (OrientationType) Descriptor() protoreflect.EnumDescriptor {
method Type (line 78) | func (OrientationType) Type() protoreflect.EnumType {
method Number (line 82) | func (x OrientationType) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 87) | func (OrientationType) EnumDescriptor() ([]byte, []int) {
constant OrientationType_UndefinedOrientation (line 27) | OrientationType_UndefinedOrientation OrientationType = 0
constant OrientationType_TopLeftOrientation (line 28) | OrientationType_TopLeftOrientation OrientationType = 1
constant OrientationType_TopRightOrientation (line 29) | OrientationType_TopRightOrientation OrientationType = 2
constant OrientationType_BottomRightOrientation (line 30) | OrientationType_BottomRightOrientation OrientationType = 3
constant OrientationType_BottomLeftOrientation (line 31) | OrientationType_BottomLeftOrientation OrientationType = 4
constant OrientationType_LeftTopOrientation (line 32) | OrientationType_LeftTopOrientation OrientationType = 5
constant OrientationType_RightTopOrientation (line 33) | OrientationType_RightTopOrientation OrientationType = 6
constant OrientationType_RightBottomOrientation (line 34) | OrientationType_RightBottomOrientation OrientationType = 7
constant OrientationType_LeftBottomOrientation (line 35) | OrientationType_LeftBottomOrientation OrientationType = 8
type ColorspaceType (line 92) | type ColorspaceType
method Enum (line 165) | func (x ColorspaceType) Enum() *ColorspaceType {
method String (line 171) | func (x ColorspaceType) String() string {
method Descriptor (line 175) | func (ColorspaceType) Descriptor() protoreflect.EnumDescriptor {
method Type (line 179) | func (ColorspaceType) Type() protoreflect.EnumType {
method Number (line 183) | func (x ColorspaceType) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 188) | func (ColorspaceType) EnumDescriptor() ([]byte, []int) {
constant ColorspaceType_UndefinedColorspace (line 95) | ColorspaceType_UndefinedColorspace ColorspaceType = 0
constant ColorspaceType_RGBColorspace (line 96) | ColorspaceType_RGBColorspace ColorspaceType = 1
constant ColorspaceType_GRAYColorspace (line 97) | ColorspaceType_GRAYColorspace ColorspaceType = 2
constant ColorspaceType_TransparentColorspace (line 98) | ColorspaceType_TransparentColorspace ColorspaceType = 3
constant ColorspaceType_OHTAColorspace (line 99) | ColorspaceType_OHTAColorspace ColorspaceType = 4
constant ColorspaceType_XYZColorspace (line 100) | ColorspaceType_XYZColorspace ColorspaceType = 5
constant ColorspaceType_YCCColorspace (line 101) | ColorspaceType_YCCColorspace ColorspaceType = 6
constant ColorspaceType_YIQColorspace (line 102) | ColorspaceType_YIQColorspace ColorspaceType = 7
constant ColorspaceType_YPbPrColorspace (line 103) | ColorspaceType_YPbPrColorspace ColorspaceType = 8
constant ColorspaceType_YUVColorspace (line 104) | ColorspaceType_YUVColorspace ColorspaceType = 9
constant ColorspaceType_CMYKColorspace (line 105) | ColorspaceType_CMYKColorspace ColorspaceType = 10
constant ColorspaceType_sRGBColorspace (line 106) | ColorspaceType_sRGBColorspace ColorspaceType = 11
constant ColorspaceType_HSLColorspace (line 107) | ColorspaceType_HSLColorspace ColorspaceType = 12
constant ColorspaceType_HWBColorspace (line 108) | ColorspaceType_HWBColorspace ColorspaceType = 13
constant ColorspaceType_LABColorspace (line 109) | ColorspaceType_LABColorspace ColorspaceType = 14
constant ColorspaceType_CineonLogRGBColorspace (line 110) | ColorspaceType_CineonLogRGBColorspace ColorspaceType = 15
constant ColorspaceType_Rec601LumaColorspace (line 111) | ColorspaceType_Rec601LumaColorspace ColorspaceType = 16
constant ColorspaceType_Rec601YCbCrColorspace (line 112) | ColorspaceType_Rec601YCbCrColorspace ColorspaceType = 17
constant ColorspaceType_Rec709LumaColorspace (line 113) | ColorspaceType_Rec709LumaColorspace ColorspaceType = 18
constant ColorspaceType_Rec709YCbCrColorspace (line 114) | ColorspaceType_Rec709YCbCrColorspace ColorspaceType = 19
type MagickInitializeMagickRequest (line 192) | type MagickInitializeMagickRequest struct
method Reset (line 200) | func (x *MagickInitializeMagickRequest) Reset() {
method String (line 209) | func (x *MagickInitializeMagickRequest) String() string {
method ProtoMessage (line 213) | func (*MagickInitializeMagickRequest) ProtoMessage() {}
method ProtoReflect (line 215) | func (x *MagickInitializeMagickRequest) ProtoReflect() protoreflect.Me...
method Descriptor (line 228) | func (*MagickInitializeMagickRequest) Descriptor() ([]byte, []int) {
method GetPath (line 232) | func (x *MagickInitializeMagickRequest) GetPath() string {
type MagickInitializeMagickResponse (line 239) | type MagickInitializeMagickResponse struct
method Reset (line 247) | func (x *MagickInitializeMagickResponse) Reset() {
method String (line 256) | func (x *MagickInitializeMagickResponse) String() string {
method ProtoMessage (line 260) | func (*MagickInitializeMagickResponse) ProtoMessage() {}
method ProtoReflect (line 262) | func (x *MagickInitializeMagickResponse) ProtoReflect() protoreflect.M...
method Descriptor (line 275) | func (*MagickInitializeMagickResponse) Descriptor() ([]byte, []int) {
method GetError (line 279) | func (x *MagickInitializeMagickResponse) GetError() *code.CgoError {
type MagickImageDecodeRequest (line 286) | type MagickImageDecodeRequest struct
method Reset (line 295) | func (x *MagickImageDecodeRequest) Reset() {
method String (line 304) | func (x *MagickImageDecodeRequest) String() string {
method ProtoMessage (line 308) | func (*MagickImageDecodeRequest) ProtoMessage() {}
method ProtoReflect (line 310) | func (x *MagickImageDecodeRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 323) | func (*MagickImageDecodeRequest) Descriptor() ([]byte, []int) {
method GetImage (line 327) | func (x *MagickImageDecodeRequest) GetImage() []byte {
method GetTargetColorSpace (line 334) | func (x *MagickImageDecodeRequest) GetTargetColorSpace() string {
type MagickImageDecodeResponse (line 341) | type MagickImageDecodeResponse struct
method Reset (line 355) | func (x *MagickImageDecodeResponse) Reset() {
method String (line 364) | func (x *MagickImageDecodeResponse) String() string {
method ProtoMessage (line 368) | func (*MagickImageDecodeResponse) ProtoMessage() {}
method ProtoReflect (line 370) | func (x *MagickImageDecodeResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 383) | func (*MagickImageDecodeResponse) Descriptor() ([]byte, []int) {
method GetError (line 387) | func (x *MagickImageDecodeResponse) GetError() *code.CgoError {
method GetCvMatPointer (line 394) | func (x *MagickImageDecodeResponse) GetCvMatPointer() int64 {
method GetRows (line 401) | func (x *MagickImageDecodeResponse) GetRows() int64 {
method GetColumns (line 408) | func (x *MagickImageDecodeResponse) GetColumns() int64 {
method GetMagick (line 415) | func (x *MagickImageDecodeResponse) GetMagick() string {
method GetOrientationType (line 422) | func (x *MagickImageDecodeResponse) GetOrientationType() OrientationTy...
method GetColorspaceType (line 429) | func (x *MagickImageDecodeResponse) GetColorspaceType() ColorspaceType {
function file_gocv_gocv_magick_proto_rawDescGZIP (line 536) | func file_gocv_gocv_magick_proto_rawDescGZIP() []byte {
function init (line 566) | func init() { file_gocv_gocv_magick_proto_init() }
function file_gocv_gocv_magick_proto_init (line 567) | func file_gocv_gocv_magick_proto_init() {
FILE: pkg/gocv/cgo/api/openapi-spec/gocv/gocv.magick.pb.h
type TableStruct (line 40) | struct TableStruct {
function namespace (line 50) | namespace sdk {
function namespace (line 68) | namespace google {
function namespace (line 78) | namespace gocv {
function namespace (line 1069) | namespace google {
FILE: pkg/gocv/cgo/api/openapi-spec/types/code/code.error.go
method Error (line 29) | func (x *CgoError) Error() string {
FILE: pkg/gocv/cgo/api/openapi-spec/types/code/sdk-go.code.pb.go
constant _ (line 18) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 20) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type Code (line 23) | type Code
method Enum (line 217) | func (x Code) Enum() *Code {
method String (line 223) | func (x Code) String() string {
method Descriptor (line 227) | func (Code) Descriptor() protoreflect.EnumDescriptor {
method Type (line 231) | func (Code) Type() protoreflect.EnumType {
method Number (line 235) | func (x Code) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 240) | func (Code) EnumDescriptor() ([]byte, []int) {
constant Code_OK (line 27) | Code_OK Code = 0
constant Code_Canceled (line 33) | Code_Canceled Code = 1
constant Code_Unknown (line 42) | Code_Unknown Code = 2
constant Code_InvalidArgument (line 49) | Code_InvalidArgument Code = 3
constant Code_DeadlineExceeded (line 58) | Code_DeadlineExceeded Code = 4
constant Code_NotFound (line 63) | Code_NotFound Code = 5
constant Code_AlreadyExists (line 68) | Code_AlreadyExists Code = 6
constant Code_PermissionDenied (line 78) | Code_PermissionDenied Code = 7
constant Code_ResourceExhausted (line 85) | Code_ResourceExhausted Code = 8
constant Code_FailedPrecondition (line 107) | Code_FailedPrecondition Code = 9
constant Code_Aborted (line 116) | Code_Aborted Code = 10
constant Code_OutOfRange (line 134) | Code_OutOfRange Code = 11
constant Code_Unimplemented (line 143) | Code_Unimplemented Code = 12
constant Code_Internal (line 150) | Code_Internal Code = 13
constant Code_Unavailable (line 161) | Code_Unavailable Code = 14
constant Code_DataLoss (line 165) | Code_DataLoss Code = 15
constant Code_Unauthenticated (line 172) | Code_Unauthenticated Code = 16
type CgoError (line 244) | type CgoError struct
method Reset (line 255) | func (x *CgoError) Reset() {
method String (line 264) | func (x *CgoError) String() string {
method ProtoMessage (line 268) | func (*CgoError) ProtoMessage() {}
method ProtoReflect (line 270) | func (x *CgoError) ProtoReflect() protoreflect.Message {
method Descriptor (line 283) | func (*CgoError) Descriptor() ([]byte, []int) {
method GetErrorCode (line 287) | func (x *CgoError) GetErrorCode() Code {
method GetErrorMessage (line 294) | func (x *CgoError) GetErrorMessage() string {
method GetSdkErrorCode (line 301) | func (x *CgoError) GetSdkErrorCode() int32 {
method GetSdkErrorMessage (line 308) | func (x *CgoError) GetSdkErrorMessage() string {
function file_types_code_sdk_go_code_proto_rawDescGZIP (line 364) | func file_types_code_sdk_go_code_proto_rawDescGZIP() []byte {
function init (line 386) | func init() { file_types_code_sdk_go_code_proto_init() }
function file_types_code_sdk_go_code_proto_init (line 387) | func file_types_code_sdk_go_code_proto_init() {
FILE: pkg/gocv/cgo/api/openapi-spec/types/code/sdk-go.code.pb.h
type TableStruct (line 39) | struct TableStruct {
function namespace (line 49) | namespace sdk {
function namespace (line 58) | namespace google {
function namespace (line 64) | namespace types {
function namespace (line 398) | namespace google {
FILE: pkg/gocv/cgo/api/openapi-spec/types/sdk-go.types.pb.go
constant _ (line 18) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 20) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
constant Code_OK (line 27) | Code_OK = code.Code_OK
constant Code_Canceled (line 28) | Code_Canceled = code.Code_Canceled
constant Code_Unknown (line 29) | Code_Unknown = code.Code_Unknown
constant Code_InvalidArgument (line 30) | Code_InvalidArgument = code.Code_InvalidArgument
constant Code_DeadlineExceeded (line 31) | Code_DeadlineExceeded = code.Code_DeadlineExceeded
constant Code_NotFound (line 32) | Code_NotFound = code.Code_NotFound
constant Code_AlreadyExists (line 33) | Code_AlreadyExists = code.Code_AlreadyExists
constant Code_PermissionDenied (line 34) | Code_PermissionDenied = code.Code_PermissionDenied
constant Code_ResourceExhausted (line 35) | Code_ResourceExhausted = code.Code_ResourceExhausted
constant Code_FailedPrecondition (line 36) | Code_FailedPrecondition = code.Code_FailedPrecondition
constant Code_Aborted (line 37) | Code_Aborted = code.Code_Aborted
constant Code_OutOfRange (line 38) | Code_OutOfRange = code.Code_OutOfRange
constant Code_Unimplemented (line 39) | Code_Unimplemented = code.Code_Unimplemented
constant Code_Internal (line 40) | Code_Internal = code.Code_Internal
constant Code_Unavailable (line 41) | Code_Unavailable = code.Code_Unavailable
constant Code_DataLoss (line 42) | Code_DataLoss = code.Code_DataLoss
constant Code_Unauthenticated (line 43) | Code_Unauthenticated = code.Code_Unauthenticated
function init (line 75) | func init() { file_types_sdk_go_types_proto_init() }
function file_types_sdk_go_types_proto_init (line 76) | func file_types_sdk_go_types_proto_init() {
FILE: pkg/gocv/cgo/api/openapi-spec/types/sdk-go.types.pb.h
type TableStruct (line 37) | struct TableStruct {
function namespace (line 47) | namespace sdk {
function namespace (line 53) | namespace sdk {
FILE: pkg/gocv/cgo/gocv/gocv.go
function NewMagickInitializeMagickRequest (line 30) | func NewMagickInitializeMagickRequest() *gocv.MagickInitializeMagickRequ...
function NewMagickImageDecodeRequest (line 36) | func NewMagickImageDecodeRequest() *gocv.MagickImageDecodeRequest {
FILE: pkg/gocv/cgo/gocv/gocv_test.go
function TestMagickInitializeMagick (line 31) | func TestMagickInitializeMagick(t *testing.T) {
function TestMagickImageDecode (line 34) | func TestMagickImageDecode(t *testing.T) {
FILE: pkg/gocv/cgo/gocv/magick_linux_amd64.cpp
function sdk_gocv_magick_initialize_magick (line 8) | void sdk_gocv_magick_initialize_magick(void* req_data, int req_data_len,
function sdk_gocv_magick_image_decode (line 52) | void sdk_gocv_magick_image_decode(void* req_data, int req_data_len,
FILE: pkg/gocv/cgo/gocv/magick_linux_amd64.go
function init (line 45) | func init() {
function MagickInitializeMagick (line 52) | func MagickInitializeMagick(req *gocvpb.MagickInitializeMagickRequest) e...
function MagickImageDecode (line 92) | func MagickImageDecode(req *gocvpb.MagickImageDecodeRequest) (*gocvpb.Ma...
FILE: pkg/gocv/cgo/swig/gocv/gocv.go
type _ (line 109) | type _
type _swig_fnptr (line 117) | type _swig_fnptr
type _swig_memberptr (line 118) | type _swig_memberptr
function getSwigcptr (line 121) | func getSwigcptr(v interface { Swigcptr() uintptr }) uintptr {
type _ (line 129) | type _
function cgo_panic__gocv_ba346308b44e7b91 (line 132) | func cgo_panic__gocv_ba346308b44e7b91(p *byte) {
type swig_gostring (line 143) | type swig_gostring struct
function swigCopyString (line 144) | func swigCopyString(s string) string {
function Swig_free (line 151) | func Swig_free(arg1 uintptr) {
function Swig_malloc (line 156) | func Swig_malloc(arg1 int) (_swig_ret uintptr) {
type SwigcptrMagickInitializeMagickRequest (line 163) | type SwigcptrMagickInitializeMagickRequest
method Swigcptr (line 165) | func (p SwigcptrMagickInitializeMagickRequest) Swigcptr() uintptr {
method SwigIsMagickInitializeMagickRequest (line 169) | func (p SwigcptrMagickInitializeMagickRequest) SwigIsMagickInitializeM...
method SetPath (line 172) | func (arg1 SwigcptrMagickInitializeMagickRequest) SetPath(arg2 string) {
method GetPath (line 181) | func (arg1 SwigcptrMagickInitializeMagickRequest) GetPath() (_swig_ret...
function NewMagickInitializeMagickRequest (line 191) | func NewMagickInitializeMagickRequest() (_swig_ret MagickInitializeMagic...
function DeleteMagickInitializeMagickRequest (line 197) | func DeleteMagickInitializeMagickRequest(arg1 MagickInitializeMagickRequ...
type MagickInitializeMagickRequest (line 202) | type MagickInitializeMagickRequest interface
type SwigcptrMagickInitializeMagickResponse (line 209) | type SwigcptrMagickInitializeMagickResponse
method Swigcptr (line 211) | func (p SwigcptrMagickInitializeMagickResponse) Swigcptr() uintptr {
method SwigIsMagickInitializeMagickResponse (line 215) | func (p SwigcptrMagickInitializeMagickResponse) SwigIsMagickInitialize...
function NewMagickInitializeMagickResponse (line 218) | func NewMagickInitializeMagickResponse() (_swig_ret MagickInitializeMagi...
function DeleteMagickInitializeMagickResponse (line 224) | func DeleteMagickInitializeMagickResponse(arg1 MagickInitializeMagickRes...
type MagickInitializeMagickResponse (line 229) | type MagickInitializeMagickResponse interface
type SwigcptrMagickImageDecodeRequest (line 234) | type SwigcptrMagickImageDecodeRequest
method Swigcptr (line 236) | func (p SwigcptrMagickImageDecodeRequest) Swigcptr() uintptr {
method SwigIsMagickImageDecodeRequest (line 240) | func (p SwigcptrMagickImageDecodeRequest) SwigIsMagickImageDecodeReque...
method SetImage (line 243) | func (arg1 SwigcptrMagickImageDecodeRequest) SetImage(arg2 string) {
method GetImage (line 252) | func (arg1 SwigcptrMagickImageDecodeRequest) GetImage() (_swig_ret str...
method SetTarget_color_space (line 262) | func (arg1 SwigcptrMagickImageDecodeRequest) SetTarget_color_space(arg...
method GetTarget_color_space (line 271) | func (arg1 SwigcptrMagickImageDecodeRequest) GetTarget_color_space() (...
function NewMagickImageDecodeRequest (line 281) | func NewMagickImageDecodeRequest() (_swig_ret MagickImageDecodeRequest) {
function DeleteMagickImageDecodeRequest (line 287) | func DeleteMagickImageDecodeRequest(arg1 MagickImageDecodeRequest) {
type MagickImageDecodeRequest (line 292) | type MagickImageDecodeRequest interface
type GocvOrientationType (line 301) | type GocvOrientationType
function _swig_getUndefinedOrientation (line 302) | func _swig_getUndefinedOrientation() (_swig_ret GocvOrientationType) {
function _swig_getTopLeftOrientation (line 309) | func _swig_getTopLeftOrientation() (_swig_ret GocvOrientationType) {
function _swig_getTopRightOrientation (line 316) | func _swig_get
Copy disabled (too large)
Download .json
Condensed preview — 1959 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (26,227K chars).
[
{
"path": ".gitattributes",
"chars": 46,
"preview": "pkg/gocv/cgo/third_path/** linguist-vendored \n"
},
{
"path": ".gitignore",
"chars": 810,
"preview": "#\n# NOTE! Please use 'git ls-files -i --exclude-standard'\n# command after changing this file, to see if there are\n# any "
},
{
"path": "LICENSE",
"chars": 1060,
"preview": "MIT License\n\nCopyright (c) 2020 kay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof thi"
},
{
"path": "README.md",
"chars": 6156,
"preview": "# golang\n\nGolang lib is a comprehensive programming toolkit for building microservices in Go. It provides a rich set of "
},
{
"path": "doc/health_check_design.md",
"chars": 9076,
"preview": "# 健康检查增强功能设计文档\n\n## 1. 概述\n\n本文档描述了 golang 库中健康检查(Health Check)功能的设计思路和实现细节。该功能提供了 Kubernetes 兼容的健康检查端点,支持存活探针(Liveness)和就绪"
},
{
"path": "doc/opentelemetry_design.md",
"chars": 43728,
"preview": "# OpenTelemetry 监控设计文档\n\n## 1. 概述\n\n本文档描述了 golang 库中 OpenTelemetry 监控功能的设计思路和实现细节。该功能提供统一的可观测性能力,支持 **Metrics(指标)**、**Trac"
},
{
"path": "doc/rate_limit_design.md",
"chars": 16972,
"preview": "# 限流增强功能设计文档\n\n## 1. 概述\n\n本文档描述了 golang 库中限流(Rate Limit)功能的增强设计,支持**基于 QPS 的限流**、**并发数控制**和**不同接口不同限流策略**的能力。\n\n## 2. 限流模式分"
},
{
"path": "doc.go",
"chars": 55,
"preview": "package golang\n\nimport _ \"github.com/kaydxh/golang/go\"\n"
},
{
"path": "go/archive/archive.go",
"chars": 1590,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/archive/option/file_info.go",
"chars": 1747,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/archive/zip/zip.go",
"chars": 5398,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/archive/zip/zip_test.go",
"chars": 1683,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/bytes/bytes.go",
"chars": 1668,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/bytes/bytes_test.go",
"chars": 943,
"preview": "package bytes_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"unsafe\"\n\n\tbytes_ \"github.com/kaydxh/golang/go/bytes\"\n)\n\nfunc TestEncod"
},
{
"path": "go/client/client.go",
"chars": 1504,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/client/client.options.go",
"chars": 1240,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/client/client_options.go",
"chars": 1970,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/client/client_test.go",
"chars": 1299,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/container/heap/heap.go",
"chars": 9732,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/container/heap/heap_test.go",
"chars": 4703,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/container/set/set.go",
"chars": 5034,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/container/set/set.interface.go",
"chars": 7313,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/container/set/set_interface_test.go",
"chars": 4173,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/container/set/set_string.go",
"chars": 5307,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/container/set/set_string_test.go",
"chars": 4197,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/container/set/set_test.go",
"chars": 2083,
"preview": "package set_test\n\nimport (\n\t\"testing\"\n\n\tset_ \"github.com/kaydxh/golang/go/container/set\"\n)\n\nfunc TestGenericSetNew(t *te"
},
{
"path": "go/container/workqueue/queue.go",
"chars": 5668,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/container/workqueue/queue_test.go",
"chars": 3014,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/context/context.go",
"chars": 3363,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/context/context_test.go",
"chars": 3391,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/crypto/aes/aes_cbc.go",
"chars": 2670,
"preview": "/*\nMIT License\n\nCopyright (c) 2020 kay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "go/crypto/aes/aes_cbc_test.go",
"chars": 2466,
"preview": "/*\nMIT License\n\nCopyright (c) 2020 kay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "go/crypto/aes/error.go",
"chars": 1270,
"preview": "/*\nMIT License\n\nCopyright (c) 2020 kay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "go/crypto/md5/md5.go",
"chars": 2678,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/crypto/md5/md5_test.go",
"chars": 2880,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/crypto/sha256/sha256.go",
"chars": 2696,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/crypto/sha256/sha256_test.go",
"chars": 2907,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/doc.go",
"chars": 12,
"preview": "package _go\n"
},
{
"path": "go/encoding/base64/base64.go",
"chars": 1737,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/base64/base64_test.go",
"chars": 4145,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/hash/hash.go",
"chars": 1204,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/hash/hash_test.go",
"chars": 1701,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/jwt/jwt.go",
"chars": 3127,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/jwt/jwt_test.go",
"chars": 3460,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/protojson/decode.go",
"chars": 1598,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/protojson/decode.option.go",
"chars": 1575,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/protojson/decode_option.go",
"chars": 2070,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/protojson/encode.go",
"chars": 1547,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/protojson/encode.option.go",
"chars": 1738,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/protojson/encode_option.go",
"chars": 2030,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/protojson/protojson_test.go",
"chars": 1745,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/protojson/testdata/date.pb.go",
"chars": 9045,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/encoding/protojson/testdata/date.proto",
"chars": 361,
"preview": "syntax = \"proto3\";\n\npackage golang.go.encoding.date.v1;\nimport \"google/protobuf/descriptor.proto\";\n\noption go_package = "
},
{
"path": "go/errors/error.code.go",
"chars": 84,
"preview": "package errors\n\nimport \"errors\"\n\nvar (\n\tErrNotEnabled = errors.New(\"not enabled\")\n)\n"
},
{
"path": "go/errors/error.grpc.go",
"chars": 3086,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/errors/errors.go",
"chars": 3037,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/errors/errors_test.go",
"chars": 3277,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/errors/handler.go",
"chars": 2522,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/filesystem/filesystem.go",
"chars": 2153,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/filesystem/mountpoint.go",
"chars": 11015,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/flag/flag.go",
"chars": 3720,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/go.mod",
"chars": 2492,
"preview": "module github.com/kaydxh/golang/go\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/gin-gonic/gin v1.11.0\n\tgithub.com/go-playground/val"
},
{
"path": "go/go.sum",
"chars": 11800,
"preview": "github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=\ngithub.c"
},
{
"path": "go/idgen/id_gen.go",
"chars": 3914,
"preview": "// Package idgen 提供基于 Snowflake 算法的分布式唯一 ID 生成器\n//\n// ID 结构 (64位):\n// - 1位: 保留位(始终为0)\n// - 41位: 时间戳(毫秒级)\n// - 10位:"
},
{
"path": "go/idgen/id_gen_test.go",
"chars": 8510,
"preview": "package idgen\n\nimport (\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n)\n\n// TestNewGenerator 测试生成器的创建\nfunc TestNewGenerator(t *testing.T) {"
},
{
"path": "go/idgen/wk_id_gen.go",
"chars": 5499,
"preview": "package idgen\n\nimport (\n\t\"crypto/md5\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n)\n\n// WorkerIDGenerator 用于根据机器信息"
},
{
"path": "go/idgen/wk_id_gen_test.go",
"chars": 7641,
"preview": "package idgen\n\nimport (\n\t\"os\"\n\t\"testing\"\n)\n\n// TestGenerateWorkerID 测试自动生成 WorkerID\nfunc TestGenerateWorkerID(t *testing"
},
{
"path": "go/io/copy.go",
"chars": 4397,
"preview": "/*\nMIT License\n\nCopyright (c) 2020 kay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "go/io/copy_darwin.go",
"chars": 1384,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/io/copy_linux.go",
"chars": 3340,
"preview": "/*\nMIT License\n\nCopyright (c) 2020 kay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "go/io/copy_test.go",
"chars": 4407,
"preview": "/*\nMIT License\n\nCopyright (c) 2020 kay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "go/io/io.go",
"chars": 6870,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/io/io_test.go",
"chars": 8230,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/io/testdata/dir/file/1.txt",
"chars": 11,
"preview": "hello word\n"
},
{
"path": "go/io/testdata/dir/hello.text",
"chars": 11,
"preview": "hello word\n"
},
{
"path": "go/io/testdata/file/1.txt",
"chars": 11,
"preview": "hello word\n"
},
{
"path": "go/math/exp/exp.go",
"chars": 1856,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/math/exp/exp_test.go",
"chars": 2144,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/math/math.go",
"chars": 1279,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/math/math_test.go",
"chars": 1615,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/math/rand/rand.go",
"chars": 3015,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/math/rand/rand_test.go",
"chars": 2913,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/grpc/example/data.pb.go",
"chars": 9569,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.36.10\n// \tprotoc v5.29.3\n// so"
},
{
"path": "go/net/grpc/example/data.proto",
"chars": 934,
"preview": "syntax = \"proto3\";\n\npackage sea.api.seadate;\nimport \"google/protobuf/descriptor.proto\";\n\noption go_package = \"github.com"
},
{
"path": "go/net/grpc/example/data.repository.go",
"chars": 515,
"preview": "package v1\n\nimport (\n\t\"context\"\n\n\tgrpc_ \"github.com/kaydxh/golang/go/net/grpc\"\n)\n\ntype Repository struct {\n\tgrpc_.Reposi"
},
{
"path": "go/net/grpc/example/data.repository_test.go",
"chars": 1709,
"preview": "package v1_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"context\"\n\n\tgrpc_ \"github.com/kaydxh/golang/go/net/grpc\"\n\tdate_ \"github.c"
},
{
"path": "go/net/grpc/example/data_grpc.pb.go",
"chars": 6050,
"preview": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n// versions:\n// - protoc-gen-go-grpc v1.5.1\n// - protoc "
},
{
"path": "go/net/grpc/grpc_client.go",
"chars": 7355,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/grpc/grpc_client.option.go",
"chars": 2118,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/grpc/grpc_client.repository.factory.go",
"chars": 3900,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/grpc/grpc_client.repository.go",
"chars": 1729,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/grpc/grpc_client_option.go",
"chars": 1855,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/grpc/grpc_client_test.go",
"chars": 1766,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/grpc/grpc_stats.handler.go",
"chars": 2660,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/grpc/ip.go",
"chars": 2290,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/clone.go",
"chars": 1874,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/example/data.pb.go",
"chars": 8055,
"preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.28.1\n// \tprotoc v3.13.0\n// sou"
},
{
"path": "go/net/http/example/data.proto",
"chars": 471,
"preview": "syntax = \"proto3\";\n\npackage sea.api.date;\nimport \"google/protobuf/descriptor.proto\";\n\noption go_package = \"github.com/ka"
},
{
"path": "go/net/http/example/http_client.repository_test.go",
"chars": 1664,
"preview": "package date_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"context\"\n\n\thttp_ \"github.com/kaydxh/golang/go/net/http\"\n\tdate_ \"github"
},
{
"path": "go/net/http/http_client.do.go",
"chars": 2904,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_client.go",
"chars": 8196,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_client.option.go",
"chars": 2611,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_client.repository.factory.go",
"chars": 2911,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_client.repository.go",
"chars": 6057,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_client_option.go",
"chars": 1965,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_client_proxy.go",
"chars": 1607,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_client_test.go",
"chars": 3900,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_error.go",
"chars": 1318,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_handler_chain.option.go",
"chars": 2091,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_handler_interceptor.go",
"chars": 2479,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_handler_interceptor.option.go",
"chars": 2217,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_host_context.go",
"chars": 1866,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_proxy_context.go",
"chars": 2104,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_request_id.go",
"chars": 2992,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_round_trip.go",
"chars": 1310,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_transport.go",
"chars": 1729,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_transport.host.go",
"chars": 2457,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/http_transport.proxy.go",
"chars": 2734,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/ip.go",
"chars": 1835,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/http/response_writer.go",
"chars": 2632,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/ip.go",
"chars": 6532,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/ip_test.go",
"chars": 2605,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/mac.go",
"chars": 1848,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/mac_test.go",
"chars": 1555,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/parse.go",
"chars": 5167,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/build.go",
"chars": 4058,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/build.option.go",
"chars": 1337,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/build_option.go",
"chars": 2182,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/dns/dns_resolver.go",
"chars": 11994,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/dns/dns_resolver_builder.option.go",
"chars": 1292,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/dns/dns_resolver_builder_option.go",
"chars": 2055,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/passthrough/passthrough.go",
"chars": 2126,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/register.reslover.go",
"chars": 3140,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/resolve/resolve.go",
"chars": 1818,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/resolve.all.option.go",
"chars": 1274,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/resolve.all_option.go",
"chars": 2116,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/resolve.now_option.go",
"chars": 2116,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/resolve.one.option.go",
"chars": 1425,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/resolve.one_option.go",
"chars": 2116,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/resolver.go",
"chars": 3097,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/resolver_test.go",
"chars": 3272,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/target.go",
"chars": 5557,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/resolver/unix/unix.go",
"chars": 2519,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/url/url.go",
"chars": 5047,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/url/url.resolve.go",
"chars": 1522,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/url/url_codec.go",
"chars": 1442,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/url/url_option.go",
"chars": 1964,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/url/url_test.go",
"chars": 1917,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/net/url/value.go",
"chars": 2581,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/env.go",
"chars": 2165,
"preview": "/*\nMIT License\n\nCopyright (c) 2020 kay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "go/os/env_test.go",
"chars": 3346,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/exec/exec.go",
"chars": 2987,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/exec/exec.options.go",
"chars": 1290,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/exec/exec_options.go",
"chars": 2155,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/exec/exec_test.go",
"chars": 1729,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/file.go",
"chars": 5893,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/file_test.go",
"chars": 4548,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/getwd.go",
"chars": 1173,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/getwd_test.go",
"chars": 1319,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/proc.go",
"chars": 1985,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/proc_darwin.go",
"chars": 1323,
"preview": "/*\n *Copyright (c) 2024, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/proc_linux.go",
"chars": 1297,
"preview": "/*\n *Copyright (c) 2024, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/proc_test.go",
"chars": 1521,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/remove_file.go",
"chars": 1593,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/signal_posix.go",
"chars": 1252,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/term/term.go",
"chars": 1708,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/os/value.go",
"chars": 141,
"preview": "package os\n\nfunc GetValueOrFallback[T comparable](v, defaultValue T) T {\n\tvar zeroE T\n\tif v != zeroE {\n\t\treturn v\n\t}\n\n\tr"
},
{
"path": "go/os/value_test.go",
"chars": 1802,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/path/filepath/match.go",
"chars": 1564,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/path/filepath/path.go",
"chars": 2438,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/path/filepath/path_test.go",
"chars": 2846,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/array.go",
"chars": 2130,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/array_test.go",
"chars": 2135,
"preview": "/*\n *Copyright (c) 2023, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/error.go",
"chars": 1538,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/id.go",
"chars": 1600,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/struct.go",
"chars": 4390,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/struct_test.go",
"chars": 2983,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/truncate.go",
"chars": 5531,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/truncate_test.go",
"chars": 8756,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/value.go",
"chars": 8611,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/reflect/value_test.go",
"chars": 1939,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/extern.go",
"chars": 2037,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/extern_test.go",
"chars": 1341,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/function.go",
"chars": 1331,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/function_test.go",
"chars": 1990,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/goroutine.go",
"chars": 3478,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/marshaler/jsonpb.marshaler.go",
"chars": 3749,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/marshaler/jsonpb.marshaler.option.go",
"chars": 1982,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/marshaler/jsonpb.marshaler_option.go",
"chars": 1970,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/marshaler/proto.marshaler.go",
"chars": 1514,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/meta.data.go",
"chars": 1381,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/panic.go",
"chars": 2990,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/panic_test.go",
"chars": 1477,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/runtime/stack.go",
"chars": 4146,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/slices/slices.go",
"chars": 2497,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/slices/slices_test.go",
"chars": 2325,
"preview": "package slices_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\tslices_ \"github.com/kaydxh/golang/go/slices\"\n)\n\nfunc TestSliceIntersec"
},
{
"path": "go/strconv/atoi.go",
"chars": 1592,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/strconv/atoi_test.go",
"chars": 1536,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/strconv/atonum.go",
"chars": 2204,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
},
{
"path": "go/strconv/atonum_test.go",
"chars": 2449,
"preview": "/*\n *Copyright (c) 2022, kaydxh\n *\n *Permission is hereby granted, free of charge, to any person obtaining a copy\n *of t"
}
]
// ... and 1759 more files (download for full content)
About this extraction
This page contains the full source code of the kaydxh/golang GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1959 files (124.4 MB), approximately 6.4M tokens, and a symbol index with 18496 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.