Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions learning/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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<T>
- 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.

### 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.
32 changes: 32 additions & 0 deletions learning/flat_hash_map_playground.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <string>
#include <vector>

#include "absl/container/flat_hash_map.h"

namespace learning {

absl::flat_hash_map<std::string, int> CountWords(const std::vector<std::string>& words) {
absl::flat_hash_map<std::string, int> counts;
for (const auto& w : words) {
++counts[w];
}
return counts;
}

int MostFrequentCount(const absl::flat_hash_map<std::string, int>& counts) {
int best = 0;
for (const auto& kv : counts) {
if (kv.second > best) best = kv.second;
}
return best;
}

} // namespace learning

int main() {
std::vector<std::string> words = {"absl", "status", "absl", "time", "absl", "map", "time"};
auto counts = learning::CountWords(words);
int best = learning::MostFrequentCount(counts);
(void)best;
return 0;
}
88 changes: 88 additions & 0 deletions learning/status_patterns.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <cctype>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/statusor.h"

namespace learning {

absl::StatusOr<int> 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<unsigned char>(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<int> 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<std::pair<std::string, int>> 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<int> 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<std::pair<std::string, int>> ParseEndpointWithContext(const std::string& input) {
absl::StatusOr<std::pair<std::string, int>> 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;
}
55 changes: 55 additions & 0 deletions learning/status_playground.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <cctype>
#include <string>

#include "absl/status/status.h"
#include "absl/status/statusor.h"

namespace learning {

absl::StatusOr<int> 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<unsigned char>(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<int> 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;
}
33 changes: 33 additions & 0 deletions learning/time_playground.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <string>

#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;
}