From 713a0f597c7a05d941760a4a6f97f4e03bdf00c5 Mon Sep 17 00:00:00 2001 From: "Daeun(Sophie) Kim" Date: Sun, 18 Jan 2026 18:52:54 +0900 Subject: [PATCH 1/7] Create README.md --- learning/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 learning/README.md diff --git a/learning/README.md b/learning/README.md new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/learning/README.md @@ -0,0 +1 @@ + From 9c010510fd4894fde551b52b2e53a95344cddff2 Mon Sep 17 00:00:00 2001 From: "Daeun(Sophie) Kim" Date: Sun, 18 Jan 2026 18:58:09 +0900 Subject: [PATCH 2/7] docs(learning): add Abseil study journal and plan --- learning/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/learning/README.md b/learning/README.md index 8b137891..d5afa6c8 100644 --- a/learning/README.md +++ b/learning/README.md @@ -1 +1,18 @@ +# Abseil Learning Journal +This folder is a lightweight learning space for reading Abseil code and writing tiny playground examples. + +## Focus areas +- absl::Status and absl::StatusOr +- absl::Time and absl::Duration +- absl::flat_hash_map + +## Plan +1. Read the header files and follow the types and helpers. +2. Keep playground files small and focused. +3. Add new playgrounds incrementally as I learn more APIs. + +## Sessions +### Session 1 +- Created minimal playground sources for Status, Time, and flat_hash_map. +- Next: read implementation details around status macros/helpers and time formatting utilities. From 8c30fb148214b682b2b3a886826cb9b39f06c7a2 Mon Sep 17 00:00:00 2001 From: "Daeun(Sophie) Kim" Date: Sun, 18 Jan 2026 18:59:54 +0900 Subject: [PATCH 3/7] chore(learning): add Status and StatusOr playground --- learning/status_playground.cc | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 learning/status_playground.cc diff --git a/learning/status_playground.cc b/learning/status_playground.cc new file mode 100644 index 00000000..5381a66d --- /dev/null +++ b/learning/status_playground.cc @@ -0,0 +1,55 @@ +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" + +namespace learning { + +absl::StatusOr ParsePort(const std::string& input) { + if (input.empty()) { + return absl::InvalidArgumentError("port is empty"); + } + + int value = 0; + for (char c : input) { + if (!std::isdigit(static_cast(c))) { + return absl::InvalidArgumentError("port must be numeric"); + } + value = value * 10 + (c - '0'); + if (value > 65535) { + return absl::OutOfRangeError("port is out of range"); + } + } + + if (value == 0) { + return absl::OutOfRangeError("port must be between 1 and 65535"); + } + + return value; +} + +absl::Status ValidateHostPort(const std::string& host, const std::string& port) { + if (host.empty()) { + return absl::InvalidArgumentError("host is empty"); + } + + absl::StatusOr parsed = ParsePort(port); + if (!parsed.ok()) { + return parsed.status(); + } + + return absl::OkStatus(); +} + +} // namespace learning + +int main() { + absl::Status s1 = learning::ValidateHostPort("localhost", "8080"); + absl::Status s2 = learning::ValidateHostPort("", "8080"); + absl::Status s3 = learning::ValidateHostPort("localhost", "99999"); + (void)s1; + (void)s2; + (void)s3; + return 0; +} From da333f173488c9137a95a5519970d14a0796c408 Mon Sep 17 00:00:00 2001 From: "Daeun(Sophie) Kim" Date: Sun, 18 Jan 2026 19:00:51 +0900 Subject: [PATCH 4/7] chore(learning): add Time and Duration playground --- learning/time_playground.cc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 learning/time_playground.cc diff --git a/learning/time_playground.cc b/learning/time_playground.cc new file mode 100644 index 00000000..c3a03417 --- /dev/null +++ b/learning/time_playground.cc @@ -0,0 +1,33 @@ +#include + +#include "absl/time/clock.h" +#include "absl/time/time.h" + +namespace learning { + +std::string FormatLocalNow() { + absl::Time now = absl::Now(); + absl::TimeZone tz = absl::LocalTimeZone(); + return absl::FormatTime("%Y-%m-%d %H:%M:%S", now, tz); +} + +absl::Duration BackoffDelay(int attempt) { + if (attempt <= 0) return absl::ZeroDuration(); + absl::Duration base = absl::Milliseconds(200); + absl::Duration cap = absl::Seconds(5); + absl::Duration d = base * attempt; + if (d > cap) d = cap; + return d; +} + +} // namespace learning + +int main() { + std::string t = learning::FormatLocalNow(); + absl::Duration d1 = learning::BackoffDelay(1); + absl::Duration d2 = learning::BackoffDelay(10); + (void)t; + (void)d1; + (void)d2; + return 0; +} From f1fc46d5d5336c88a5b8c2ede9479396b720a42b Mon Sep 17 00:00:00 2001 From: "Daeun(Sophie) Kim" Date: Sun, 18 Jan 2026 19:01:46 +0900 Subject: [PATCH 5/7] chore(learning): add flat_hash_map playground --- learning/flat_hash_map_playground.cc | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 learning/flat_hash_map_playground.cc diff --git a/learning/flat_hash_map_playground.cc b/learning/flat_hash_map_playground.cc new file mode 100644 index 00000000..df49ae95 --- /dev/null +++ b/learning/flat_hash_map_playground.cc @@ -0,0 +1,32 @@ +#include +#include + +#include "absl/container/flat_hash_map.h" + +namespace learning { + +absl::flat_hash_map CountWords(const std::vector& words) { + absl::flat_hash_map counts; + for (const auto& w : words) { + ++counts[w]; + } + return counts; +} + +int MostFrequentCount(const absl::flat_hash_map& counts) { + int best = 0; + for (const auto& kv : counts) { + if (kv.second > best) best = kv.second; + } + return best; +} + +} // namespace learning + +int main() { + std::vector words = {"absl", "status", "absl", "time", "absl", "map", "time"}; + auto counts = learning::CountWords(words); + int best = learning::MostFrequentCount(counts); + (void)best; + return 0; +} From 2497596fcd3f8f17fec9228a2697eb3ddad2ba2f Mon Sep 17 00:00:00 2001 From: "Daeun(Sophie) Kim" Date: Sun, 18 Jan 2026 19:03:00 +0900 Subject: [PATCH 6/7] Update README.md --- learning/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/learning/README.md b/learning/README.md index d5afa6c8..be89125c 100644 --- a/learning/README.md +++ b/learning/README.md @@ -16,3 +16,10 @@ This folder is a lightweight learning space for reading Abseil code and writing ### Session 1 - Created minimal playground sources for Status, Time, and flat_hash_map. - Next: read implementation details around status macros/helpers and time formatting utilities. + +### Session 2 +- Practiced common Status patterns: + - Early return on failure + - StatusOr chaining across steps + - Adding context to errors while preserving the original cause +- Next: read helper utilities around status handling and investigate how errors are commonly propagated across library boundaries. From 2ccb0fa88387cb0d44904e077f92c43b34642242 Mon Sep 17 00:00:00 2001 From: "Daeun(Sophie) Kim" Date: Sun, 18 Jan 2026 19:06:15 +0900 Subject: [PATCH 7/7] chore(learning): add Status patterns playground (early return, StatusOr chain, annotate) --- learning/status_patterns.cc | 88 +++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 learning/status_patterns.cc diff --git a/learning/status_patterns.cc b/learning/status_patterns.cc new file mode 100644 index 00000000..114873d3 --- /dev/null +++ b/learning/status_patterns.cc @@ -0,0 +1,88 @@ +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" + +namespace learning { + +absl::StatusOr ParsePositiveInt(const std::string& s) { + if (s.empty()) return absl::InvalidArgumentError("empty string"); + + int v = 0; + for (char c : s) { + if (!std::isdigit(static_cast(c))) { + return absl::InvalidArgumentError("not a number"); + } + v = v * 10 + (c - '0'); + if (v > 1000000) return absl::OutOfRangeError("value too large"); + } + + if (v <= 0) return absl::OutOfRangeError("value must be positive"); + return v; +} + +absl::Status ValidateRange(int v, int lo, int hi) { + if (v < lo || v > hi) { + return absl::OutOfRangeError("value out of allowed range"); + } + return absl::OkStatus(); +} + +absl::Status ConfigureRetries(const std::string& retries_text) { + absl::StatusOr retries = ParsePositiveInt(retries_text); + if (!retries.ok()) return retries.status(); + + absl::Status vr = ValidateRange(*retries, 1, 10); + if (!vr.ok()) return vr; + + return absl::OkStatus(); +} + +absl::StatusOr> ParseEndpoint(const std::string& input) { + auto pos = input.find(':'); + if (pos == std::string::npos) return absl::InvalidArgumentError("missing ':'"); + + std::string host = input.substr(0, pos); + std::string port_text = input.substr(pos + 1); + + if (host.empty()) return absl::InvalidArgumentError("empty host"); + + absl::StatusOr port = ParsePositiveInt(port_text); + if (!port.ok()) return port.status(); + + absl::Status in_range = ValidateRange(*port, 1, 65535); + if (!in_range.ok()) return in_range; + + return std::make_pair(host, *port); +} + +absl::StatusOr> ParseEndpointWithContext(const std::string& input) { + absl::StatusOr> ep = ParseEndpoint(input); + if (!ep.ok()) { + std::string msg = "failed to parse endpoint '" + input + "': " + std::string(ep.status().message()); + return absl::InvalidArgumentError(msg); + } + return *ep; +} + +} // namespace learning + +int main() { + absl::Status s1 = learning::ConfigureRetries("3"); + absl::Status s2 = learning::ConfigureRetries("0"); + absl::Status s3 = learning::ConfigureRetries("abc"); + + auto e1 = learning::ParseEndpoint("localhost:8080"); + auto e2 = learning::ParseEndpoint("localhost:99999"); + auto e3 = learning::ParseEndpointWithContext("bad_endpoint"); + + (void)s1; + (void)s2; + (void)s3; + (void)e1; + (void)e2; + (void)e3; + return 0; +}