<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Control Flow]]></title><description><![CDATA[Thoughts on software engineering, systems architecture, technical hiring and engineering management.]]></description><link>https://controlflow.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!t90j!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F49fa040d-0a5e-4e2d-814b-722e10197312_1280x1280.png</url><title>Control Flow</title><link>https://controlflow.substack.com</link></image><generator>Substack</generator><lastBuildDate>Sat, 11 Apr 2026 06:03:59 GMT</lastBuildDate><atom:link href="https://controlflow.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[George Psarakis]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[controlflow@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[controlflow@substack.com]]></itunes:email><itunes:name><![CDATA[George Psarakis]]></itunes:name></itunes:owner><itunes:author><![CDATA[George Psarakis]]></itunes:author><googleplay:owner><![CDATA[controlflow@substack.com]]></googleplay:owner><googleplay:email><![CDATA[controlflow@substack.com]]></googleplay:email><googleplay:author><![CDATA[George Psarakis]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Structured Logging in Golang]]></title><description><![CDATA[Effective Logging Design Patterns & Best Practices]]></description><link>https://controlflow.substack.com/p/structured-logging-in-golang</link><guid isPermaLink="false">https://controlflow.substack.com/p/structured-logging-in-golang</guid><dc:creator><![CDATA[George Psarakis]]></dc:creator><pubDate>Sun, 25 Jan 2026 18:36:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!t90j!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F49fa040d-0a5e-4e2d-814b-722e10197312_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-button-wrap" data-attrs="{&quot;url&quot;:&quot;https://controlflow.substack.com/p/structured-logging-in-golang?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="CaptionedButtonToDOM"><div class="preamble"><p class="cta-caption">Thanks for reading Control Flow! This post is public so feel free to share it.</p></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://controlflow.substack.com/p/structured-logging-in-golang?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://controlflow.substack.com/p/structured-logging-in-golang?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p></div><h2>Introduction</h2><p>Logs are a crucial method of obtaining historical context for the application state, as  streams of time-series data. They are usually composed of a human-friendly message along with contextual information, providing a timeline and insights on the  application state at each step of a given flow. Using a structured format for attaching context means that we can create a document database where attributes conform to certain types and structure and allow for more complex, efficient and consistent queries.</p><blockquote><p>Structured logging helps us interface with logs as a read-only, document database storing a time-series event stream.</p></blockquote><p>Although observability has advanced significantly, log records allow for extended retention and providing precise, application-wide historical context, spanning queue/stream message processing, HTTP request processing and scheduled tasks.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://controlflow.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Control Flow! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>Design Patterns</h1><h3>Log Entry Association</h3><p>In order to properly group multiple log entries that belong to a specific flow, a common identifier must be embedded in the context. For HTTP requests, this is usually referred to as <em>Request ID</em>, although the same correlation concepts apply to asynchronous, background processing (scheduled tasks, queue message processing). Each unique identifier marks a new<em> request-local context</em>.</p><p>Nested contexts enable correlations that facilitate tracking the timeline and state transitions in extended sub-flows. We can create nested contexts in a simple way, by using the parent context ID as a namespace and a constant delimiter that will allow us to deterministically parse the composite context identifier, for example:</p><ul><li><p>Main Flow: <code>a3003c58-f723-41e3-b50a-a0659d484b60</code></p></li><li><p>Nested Flow: <code>e14f9f9e-003b-4376-bc65-e5e122a4e097</code></p></li><li><p>Composite Flow ID: <code>a3003c58-f723-41e3-b50a-a0659d484b60/e14f9f9e-003b-4376-bc65-e5e122a4e097</code></p></li></ul><p>You can then select all log records for a given flow or sub-flow using prefix matching (SQL syntax):</p><pre><code>request_id LIKE 'a3003c58-f723-41e3-b50a-a0659d484b60%'</code></pre><p>and for the sub-flow:</p><pre><code>request_id LIKE 'a3003c58-f723-41e3-b50a-a0659d484b60/e14f9f9e-003b-4376-bc65-e5e122a4e097%'</code></pre><blockquote><p>The concept of trace identifier chaining is similar to what <a href="https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-request-tracing.html#request-tracing-syntax">AWS ALB</a> does in a more structured form.</p></blockquote><h3>Well-Defined, Stable Log Entry Schema</h3><p>Although often overlooked, it is very beneficial to <strong>maintain models for each log entry and treat them as Message or HTTP API Response Schemas.</strong> The benefit? Safeguard against making backwards incompatible changes which can have severe downstream implications, such as <strong>breaking alert queries, log metric extraction and incident/troubleshooting runbooks.</strong></p><h4>Schema Definition</h4><p>Let&#8217;s assume a user signup event which we need to log. We decide that the following fields are important:</p><ul><li><p>The email domain, e.g. <code>gmail.com</code>.</p></li><li><p>Whether the email address is valid.</p></li><li><p>Whether the password (if provided) is valid.</p></li><li><p>The provider: Google or self (application built-in user management).</p></li></ul><pre><code>package main

import (
&#9;"net/mail"
&#9;"os"
&#9;"strings"

&#9;"github.com/rs/zerolog"
&#9;"go.uber.org/zap"
&#9;"go.uber.org/zap/zapcore"
)

// Log is the base type for all log entries.
// Note: only include one interface, depending on your logger library!
type Log struct {
&#9;zerolog.LogObjectMarshaler
&#9;zapcore.ObjectMarshaler
&#9;Type string
}

const (
&#9;SignupProviderSelf   = "self"
&#9;SignupProviderGoogle = "google"
)

// LogEntryUserSignup provides the log context for a user signup event.
type LogEntryUserSignup struct {
&#9;Log
&#9;// HasValidPassword is false for non-password-enabled sign-up methods.
&#9;HasValidPassword bool
&#9;// HasValidEmail reports that the provided address is valid.
&#9;HasValidEmail bool
&#9;// EmailDomain stores the domain part of a valid email address.
&#9;EmailDomain string
&#9;// Provider is an optional signup source: can be one of "self,google".
&#9;Provider *string
}</code></pre><p>We will also be using some simple helper functions:</p><pre><code>func getDomain(email string) (string, error) {
&#9;addr, err := mail.ParseAddress(email)
&#9;if err != nil {
&#9;&#9;return "", err
&#9;}

&#9;at := strings.LastIndex(addr.Address, "@")
&#9;return addr.Address[at+1:], nil
}

func strToPtr(s string) *string {
&#9;return &amp;s
}</code></pre><h4>Application Logic</h4><pre><code>
func main() {
&#9;email := "tester@domain.com"
&#9;domain, err := getDomain(email)
&#9;le := LogEntryUserSignup{
&#9;&#9;Log: Log{
&#9;&#9;&#9;Type: "user_signup",
&#9;&#9;},
&#9;&#9;HasValidPassword: true,
&#9;&#9;HasValidEmail:    err == nil,
&#9;&#9;EmailDomain:      domain,
&#9;}

&#9;zeroLogger := zerolog.New(os.Stdout).With().Timestamp().Logger()
&#9;zeroLogger.Info().Object("context", le).Msg("new user signed up")

&#9;
         // Assuming a non-nil provider scenario
         le.Provider = strToPtr(SignupProviderGoogle)
&#9;zapLogger, err := zap.NewProduction()
&#9;if err != nil {
&#9;&#9;panic(err)
&#9;}
&#9;zapLogger.Info("new user signed up", zap.Object("context", le))
}</code></pre><blockquote><p>Note: only a single logging library should be used, here we utilize both for demo purposes!</p></blockquote><p>We receive the following logs:</p><pre><code>{
  "level": "info",
  "context": {
    "type": "user_signup",
    "email_domain": "domain.com",
    "has_valid_password": true,
    "has_valid_email": true
  },
  "time": "2026-01-25T10:33:15+00:00",
  "message": "new user signed up"
}</code></pre><p>and:</p><pre><code>{
  "level": "info",
  "ts": 1769329995.225628,
  "msg": "new user signed up",
  "context": {
    "type": "user_signup",
    "email_domain": "domain.com",
    "has_valid_password": true,
    "has_valid_email": true,
    "provider": "google"
  }
}</code></pre><blockquote><p>Note how in the second case (<code>zap</code>) we also define the <code>provider</code> context field.</p></blockquote><h4>zap</h4><p>Structs implementing the  <a href="https://pkg.go.dev/go.uber.org/zap@v1.27.1/zapcore#ObjectMarshaler">zapcore.ObjectMarshaler</a> interface allow for controlled, structured serialization. Example code:</p><pre><code>func (l LogEntryUserSignup) MarshalLogObject(enc zapcore.ObjectEncoder) error {
&#9;enc.AddString("type", l.Type)
&#9;enc.AddString("email_domain", l.EmailDomain)
&#9;enc.AddBool("has_valid_password", l.HasValidPassword)
&#9;enc.AddBool("has_valid_email", l.HasValidEmail)
&#9;if l.Provider != nil {
&#9;&#9;enc.AddString("provider", *l.Provider)
&#9;}
&#9;return nil
}</code></pre><p>Note that within the <code>MarshalLogObject</code> implementation we can control which fields should be part of the context.</p><p>The struct instance can then be added as log context using <a href="https://pkg.go.dev/go.uber.org/zap@v1.27.1#Object">zap.Object</a>:</p><pre><code><code>// le is an instance of LogEntryUserSignup
zapLogger.Info("new user signed up", zap.Object("context", le))</code></code></pre><h4>zerolog</h4><p>Structs implementing the <a href="https://pkg.go.dev/github.com/rs/zerolog#LogObjectMarshaler">zerolog.LogObjectMarshaler</a> interface allow for controlled, structured serialization. Let&#8217;s see the example code:</p><pre><code>func (l LogEntryUserSignup) MarshalZerologObject(e *zerolog.Event) {
&#9;e.Str("type", l.Type).
&#9;&#9;Str("email_domain", l.EmailDomain).
&#9;&#9;Bool("has_valid_password", l.HasValidPassword).
&#9;&#9;Bool("has_valid_email", l.HasValidEmail)
&#9;if l.Provider != nil {
&#9;&#9;e.Str("provider", *l.Provider)
&#9;}
}</code></pre><p>The struct instance can then be added as context using <a href="https://pkg.go.dev/github.com/rs/zerolog#Event.Object">zerolog.Event.Object</a>:</p><pre><code><code>// le is an instance of LogEntryUserSignup
zeroLogger.Info().Object("context", le).Msg("new user signed up")</code></code></pre><h3>Logger Instance in Context &amp; Child Loggers</h3><p>Although passing dependencies via the <code>context.Context</code> parameter is often debatable, primarily due to hiding dependencies, creating optional branches and additional handling, the logger instance might be a good candidate for context injection because it changes per call; <em>the logger can indeed carry request-scoped local context per goroutine, such as in HTTP request handling</em>.</p><p>Using the context container allows any function to obtain this dependency without making it a specific, static dependency in service objects. The pattern is as follows: Cloning the logger, attaching extra context (see <a href="https://pkg.go.dev/go.uber.org/zap#Logger.With">zap.With</a>) and creating a <code>context.Context</code> copy with the new logger value, will allow any subsequent layer to emit log entries with the corresponding parent context.</p><pre><code>logger := logger.With(zap.Bool("signup", true))
ctx := logging.WithContext(ctx, logger)</code></pre><h1>Best Practices</h1><h3>HTTP Request ID as Message Metadata</h3><p>HTTP Requests often generate background tasks (database), publish messages in message queues (SQS) or message streams (Kafka). When task processing fails or you need to investigate the activity that resulted in each task (e.g. due to volume/high backlog), it is useful to embed the message publisher request ID in the message metadata. This will allow you to include the <strong>originating request ID</strong> in the <strong>task log context</strong>. By filtering with the HTTP Request ID later on, you can obtain a full view of the timeline (<em>when was each task processed?</em>) and correlate failures with actual requests.</p><p><em>What about tracing tasks that were generated by other tasks?</em></p><p>Tasks that publish messages themselves can create nested contexts, resulting to a <strong>composite request ID. </strong>Let&#8217;s break it down with <strong>example values:</strong></p><ul><li><p><strong>HTTP/ChangeUserProfile:</strong> <code>a3003c58-f723-41e3-b50a-a0659d484b60</code></p></li><li><p><strong>Task/ProcessUserNotification: </strong><code>64b051a2-dff3-4f64-9ca0-c40ee138d55e</code></p><ul><li><p><strong>Task/SendEmail: </strong><code>2141e184-fe61-4d83-ba1e-6ef04d78283f</code></p></li></ul></li></ul><p>Sample log for <strong>Task/SendEmail:</strong></p><pre><code>{
  "time": "2026-01-25T08:47:02+00:00",
  "trace_id": "a3003c58-f723-41e3-b50a-a0659d484b60/64b051a2-dff3-4f64-9ca0-c40ee138d55e/2141e184-fe61-4d83-ba1e-6ef04d78283f",
  "message": "email sent successfully",
  "email_domain": "gmail.com",
  "task_processing_time_seconds": 0.24
}</code></pre><p>Note that a Message ID is a different entity and can be a persistent property of the message itself (e.g. see <a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-queue-message-identifiers.html">SQS</a>). Here we are referring to <strong>an execution-scoped identifier, which will change in case of retries</strong>.</p><p>Querying all log entries for which the <code>trace_id</code> starts with the HTTP Request ID, will provide the full context about HTTP &amp; task execution.</p><h3>Avoid Arbitrary Object Logging</h3><p>Context definition should extract and define specific fields and translate application-level object fields to logging fields. Although it seems convenient at the time to log arbitrary objects (e.g. the entire <code>User</code> object), it has the following drawbacks:</p><ul><li><p>Unnecessary log volume increase.</p></li><li><p>Noise-vs-signal ratio increase/log pollution.</p></li><li><p>Unexpected secret or privacy leaks due to extensions and changes in the object fields.</p></li></ul><p>In essence, something like the following <strong>should be considered an anti-pattern and be avoided:</strong></p><pre><code>type User struct {
    Email string
    FirstName string
    LastName string
}

u := User{Email: "tester@domain.com", FirstName: "Tester"}
zapLogger.Info("user signup", zap.Any("user", u))</code></pre><p>See also the section above <a href="https://controlflow.substack.com/i/185702283/well-defined-stable-log-entry-schema">regarding maintaining specific log schemas</a>.</p><h3>Timezone</h3><p>Regardless of your application timezone settings, <strong>the timestamp included in the log entry should be in UTC</strong>. Keep in mind that log aggregation systems maintain their own ingestion timestamp, however there might be some latency between generation and ingestion, usually in the order of only a few seconds, but could potentially extend to minutes at times in case of maintenance or resource contention.</p><h3>Sampling</h3><p>Production scale, external inputs, transient issues with dependencies, or a bug can cause extremely high amounts of logs being generated. Large log volumes can cause:</p><ul><li><p>Each application process consumes too much CPU/memory on serialization and output buffers.</p></li><li><p>Excessive infrastructure costs in the log aggregation system (i.e. ELK, Grafana, Datadog).</p></li><li><p>Too much log noise makes it more difficult to filter for other important logs.</p></li></ul><p>This is where sampling takes effect. Most logging libraries will maintain a small in-memory cache which groups and monitors log entry generation rate per group. <strong>The sampler decides whether each message group has exceeded their quota and will start dropping messages after a certain threshold.</strong> New logs will start reappearing at a later moment in time due to the rate reset. You can read more on the reasoning and how <code>zap</code> sampling works <a href="https://github.com/uber-go/zap/blob/16fb16b353f2e27bcd71eba69cbd346b3dcc471a/FAQ.md#why-sample-application-logs">here</a> and <a href="https://pkg.go.dev/go.uber.org/zap#SamplingConfig">here</a>.</p><blockquote><p>Sampling should usually be disabled for development purposes since it can unintentionally hide logs.</p></blockquote><h3>Avoid logging in low-level layers</h3><p>It is often tempting to use logging in several functions, emitting logs where valuable local context is present. However, it might be best to propagate context to higher layers in the stack, possibly within error types or other return values. For an illustration of this practice you can check <a href="https://github.com/georgepsarakis/errorcontext">this library</a>.</p><p>Some possible drawbacks of this anti-pattern are:</p><ul><li><p>Reduced control over the log volume. A function that is later reused within a loop, starts emitting log entries for each call.</p></li><li><p>Passing parameters that do not have functional use for the function, only utilized in logging context. At the call site, this is non-obvious and pollutes the API and function signature.</p></li><li><p>Testing side-effects: error handling should generally be unit tested which is more difficult and brittle compared to typed return values.</p></li></ul><h2>Conclusion</h2><p>Logging may sound trivial until we start considering maintainability &amp; ergonomics and maximing its efficiency across code &amp; service components. The above practices and patterns should at least provide a good starting point for highlighting the possible issues that may arise within a large-scale service.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://controlflow.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Control Flow! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Probabilistic Data Structures: Bloom Filter]]></title><description><![CDATA[Compact and efficient set membership testing]]></description><link>https://controlflow.substack.com/p/probabilistic-data-structures-bloom</link><guid isPermaLink="false">https://controlflow.substack.com/p/probabilistic-data-structures-bloom</guid><dc:creator><![CDATA[George Psarakis]]></dc:creator><pubDate>Sun, 16 Nov 2025 16:02:37 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!t90j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F49fa040d-0a5e-4e2d-814b-722e10197312_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Applications of Set Membership Testing</h2><h3>Cache Gain &amp; Entry Eligibility</h3><p>Caching gain increases as read/write ratio becomes much higher than 1: write once, read many times. An example is caching a blog post after it has been published or edited, since we expect that it will be read many times after users have been notified about the changes.</p><p>Aggressively caching state can quickly remove entries with high read/write ratio and replace them with low-value entries which will be read very few times. Since memory is limited, insertion operations will try to make room for new entries.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://controlflow.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Control Flow! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><blockquote><p>More sophisticated cache eviction policies can mitigate the effect of incorrect removal of high-gain cache entries. For example, weighted LRU can take into account (a) the cost of regenerating the cache value and/or (b) hit rate.</p></blockquote><p>In order to determine whether an entry is eligible for caching, an assumption can be made that at least two queries must be performed before an element is eligible as a cache entry. A Bloom Filter can help ascertain that at least two queries occurred, in an efficient manner; if the element is found by the filter, the query value can be cached.</p><h3>Rate Limiting</h3><p>A simple rate limiter identifies requests according to an identification token (session ID, user ID, API token etc). A potential algorithm here is:</p><ol><li><p>Extract request token.</p></li><li><p>Check if the rate limiting threshold is exceeded.</p><ol><li><p>If no, continue recording activity.</p></li><li><p>If yes, insert into time-limited blocklist.</p></li></ol></li><li><p>On blocklist expiration, requests with the same token start being re-evaluated.</p></li></ol><p>Rate-limited tokens can be quickly validated with an error-free hash. Assuming 32-byte tokens the memory storage is of the order: </p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;O(32 * N) = O(N)&quot;,&quot;id&quot;:&quot;PAQCBXURCW&quot;}" data-component-name="LatexBlockToDOM"></div><p>For 1M entries we need to store at least 32MB, plus the size of the hash table structure which we assume is small in comparison to the actual data storage. Note that:</p><ul><li><p>We will need to reset the blocklist state in regular intervals, thus requiring garbage collection of now unused objects.</p></li><li><p>We will likely need more than a single rate limiter. For example, for HTTP server endpoints, we may need to maintain multiple rate limiters since thresholds often differ depending on the (a) the verb and (b) the mutation operation impact.</p></li></ul><h2>Primer on Probabilistic Data Structures</h2><p>What are probabilistic data structures and why are they useful?</p><blockquote><p>Probabilistic Data Structures are data structures that provide approximate answers to queries about a large dataset, rather than exact answers.</p></blockquote><p>The key here is the tradeoff between scalability and accuracy. If our application logic can tolerate certain loss of precision, while achieving 100% accuracy would amount to extreme computational or memory requirements and thus become prohibitive, then perhaps introducing a probabilistic structure is the solution.</p><p>Two well-known algorithms with wide applications are:</p><ul><li><p><a href="https://en.wikipedia.org/wiki/HyperLogLog">HyperLogLog</a>: a cardinality estimation algorithm, present in several database implementations. Counters usually serve as indicators of magnitude, e.g. X number of unique visitors per day where 100% precision is not mandatory.</p></li><li><p><a href="https://en.wikipedia.org/wiki/Bloom_filter">Bloom Filter</a>: allows efficient set membership testing and is applicable where low false positive rates can be tolerated, for example in <a href="https://stackoverflow.com/a/63431819">browser URL safety checks</a>.</p></li></ul><h2>Building a cache for invalid JWT tokens</h2><p>Web session and API authentication often use signed/encrypted JWT as a serialization format for context-aware tokens. Verifying an invalid token can still be computationally intensive which can cause Denial-of-Service conditions. In order to protect application servers against this type of condition, we need to find a reliable, lightweight way of quickly marking and detecting previously evaluated invalid tokens.</p><p><strong>How does a bloom filter work?</strong></p><ul><li><p>A bit array (or bit set) with fixed positions is preallocated. All elements are initially unset (zeroed).</p></li><li><p>A new token is hashed and the corresponding matching bit positions are set.</p></li><li><p>Whether a bit was already set or not is not taken into account.</p></li><li><p>Queries perform the same hashing process and evaluate if bits on matching positions are set. If all positions are set, then the test returns a positive result - the element is a member of the set.</p></li></ul><blockquote><p>As you might observe, a false negative is never possible!</p></blockquote><p>You&#8217;ll notice that if the bit array nears a state where most positions are set, then the filter degrades to a high false positive rate, gradually becoming unreliable. However, by choosing the hashing functions and the bit array size carefully it is possible to obtain an acceptably low false positive rate.</p><blockquote><p>A Bloom Filter cannot grow after its original construction in order to increase its capacity.</p></blockquote><p>With regard to memory requirements, a Bloom Filter estimated to accept 10,000 elements with a false positive rate of 0.01% will occupy approximately 200KB.</p><p>For our use case, we will try to construct an algorithm that avoids expensive computations (signature verification) on signed JWT tokens that have already been evaluated as invalid. Our probabilistic cache will automatically reset after a predefined duration. New tokens are expected to be constantly issued and different values would otherwise fill the bloom filter over time.</p><blockquote><p>The following implementation uses a read/write mutex and is goroutine-safe.</p></blockquote><p>Let&#8217;s also perform a benchmark to measure how a Bloom Filter can reduce computational overhead from incorrectly signed tokens.</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist142797336\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot; data-color-mode=\&quot;light\&quot; data-light-theme=\&quot;light\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container\&quot;>\n  <div id=\&quot;file-benchmark_test-go\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot;\n      class=\&quot;Box-body p-0 blob-wrapper data type-go  \&quot;\n      style=\&quot;overflow: auto\&quot; tabindex=\&quot;0\&quot; role=\&quot;region\&quot;\n      aria-label=\&quot;benchmark_test.go content, created by georgepsarakis on 05:49PM today.\&quot;\n    >\n\n        \n<div class=\&quot;js-check-hidden-unicode js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container\&quot; data-tab-size=\&quot;4\&quot; data-paste-markdown-skip data-tagsearch-path=\&quot;benchmark_test.go\&quot;>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L1\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>package</span> main</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L2\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L3\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>import</span> (</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L4\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;context&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L5\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;errors&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L6\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;fmt&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L7\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;testing&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L8\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;time&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L9\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L10\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;github.com/golang-jwt/jwt/v5&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L11\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L12\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L13\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-c>// Define a custom claims structure that includes standard claims</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L14\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>type</span> <span class=pl-smi>MyClaims</span> <span class=pl-k>struct</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L15\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\tjwt.<span class=pl-smi>RegisteredClaims</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L16\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c1>UserID</span>   <span class=pl-smi>string</span> <span class=pl-s>`json:&amp;quot;user_id&amp;quot;`</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L17\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c1>UserRole</span> <span class=pl-smi>string</span> <span class=pl-s>`json:&amp;quot;role&amp;quot;`</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L18\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L19\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L20\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-c>// Global variable to hold the token string for verification benchmarks</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L21\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>var</span> <span class=pl-s1>tokenString</span> <span class=pl-smi>string</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L22\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L23\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-c>// Secret key for HMAC signing (must be a strong, cryptographically random key in production)</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L24\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>const</span> <span class=pl-s1>hmacSecret</span> <span class=pl-c1>=</span> <span class=pl-s>&amp;quot;super-secret-key-for-hmac-sha256-verification-32-bytes&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L25\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>const</span> <span class=pl-s1>hmacSecret2</span> <span class=pl-c1>=</span> <span class=pl-s1>hmacSecret</span> <span class=pl-c1>+</span> <span class=pl-s>&amp;quot;-2&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L26\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L27\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> <span class=pl-s1>init</span>() {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L28\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>claims</span> <span class=pl-c1>:=</span> <span class=pl-smi>MyClaims</span>{</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L29\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>RegisteredClaims</span>: jwt.<span class=pl-smi>RegisteredClaims</span>{</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L30\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>ExpiresAt</span>: <span class=pl-s1>jwt</span>.<span class=pl-c1>NewNumericDate</span>(<span class=pl-s1>time</span>.<span class=pl-c1>Now</span>().<span class=pl-c1>Add</span>(<span class=pl-s1>time</span>.<span class=pl-c1>Hour</span> <span class=pl-c1>*</span> <span class=pl-c1>24</span>)),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L31\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>IssuedAt</span>:  <span class=pl-s1>jwt</span>.<span class=pl-c1>NewNumericDate</span>(<span class=pl-s1>time</span>.<span class=pl-c1>Now</span>()),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L32\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>Subject</span>:   <span class=pl-s>&amp;quot;test-user&amp;quot;</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L33\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t},</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L34\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;34\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>UserID</span>:   <span class=pl-s>&amp;quot;user-12345&amp;quot;</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L35\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;35\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>UserRole</span>: <span class=pl-s>&amp;quot;admin&amp;quot;</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L36\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;36\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L37\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;37\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L38\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;38\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC38\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>token</span> <span class=pl-c1>:=</span> <span class=pl-s1>jwt</span>.<span class=pl-c1>NewWithClaims</span>(<span class=pl-s1>jwt</span>.<span class=pl-c1>SigningMethodHS256</span>, <span class=pl-s1>claims</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L39\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;39\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC39\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>var</span> <span class=pl-s1>err</span> <span class=pl-smi>error</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L40\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;40\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC40\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>tokenString</span>, <span class=pl-s1>err</span> <span class=pl-c1>=</span> <span class=pl-s1>token</span>.<span class=pl-c1>SignedString</span>([]<span class=pl-smi>byte</span>(<span class=pl-s1>hmacSecret2</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L41\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;41\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC41\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>if</span> <span class=pl-s1>err</span> <span class=pl-c1>!=</span> <span class=pl-c1>nil</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L42\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;42\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC42\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>panic</span>(<span class=pl-s1>fmt</span>.<span class=pl-c1>Sprintf</span>(<span class=pl-s>&amp;quot;Failed to sign token in init: %v&amp;quot;</span>, <span class=pl-s1>err</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L43\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;43\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC43\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L44\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;44\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC44\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L45\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;45\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC45\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L46\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;46\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC46\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-c>// Key function for verification that returns the secret</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L47\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;47\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC47\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> <span class=pl-s1>keyFunc</span>(<span class=pl-s1>token</span> <span class=pl-c1>*</span>jwt.<span class=pl-smi>Token</span>) (<span class=pl-k>interface</span>{}, <span class=pl-smi>error</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L48\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;48\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC48\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Always check the signing method to prevent algorithm switching attacks</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L49\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;49\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC49\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>if</span> <span class=pl-s1>_</span>, <span class=pl-s1>ok</span> <span class=pl-c1>:=</span> <span class=pl-s1>token</span>.<span class=pl-c1>Method</span>.(<span class=pl-c1>*</span>jwt.<span class=pl-smi>SigningMethodHMAC</span>); <span class=pl-c1>!</span><span class=pl-s1>ok</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L50\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;50\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC50\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>return</span> <span class=pl-c1>nil</span>, <span class=pl-s1>fmt</span>.<span class=pl-c1>Errorf</span>(<span class=pl-s>&amp;quot;unexpected signing method: %v&amp;quot;</span>, <span class=pl-s1>token</span>.<span class=pl-c1>Header</span>[<span class=pl-s>&amp;quot;alg&amp;quot;</span>])</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L51\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;51\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC51\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L52\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;52\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC52\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>return</span> []<span class=pl-smi>byte</span>(<span class=pl-s1>hmacSecret</span>), <span class=pl-c1>nil</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L53\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;53\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC53\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L54\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;54\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC54\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L55\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;55\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC55\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-c>// Benchmark the JWT verification process using HS256 and full claims validation</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L56\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;56\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC56\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> <span class=pl-s1>BenchmarkJWTVerification_HS256_Failed</span>(<span class=pl-s1>b</span> <span class=pl-c1>*</span>testing.<span class=pl-smi>B</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L57\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;57\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC57\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>var</span> <span class=pl-s1>parsedToken</span> <span class=pl-c1>*</span>jwt.<span class=pl-smi>Token</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L58\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;58\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC58\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L59\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;59\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC59\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Reset timer to exclude setup time</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L60\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;60\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC60\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>b</span>.<span class=pl-c1>ResetTimer</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L61\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;61\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC61\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>b</span>.<span class=pl-c1>ReportAllocs</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L62\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;62\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC62\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L63\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;63\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC63\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span> <span class=pl-s1>i</span> <span class=pl-c1>:=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>b</span>.<span class=pl-c1>N</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L64\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;64\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC64\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>token</span>, <span class=pl-s1>err</span> <span class=pl-c1>:=</span> <span class=pl-s1>jwt</span>.<span class=pl-c1>ParseWithClaims</span>(<span class=pl-s1>tokenString</span>, <span class=pl-c1>&amp;amp;</span><span class=pl-smi>MyClaims</span>{}, <span class=pl-s1>keyFunc</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L65\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;65\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC65\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>if</span> <span class=pl-s1>err</span> <span class=pl-c1>!=</span> <span class=pl-c1>nil</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L66\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;66\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC66\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-k>continue</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L67\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;67\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC67\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L68\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;68\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC68\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>b</span>.<span class=pl-c1>Fail</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L69\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;69\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC69\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>// Store the result to prevent the compiler from optimizing the whole loop away</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L70\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;70\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC70\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>parsedToken</span> <span class=pl-c1>=</span> <span class=pl-s1>token</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L71\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;71\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC71\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L72\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;72\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC72\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Use the result outside the loop</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L73\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;73\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC73\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>_</span> <span class=pl-c1>=</span> <span class=pl-s1>parsedToken</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L74\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;74\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC74\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L75\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;75\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC75\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L76\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;76\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC76\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> <span class=pl-s1>BenchmarkJWTVerification_HS256_BloomFilter</span>(<span class=pl-s1>b</span> <span class=pl-c1>*</span>testing.<span class=pl-smi>B</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L77\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;77\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC77\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>var</span> <span class=pl-s1>parsedToken</span> <span class=pl-c1>*</span>jwt.<span class=pl-smi>Token</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L78\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;78\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC78\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L79\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;79\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC79\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>b1</span>, <span class=pl-s1>cancel</span> <span class=pl-c1>:=</span> <span class=pl-s1>NewTTLBloomFilterWithContext</span>(<span class=pl-s1>context</span>.<span class=pl-c1>Background</span>(), <span class=pl-s1>time</span>.<span class=pl-c1>Minute</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L80\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;80\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC80\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>defer</span> <span class=pl-s1>cancel</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L81\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;81\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC81\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L82\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;82\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC82\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>b</span>.<span class=pl-c1>ResetTimer</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L83\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;83\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC83\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>b</span>.<span class=pl-c1>ReportAllocs</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L84\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;84\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC84\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L85\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;85\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC85\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span> <span class=pl-s1>i</span> <span class=pl-c1>:=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>b</span>.<span class=pl-c1>N</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L86\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;86\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC86\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>if</span> <span class=pl-s1>b1</span>.<span class=pl-c1>Test</span>([]<span class=pl-smi>byte</span>(<span class=pl-s1>tokenString</span>)) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L87\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;87\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC87\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-k>continue</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L88\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;88\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC88\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L89\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;89\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC89\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>token</span>, <span class=pl-s1>err</span> <span class=pl-c1>:=</span> <span class=pl-s1>jwt</span>.<span class=pl-c1>ParseWithClaims</span>(<span class=pl-s1>tokenString</span>, <span class=pl-c1>&amp;amp;</span><span class=pl-smi>MyClaims</span>{}, <span class=pl-s1>keyFunc</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L90\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;90\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC90\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>if</span> <span class=pl-s1>errors</span>.<span class=pl-c1>Is</span>(<span class=pl-s1>err</span>, <span class=pl-s1>jwt</span>.<span class=pl-c1>ErrTokenSignatureInvalid</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L91\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;91\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC91\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>b1</span>.<span class=pl-c1>Add</span>([]<span class=pl-smi>byte</span>(<span class=pl-s1>tokenString</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L92\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;92\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC92\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-k>continue</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L93\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;93\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC93\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L94\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;94\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC94\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>b</span>.<span class=pl-c1>Fail</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L95\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;95\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC95\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>// Store the result to prevent the compiler from optimizing the whole loop away</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L96\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;96\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC96\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>parsedToken</span> <span class=pl-c1>=</span> <span class=pl-s1>token</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L97\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;97\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC97\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L98\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;98\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC98\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Use the result outside the loop</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L99\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;99\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC99\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>_</span> <span class=pl-c1>=</span> <span class=pl-s1>parsedToken</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-benchmark_test-go-L100\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;100\&quot;></td>\n          <td id=\&quot;file-benchmark_test-go-LC100\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/georgepsarakis/557a125abdf6ad99df314ad16595248b/raw/e0d7eeb1b3b0282299f9e7b29f962ac54378e41f/benchmark_test.go\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/georgepsarakis/557a125abdf6ad99df314ad16595248b#file-benchmark_test-go\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          benchmark_test.go\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot; data-color-mode=\&quot;light\&quot; data-light-theme=\&quot;light\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container\&quot;>\n  <div id=\&quot;file-main-go\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot;\n      class=\&quot;Box-body p-0 blob-wrapper data type-go  \&quot;\n      style=\&quot;overflow: auto\&quot; tabindex=\&quot;0\&quot; role=\&quot;region\&quot;\n      aria-label=\&quot;main.go content, created by georgepsarakis on 05:49PM today.\&quot;\n    >\n\n        \n<div class=\&quot;js-check-hidden-unicode js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container\&quot; data-tab-size=\&quot;4\&quot; data-paste-markdown-skip data-tagsearch-path=\&quot;main.go\&quot;>\n        <tr>\n          <td id=\&quot;file-main-go-L1\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-main-go-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>package</span> main</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L2\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-main-go-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L3\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-main-go-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>import</span> (</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L4\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-main-go-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;context&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L5\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-main-go-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;fmt&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L6\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-main-go-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;sync&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L7\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-main-go-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;time&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L8\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-main-go-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L9\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-main-go-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s>&amp;quot;github.com/bits-and-blooms/bloom/v3&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L10\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-main-go-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L11\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-main-go-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L12\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-main-go-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>type</span> <span class=pl-smi>TTLBloomFilter</span> <span class=pl-k>struct</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L13\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-main-go-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c1>*</span>bloom.<span class=pl-smi>BloomFilter</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L14\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-main-go-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c1>ttl</span>       time.<span class=pl-smi>Duration</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L15\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-main-go-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c1>lock</span>      sync.<span class=pl-smi>RWMutex</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L16\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-main-go-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c1>workerCtx</span> context.<span class=pl-smi>Context</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L17\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-main-go-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L18\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-main-go-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L19\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-main-go-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> (<span class=pl-s1>f</span> <span class=pl-c1>*</span><span class=pl-smi>TTLBloomFilter</span>) <span class=pl-c1>Add</span>(<span class=pl-s1>item</span> []<span class=pl-smi>byte</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L20\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-main-go-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>f</span>.<span class=pl-c1>lock</span>.<span class=pl-c1>Lock</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L21\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-main-go-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>defer</span> <span class=pl-s1>f</span>.<span class=pl-c1>lock</span>.<span class=pl-c1>Unlock</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L22\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-main-go-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>f</span>.<span class=pl-c1>BloomFilter</span>.<span class=pl-c1>Add</span>(<span class=pl-s1>item</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L23\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-main-go-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L24\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-main-go-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L25\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-main-go-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> (<span class=pl-s1>f</span> <span class=pl-c1>*</span><span class=pl-smi>TTLBloomFilter</span>) <span class=pl-c1>Test</span>(<span class=pl-s1>item</span> []<span class=pl-smi>byte</span>) <span class=pl-smi>bool</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L26\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-main-go-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>f</span>.<span class=pl-c1>lock</span>.<span class=pl-c1>RLock</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L27\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-main-go-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>defer</span> <span class=pl-s1>f</span>.<span class=pl-c1>lock</span>.<span class=pl-c1>RUnlock</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L28\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-main-go-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>return</span> <span class=pl-s1>f</span>.<span class=pl-c1>BloomFilter</span>.<span class=pl-c1>Test</span>(<span class=pl-s1>item</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L29\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-main-go-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L30\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-main-go-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L31\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-main-go-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> (<span class=pl-s1>f</span> <span class=pl-c1>*</span><span class=pl-smi>TTLBloomFilter</span>) <span class=pl-c1>WithContext</span>(<span class=pl-s1>ctx</span> context.<span class=pl-smi>Context</span>) <span class=pl-c1>*</span><span class=pl-smi>TTLBloomFilter</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L32\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-main-go-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>f</span>.<span class=pl-c1>lock</span>.<span class=pl-c1>RLock</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L33\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-main-go-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>defer</span> <span class=pl-s1>f</span>.<span class=pl-c1>lock</span>.<span class=pl-c1>RUnlock</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L34\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;34\&quot;></td>\n          <td id=\&quot;file-main-go-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>return</span> <span class=pl-c1>&amp;amp;</span><span class=pl-smi>TTLBloomFilter</span>{</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L35\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;35\&quot;></td>\n          <td id=\&quot;file-main-go-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>BloomFilter</span>: <span class=pl-s1>f</span>.<span class=pl-c1>Copy</span>(),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L36\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;36\&quot;></td>\n          <td id=\&quot;file-main-go-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>ttl</span>:         <span class=pl-s1>f</span>.<span class=pl-c1>ttl</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L37\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;37\&quot;></td>\n          <td id=\&quot;file-main-go-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>workerCtx</span>:   <span class=pl-s1>ctx</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L38\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;38\&quot;></td>\n          <td id=\&quot;file-main-go-LC38\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L39\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;39\&quot;></td>\n          <td id=\&quot;file-main-go-LC39\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L40\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;40\&quot;></td>\n          <td id=\&quot;file-main-go-LC40\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L41\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;41\&quot;></td>\n          <td id=\&quot;file-main-go-LC41\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> (<span class=pl-s1>f</span> <span class=pl-c1>*</span><span class=pl-smi>TTLBloomFilter</span>) <span class=pl-c1>ExpirationWorker</span>() {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L42\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;42\&quot;></td>\n          <td id=\&quot;file-main-go-LC42\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>ctx</span> <span class=pl-c1>:=</span> <span class=pl-s1>f</span>.<span class=pl-c1>workerCtx</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L43\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;43\&quot;></td>\n          <td id=\&quot;file-main-go-LC43\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>if</span> <span class=pl-s1>ctx</span> <span class=pl-c1>==</span> <span class=pl-c1>nil</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L44\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;44\&quot;></td>\n          <td id=\&quot;file-main-go-LC44\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>ctx</span> <span class=pl-c1>=</span> <span class=pl-s1>context</span>.<span class=pl-c1>Background</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L45\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;45\&quot;></td>\n          <td id=\&quot;file-main-go-LC45\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L46\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;46\&quot;></td>\n          <td id=\&quot;file-main-go-LC46\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>ticker</span> <span class=pl-c1>:=</span> <span class=pl-s1>time</span>.<span class=pl-c1>NewTicker</span>(<span class=pl-s1>f</span>.<span class=pl-c1>ttl</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L47\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;47\&quot;></td>\n          <td id=\&quot;file-main-go-LC47\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>resetFunc</span> <span class=pl-c1>:=</span> <span class=pl-k>func</span>() {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L48\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;48\&quot;></td>\n          <td id=\&quot;file-main-go-LC48\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>f</span>.<span class=pl-c1>lock</span>.<span class=pl-c1>Lock</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L49\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;49\&quot;></td>\n          <td id=\&quot;file-main-go-LC49\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>defer</span> <span class=pl-s1>f</span>.<span class=pl-c1>lock</span>.<span class=pl-c1>Unlock</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L50\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;50\&quot;></td>\n          <td id=\&quot;file-main-go-LC50\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>f</span>.<span class=pl-c1>ClearAll</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L51\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;51\&quot;></td>\n          <td id=\&quot;file-main-go-LC51\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L52\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;52\&quot;></td>\n          <td id=\&quot;file-main-go-LC52\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L53\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;53\&quot;></td>\n          <td id=\&quot;file-main-go-LC53\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>select</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L54\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;54\&quot;></td>\n          <td id=\&quot;file-main-go-LC54\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>case</span> <span class=pl-c1>&amp;lt;-</span><span class=pl-s1>ticker</span>.<span class=pl-c1>C</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L55\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;55\&quot;></td>\n          <td id=\&quot;file-main-go-LC55\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>resetFunc</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L56\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;56\&quot;></td>\n          <td id=\&quot;file-main-go-LC56\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>case</span> <span class=pl-c1>&amp;lt;-</span><span class=pl-s1>ctx</span>.<span class=pl-c1>Done</span>():</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L57\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;57\&quot;></td>\n          <td id=\&quot;file-main-go-LC57\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>resetFunc</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L58\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;58\&quot;></td>\n          <td id=\&quot;file-main-go-LC58\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-k>return</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L59\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;59\&quot;></td>\n          <td id=\&quot;file-main-go-LC59\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L60\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;60\&quot;></td>\n          <td id=\&quot;file-main-go-LC60\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L61\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;61\&quot;></td>\n          <td id=\&quot;file-main-go-LC61\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L62\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;62\&quot;></td>\n          <td id=\&quot;file-main-go-LC62\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L63\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;63\&quot;></td>\n          <td id=\&quot;file-main-go-LC63\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> <span class=pl-s1>NewTTLBloomFilterWithContext</span>(<span class=pl-s1>ctx</span> context.<span class=pl-smi>Context</span>, <span class=pl-s1>ttl</span> time.<span class=pl-smi>Duration</span>) (<span class=pl-c1>*</span><span class=pl-smi>TTLBloomFilter</span>, context.<span class=pl-smi>CancelFunc</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L64\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;64\&quot;></td>\n          <td id=\&quot;file-main-go-LC64\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>ctx</span>, <span class=pl-s1>cancel</span> <span class=pl-c1>:=</span> <span class=pl-s1>context</span>.<span class=pl-c1>WithCancel</span>(<span class=pl-s1>ctx</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L65\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;65\&quot;></td>\n          <td id=\&quot;file-main-go-LC65\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>bf</span> <span class=pl-c1>:=</span> <span class=pl-c1>&amp;amp;</span><span class=pl-smi>TTLBloomFilter</span>{</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L66\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;66\&quot;></td>\n          <td id=\&quot;file-main-go-LC66\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>BloomFilter</span>: <span class=pl-s1>bloom</span>.<span class=pl-c1>NewWithEstimates</span>(<span class=pl-c1>1_000_000</span>, <span class=pl-c1>0.00001</span>),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L67\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;67\&quot;></td>\n          <td id=\&quot;file-main-go-LC67\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>ttl</span>:         <span class=pl-s1>ttl</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L68\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;68\&quot;></td>\n          <td id=\&quot;file-main-go-LC68\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>workerCtx</span>:   <span class=pl-s1>ctx</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L69\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;69\&quot;></td>\n          <td id=\&quot;file-main-go-LC69\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L70\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;70\&quot;></td>\n          <td id=\&quot;file-main-go-LC70\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>go</span> <span class=pl-s1>bf</span>.<span class=pl-c1>ExpirationWorker</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L71\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;71\&quot;></td>\n          <td id=\&quot;file-main-go-LC71\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>return</span> <span class=pl-s1>bf</span>, <span class=pl-s1>cancel</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L72\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;72\&quot;></td>\n          <td id=\&quot;file-main-go-LC72\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L73\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;73\&quot;></td>\n          <td id=\&quot;file-main-go-LC73\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L74\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;74\&quot;></td>\n          <td id=\&quot;file-main-go-LC74\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> <span class=pl-s1>NewTTLBloomFilter</span>(<span class=pl-s1>ttl</span> time.<span class=pl-smi>Duration</span>) <span class=pl-c1>*</span><span class=pl-smi>TTLBloomFilter</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L75\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;75\&quot;></td>\n          <td id=\&quot;file-main-go-LC75\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>bf</span> <span class=pl-c1>:=</span> <span class=pl-c1>&amp;amp;</span><span class=pl-smi>TTLBloomFilter</span>{</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L76\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;76\&quot;></td>\n          <td id=\&quot;file-main-go-LC76\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>BloomFilter</span>: <span class=pl-s1>bloom</span>.<span class=pl-c1>NewWithEstimates</span>(<span class=pl-c1>1_000_000</span>, <span class=pl-c1>0.00001</span>),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L77\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;77\&quot;></td>\n          <td id=\&quot;file-main-go-LC77\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>ttl</span>:         <span class=pl-s1>ttl</span>,</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L78\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;78\&quot;></td>\n          <td id=\&quot;file-main-go-LC78\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L79\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;79\&quot;></td>\n          <td id=\&quot;file-main-go-LC79\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>return</span> <span class=pl-s1>bf</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L80\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;80\&quot;></td>\n          <td id=\&quot;file-main-go-LC80\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L81\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;81\&quot;></td>\n          <td id=\&quot;file-main-go-LC81\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L82\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;82\&quot;></td>\n          <td id=\&quot;file-main-go-LC82\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>func</span> <span class=pl-s1>main</span>() {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L83\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;83\&quot;></td>\n          <td id=\&quot;file-main-go-LC83\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>bf</span>, <span class=pl-s1>cancel</span> <span class=pl-c1>:=</span> <span class=pl-s1>NewTTLBloomFilterWithContext</span>(<span class=pl-s1>context</span>.<span class=pl-c1>Background</span>(), <span class=pl-c1>5</span><span class=pl-c1>*</span><span class=pl-s1>time</span>.<span class=pl-c1>Second</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L84\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;84\&quot;></td>\n          <td id=\&quot;file-main-go-LC84\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>defer</span> <span class=pl-s1>cancel</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L85\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;85\&quot;></td>\n          <td id=\&quot;file-main-go-LC85\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>bf</span>.<span class=pl-c1>Add</span>([]<span class=pl-smi>byte</span>(<span class=pl-s>&amp;quot;test1&amp;quot;</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L86\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;86\&quot;></td>\n          <td id=\&quot;file-main-go-LC86\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>if</span> <span class=pl-c1>!</span><span class=pl-s1>bf</span>.<span class=pl-c1>Test</span>([]<span class=pl-smi>byte</span>(<span class=pl-s>&amp;quot;test1&amp;quot;</span>)) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L87\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;87\&quot;></td>\n          <td id=\&quot;file-main-go-LC87\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>panic</span>(<span class=pl-s>&amp;quot;test1 not found in bloom filter&amp;quot;</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L88\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;88\&quot;></td>\n          <td id=\&quot;file-main-go-LC88\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L89\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;89\&quot;></td>\n          <td id=\&quot;file-main-go-LC89\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>if</span> <span class=pl-s1>bf</span>.<span class=pl-c1>Test</span>([]<span class=pl-smi>byte</span>(<span class=pl-s>&amp;quot;test2&amp;quot;</span>)) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L90\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;90\&quot;></td>\n          <td id=\&quot;file-main-go-LC90\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>panic</span>(<span class=pl-s>&amp;quot;test2 found in bloom filter&amp;quot;</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L91\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;91\&quot;></td>\n          <td id=\&quot;file-main-go-LC91\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L92\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;92\&quot;></td>\n          <td id=\&quot;file-main-go-LC92\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>time</span>.<span class=pl-c1>Sleep</span>(<span class=pl-c1>5</span> <span class=pl-c1>*</span> <span class=pl-s1>time</span>.<span class=pl-c1>Second</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L93\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;93\&quot;></td>\n          <td id=\&quot;file-main-go-LC93\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>if</span> <span class=pl-s1>bf</span>.<span class=pl-c1>Test</span>([]<span class=pl-smi>byte</span>(<span class=pl-s>&amp;quot;test1&amp;quot;</span>)) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L94\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;94\&quot;></td>\n          <td id=\&quot;file-main-go-LC94\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>panic</span>(<span class=pl-s>&amp;quot;test1 found in bloom filter&amp;quot;</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L95\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;95\&quot;></td>\n          <td id=\&quot;file-main-go-LC95\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L96\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;96\&quot;></td>\n          <td id=\&quot;file-main-go-LC96\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>fmt</span>.<span class=pl-c1>Println</span>(<span class=pl-s1>bf</span>.<span class=pl-c1>Cap</span>() <span class=pl-c1>/</span> <span class=pl-c1>1024.</span> <span class=pl-c1>/</span> <span class=pl-c1>1024.</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-main-go-L97\&quot; class=\&quot;blob-num js-line-number js-blob-rnum\&quot; data-line-number=\&quot;97\&quot;></td>\n          <td id=\&quot;file-main-go-LC97\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/georgepsarakis/557a125abdf6ad99df314ad16595248b/raw/e0d7eeb1b3b0282299f9e7b29f962ac54378e41f/main.go\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/georgepsarakis/557a125abdf6ad99df314ad16595248b#file-main-go\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          main.go\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-0ac919313390.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-0ac919313390.css"><div id="gist142797336" class="gist">
    <div class="gist-file" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container">
  <div id="file-benchmark_test-go" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-go  " style="overflow:auto">

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip="" data-tagsearch-path="benchmark_test.go">
        <tbody><tr>
          <td id="file-benchmark_test-go-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-benchmark_test-go-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">package</span> main</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-benchmark_test-go-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-benchmark_test-go-LC3" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> (</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-benchmark_test-go-LC4" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"context"</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-benchmark_test-go-LC5" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"errors"</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-benchmark_test-go-LC6" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"fmt"</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-benchmark_test-go-LC7" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"testing"</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-benchmark_test-go-LC8" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"time"</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-benchmark_test-go-LC9" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-benchmark_test-go-LC10" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"github.com/golang-jwt/jwt/v5"</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-benchmark_test-go-LC11" class="blob-code blob-code-inner js-file-line">)</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-benchmark_test-go-LC12" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-benchmark_test-go-LC13" class="blob-code blob-code-inner js-file-line"><span class="pl-c">// Define a custom claims structure that includes standard claims</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-benchmark_test-go-LC14" class="blob-code blob-code-inner js-file-line"><span class="pl-k">type</span> <span class="pl-smi">MyClaims</span> <span class="pl-k">struct</span> {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-benchmark_test-go-LC15" class="blob-code blob-code-inner js-file-line">&#9;jwt.<span class="pl-smi">RegisteredClaims</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-benchmark_test-go-LC16" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c1">UserID</span>   <span class="pl-smi">string</span> <span class="pl-s">`json:"user_id"`</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-benchmark_test-go-LC17" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c1">UserRole</span> <span class="pl-smi">string</span> <span class="pl-s">`json:"role"`</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-benchmark_test-go-LC18" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-benchmark_test-go-LC19" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-benchmark_test-go-LC20" class="blob-code blob-code-inner js-file-line"><span class="pl-c">// Global variable to hold the token string for verification benchmarks</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-benchmark_test-go-LC21" class="blob-code blob-code-inner js-file-line"><span class="pl-k">var</span> <span class="pl-s1">tokenString</span> <span class="pl-smi">string</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-benchmark_test-go-LC22" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-benchmark_test-go-LC23" class="blob-code blob-code-inner js-file-line"><span class="pl-c">// Secret key for HMAC signing (must be a strong, cryptographically random key in production)</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-benchmark_test-go-LC24" class="blob-code blob-code-inner js-file-line"><span class="pl-k">const</span> <span class="pl-s1">hmacSecret</span> <span class="pl-c1">=</span> <span class="pl-s">"super-secret-key-for-hmac-sha256-verification-32-bytes"</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-benchmark_test-go-LC25" class="blob-code blob-code-inner js-file-line"><span class="pl-k">const</span> <span class="pl-s1">hmacSecret2</span> <span class="pl-c1">=</span> <span class="pl-s1">hmacSecret</span> <span class="pl-c1">+</span> <span class="pl-s">"-2"</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-benchmark_test-go-LC26" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-benchmark_test-go-LC27" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> <span class="pl-s1">init</span>() {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-benchmark_test-go-LC28" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">claims</span> <span class="pl-c1">:=</span> <span class="pl-smi">MyClaims</span>{</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-benchmark_test-go-LC29" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">RegisteredClaims</span>: jwt.<span class="pl-smi">RegisteredClaims</span>{</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-benchmark_test-go-LC30" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">ExpiresAt</span>: <span class="pl-s1">jwt</span>.<span class="pl-c1">NewNumericDate</span>(<span class="pl-s1">time</span>.<span class="pl-c1">Now</span>().<span class="pl-c1">Add</span>(<span class="pl-s1">time</span>.<span class="pl-c1">Hour</span> <span class="pl-c1">*</span> <span class="pl-c1">24</span>)),</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-benchmark_test-go-LC31" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">IssuedAt</span>:  <span class="pl-s1">jwt</span>.<span class="pl-c1">NewNumericDate</span>(<span class="pl-s1">time</span>.<span class="pl-c1">Now</span>()),</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-benchmark_test-go-LC32" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">Subject</span>:   <span class="pl-s">"test-user"</span>,</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-benchmark_test-go-LC33" class="blob-code blob-code-inner js-file-line">&#9;&#9;},</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-benchmark_test-go-LC34" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">UserID</span>:   <span class="pl-s">"user-12345"</span>,</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-benchmark_test-go-LC35" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">UserRole</span>: <span class="pl-s">"admin"</span>,</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-benchmark_test-go-LC36" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-benchmark_test-go-LC37" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-benchmark_test-go-LC38" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">token</span> <span class="pl-c1">:=</span> <span class="pl-s1">jwt</span>.<span class="pl-c1">NewWithClaims</span>(<span class="pl-s1">jwt</span>.<span class="pl-c1">SigningMethodHS256</span>, <span class="pl-s1">claims</span>)</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-benchmark_test-go-LC39" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">var</span> <span class="pl-s1">err</span> <span class="pl-smi">error</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L40" class="blob-num js-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-benchmark_test-go-LC40" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">tokenString</span>, <span class="pl-s1">err</span> <span class="pl-c1">=</span> <span class="pl-s1">token</span>.<span class="pl-c1">SignedString</span>([]<span class="pl-smi">byte</span>(<span class="pl-s1">hmacSecret2</span>))</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L41" class="blob-num js-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-benchmark_test-go-LC41" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">if</span> <span class="pl-s1">err</span> <span class="pl-c1">!=</span> <span class="pl-c1">nil</span> {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L42" class="blob-num js-line-number js-blob-rnum" data-line-number="42"></td>
          <td id="file-benchmark_test-go-LC42" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">panic</span>(<span class="pl-s1">fmt</span>.<span class="pl-c1">Sprintf</span>(<span class="pl-s">"Failed to sign token in init: %v"</span>, <span class="pl-s1">err</span>))</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L43" class="blob-num js-line-number js-blob-rnum" data-line-number="43"></td>
          <td id="file-benchmark_test-go-LC43" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L44" class="blob-num js-line-number js-blob-rnum" data-line-number="44"></td>
          <td id="file-benchmark_test-go-LC44" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L45" class="blob-num js-line-number js-blob-rnum" data-line-number="45"></td>
          <td id="file-benchmark_test-go-LC45" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L46" class="blob-num js-line-number js-blob-rnum" data-line-number="46"></td>
          <td id="file-benchmark_test-go-LC46" class="blob-code blob-code-inner js-file-line"><span class="pl-c">// Key function for verification that returns the secret</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L47" class="blob-num js-line-number js-blob-rnum" data-line-number="47"></td>
          <td id="file-benchmark_test-go-LC47" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> <span class="pl-s1">keyFunc</span>(<span class="pl-s1">token</span> <span class="pl-c1">*</span>jwt.<span class="pl-smi">Token</span>) (<span class="pl-k">interface</span>{}, <span class="pl-smi">error</span>) {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L48" class="blob-num js-line-number js-blob-rnum" data-line-number="48"></td>
          <td id="file-benchmark_test-go-LC48" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Always check the signing method to prevent algorithm switching attacks</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L49" class="blob-num js-line-number js-blob-rnum" data-line-number="49"></td>
          <td id="file-benchmark_test-go-LC49" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">if</span> <span class="pl-s1">_</span>, <span class="pl-s1">ok</span> <span class="pl-c1">:=</span> <span class="pl-s1">token</span>.<span class="pl-c1">Method</span>.(<span class="pl-c1">*</span>jwt.<span class="pl-smi">SigningMethodHMAC</span>); <span class="pl-c1">!</span><span class="pl-s1">ok</span> {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L50" class="blob-num js-line-number js-blob-rnum" data-line-number="50"></td>
          <td id="file-benchmark_test-go-LC50" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">return</span> <span class="pl-c1">nil</span>, <span class="pl-s1">fmt</span>.<span class="pl-c1">Errorf</span>(<span class="pl-s">"unexpected signing method: %v"</span>, <span class="pl-s1">token</span>.<span class="pl-c1">Header</span>[<span class="pl-s">"alg"</span>])</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L51" class="blob-num js-line-number js-blob-rnum" data-line-number="51"></td>
          <td id="file-benchmark_test-go-LC51" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L52" class="blob-num js-line-number js-blob-rnum" data-line-number="52"></td>
          <td id="file-benchmark_test-go-LC52" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">return</span> []<span class="pl-smi">byte</span>(<span class="pl-s1">hmacSecret</span>), <span class="pl-c1">nil</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L53" class="blob-num js-line-number js-blob-rnum" data-line-number="53"></td>
          <td id="file-benchmark_test-go-LC53" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L54" class="blob-num js-line-number js-blob-rnum" data-line-number="54"></td>
          <td id="file-benchmark_test-go-LC54" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L55" class="blob-num js-line-number js-blob-rnum" data-line-number="55"></td>
          <td id="file-benchmark_test-go-LC55" class="blob-code blob-code-inner js-file-line"><span class="pl-c">// Benchmark the JWT verification process using HS256 and full claims validation</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L56" class="blob-num js-line-number js-blob-rnum" data-line-number="56"></td>
          <td id="file-benchmark_test-go-LC56" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> <span class="pl-s1">BenchmarkJWTVerification_HS256_Failed</span>(<span class="pl-s1">b</span> <span class="pl-c1">*</span>testing.<span class="pl-smi">B</span>) {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L57" class="blob-num js-line-number js-blob-rnum" data-line-number="57"></td>
          <td id="file-benchmark_test-go-LC57" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">var</span> <span class="pl-s1">parsedToken</span> <span class="pl-c1">*</span>jwt.<span class="pl-smi">Token</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L58" class="blob-num js-line-number js-blob-rnum" data-line-number="58"></td>
          <td id="file-benchmark_test-go-LC58" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L59" class="blob-num js-line-number js-blob-rnum" data-line-number="59"></td>
          <td id="file-benchmark_test-go-LC59" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Reset timer to exclude setup time</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L60" class="blob-num js-line-number js-blob-rnum" data-line-number="60"></td>
          <td id="file-benchmark_test-go-LC60" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">b</span>.<span class="pl-c1">ResetTimer</span>()</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L61" class="blob-num js-line-number js-blob-rnum" data-line-number="61"></td>
          <td id="file-benchmark_test-go-LC61" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">b</span>.<span class="pl-c1">ReportAllocs</span>()</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L62" class="blob-num js-line-number js-blob-rnum" data-line-number="62"></td>
          <td id="file-benchmark_test-go-LC62" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L63" class="blob-num js-line-number js-blob-rnum" data-line-number="63"></td>
          <td id="file-benchmark_test-go-LC63" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">:=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">b</span>.<span class="pl-c1">N</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span> {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L64" class="blob-num js-line-number js-blob-rnum" data-line-number="64"></td>
          <td id="file-benchmark_test-go-LC64" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">token</span>, <span class="pl-s1">err</span> <span class="pl-c1">:=</span> <span class="pl-s1">jwt</span>.<span class="pl-c1">ParseWithClaims</span>(<span class="pl-s1">tokenString</span>, <span class="pl-c1">&amp;</span><span class="pl-smi">MyClaims</span>{}, <span class="pl-s1">keyFunc</span>)</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L65" class="blob-num js-line-number js-blob-rnum" data-line-number="65"></td>
          <td id="file-benchmark_test-go-LC65" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">if</span> <span class="pl-s1">err</span> <span class="pl-c1">!=</span> <span class="pl-c1">nil</span> {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L66" class="blob-num js-line-number js-blob-rnum" data-line-number="66"></td>
          <td id="file-benchmark_test-go-LC66" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-k">continue</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L67" class="blob-num js-line-number js-blob-rnum" data-line-number="67"></td>
          <td id="file-benchmark_test-go-LC67" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L68" class="blob-num js-line-number js-blob-rnum" data-line-number="68"></td>
          <td id="file-benchmark_test-go-LC68" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">b</span>.<span class="pl-c1">Fail</span>()</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L69" class="blob-num js-line-number js-blob-rnum" data-line-number="69"></td>
          <td id="file-benchmark_test-go-LC69" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">// Store the result to prevent the compiler from optimizing the whole loop away</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L70" class="blob-num js-line-number js-blob-rnum" data-line-number="70"></td>
          <td id="file-benchmark_test-go-LC70" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">parsedToken</span> <span class="pl-c1">=</span> <span class="pl-s1">token</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L71" class="blob-num js-line-number js-blob-rnum" data-line-number="71"></td>
          <td id="file-benchmark_test-go-LC71" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L72" class="blob-num js-line-number js-blob-rnum" data-line-number="72"></td>
          <td id="file-benchmark_test-go-LC72" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Use the result outside the loop</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L73" class="blob-num js-line-number js-blob-rnum" data-line-number="73"></td>
          <td id="file-benchmark_test-go-LC73" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">_</span> <span class="pl-c1">=</span> <span class="pl-s1">parsedToken</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L74" class="blob-num js-line-number js-blob-rnum" data-line-number="74"></td>
          <td id="file-benchmark_test-go-LC74" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L75" class="blob-num js-line-number js-blob-rnum" data-line-number="75"></td>
          <td id="file-benchmark_test-go-LC75" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L76" class="blob-num js-line-number js-blob-rnum" data-line-number="76"></td>
          <td id="file-benchmark_test-go-LC76" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> <span class="pl-s1">BenchmarkJWTVerification_HS256_BloomFilter</span>(<span class="pl-s1">b</span> <span class="pl-c1">*</span>testing.<span class="pl-smi">B</span>) {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L77" class="blob-num js-line-number js-blob-rnum" data-line-number="77"></td>
          <td id="file-benchmark_test-go-LC77" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">var</span> <span class="pl-s1">parsedToken</span> <span class="pl-c1">*</span>jwt.<span class="pl-smi">Token</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L78" class="blob-num js-line-number js-blob-rnum" data-line-number="78"></td>
          <td id="file-benchmark_test-go-LC78" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L79" class="blob-num js-line-number js-blob-rnum" data-line-number="79"></td>
          <td id="file-benchmark_test-go-LC79" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">b1</span>, <span class="pl-s1">cancel</span> <span class="pl-c1">:=</span> <span class="pl-s1">NewTTLBloomFilterWithContext</span>(<span class="pl-s1">context</span>.<span class="pl-c1">Background</span>(), <span class="pl-s1">time</span>.<span class="pl-c1">Minute</span>)</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L80" class="blob-num js-line-number js-blob-rnum" data-line-number="80"></td>
          <td id="file-benchmark_test-go-LC80" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">defer</span> <span class="pl-s1">cancel</span>()</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L81" class="blob-num js-line-number js-blob-rnum" data-line-number="81"></td>
          <td id="file-benchmark_test-go-LC81" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L82" class="blob-num js-line-number js-blob-rnum" data-line-number="82"></td>
          <td id="file-benchmark_test-go-LC82" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">b</span>.<span class="pl-c1">ResetTimer</span>()</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L83" class="blob-num js-line-number js-blob-rnum" data-line-number="83"></td>
          <td id="file-benchmark_test-go-LC83" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">b</span>.<span class="pl-c1">ReportAllocs</span>()</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L84" class="blob-num js-line-number js-blob-rnum" data-line-number="84"></td>
          <td id="file-benchmark_test-go-LC84" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L85" class="blob-num js-line-number js-blob-rnum" data-line-number="85"></td>
          <td id="file-benchmark_test-go-LC85" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">:=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">b</span>.<span class="pl-c1">N</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span> {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L86" class="blob-num js-line-number js-blob-rnum" data-line-number="86"></td>
          <td id="file-benchmark_test-go-LC86" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">if</span> <span class="pl-s1">b1</span>.<span class="pl-c1">Test</span>([]<span class="pl-smi">byte</span>(<span class="pl-s1">tokenString</span>)) {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L87" class="blob-num js-line-number js-blob-rnum" data-line-number="87"></td>
          <td id="file-benchmark_test-go-LC87" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-k">continue</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L88" class="blob-num js-line-number js-blob-rnum" data-line-number="88"></td>
          <td id="file-benchmark_test-go-LC88" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L89" class="blob-num js-line-number js-blob-rnum" data-line-number="89"></td>
          <td id="file-benchmark_test-go-LC89" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">token</span>, <span class="pl-s1">err</span> <span class="pl-c1">:=</span> <span class="pl-s1">jwt</span>.<span class="pl-c1">ParseWithClaims</span>(<span class="pl-s1">tokenString</span>, <span class="pl-c1">&amp;</span><span class="pl-smi">MyClaims</span>{}, <span class="pl-s1">keyFunc</span>)</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L90" class="blob-num js-line-number js-blob-rnum" data-line-number="90"></td>
          <td id="file-benchmark_test-go-LC90" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">if</span> <span class="pl-s1">errors</span>.<span class="pl-c1">Is</span>(<span class="pl-s1">err</span>, <span class="pl-s1">jwt</span>.<span class="pl-c1">ErrTokenSignatureInvalid</span>) {</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L91" class="blob-num js-line-number js-blob-rnum" data-line-number="91"></td>
          <td id="file-benchmark_test-go-LC91" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">b1</span>.<span class="pl-c1">Add</span>([]<span class="pl-smi">byte</span>(<span class="pl-s1">tokenString</span>))</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L92" class="blob-num js-line-number js-blob-rnum" data-line-number="92"></td>
          <td id="file-benchmark_test-go-LC92" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-k">continue</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L93" class="blob-num js-line-number js-blob-rnum" data-line-number="93"></td>
          <td id="file-benchmark_test-go-LC93" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L94" class="blob-num js-line-number js-blob-rnum" data-line-number="94"></td>
          <td id="file-benchmark_test-go-LC94" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">b</span>.<span class="pl-c1">Fail</span>()</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L95" class="blob-num js-line-number js-blob-rnum" data-line-number="95"></td>
          <td id="file-benchmark_test-go-LC95" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">// Store the result to prevent the compiler from optimizing the whole loop away</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L96" class="blob-num js-line-number js-blob-rnum" data-line-number="96"></td>
          <td id="file-benchmark_test-go-LC96" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">parsedToken</span> <span class="pl-c1">=</span> <span class="pl-s1">token</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L97" class="blob-num js-line-number js-blob-rnum" data-line-number="97"></td>
          <td id="file-benchmark_test-go-LC97" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L98" class="blob-num js-line-number js-blob-rnum" data-line-number="98"></td>
          <td id="file-benchmark_test-go-LC98" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Use the result outside the loop</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L99" class="blob-num js-line-number js-blob-rnum" data-line-number="99"></td>
          <td id="file-benchmark_test-go-LC99" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">_</span> <span class="pl-c1">=</span> <span class="pl-s1">parsedToken</span></td>
        </tr>
        <tr>
          <td id="file-benchmark_test-go-L100" class="blob-num js-line-number js-blob-rnum" data-line-number="100"></td>
          <td id="file-benchmark_test-go-LC100" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/georgepsarakis/557a125abdf6ad99df314ad16595248b/raw/e0d7eeb1b3b0282299f9e7b29f962ac54378e41f/benchmark_test.go" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/georgepsarakis/557a125abdf6ad99df314ad16595248b#file-benchmark_test-go" class="Link--inTextBlock">
          benchmark_test.go
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
    <div class="gist-file" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container">
  <div id="file-main-go" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-go  " style="overflow:auto">

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip="" data-tagsearch-path="main.go">
        <tbody><tr>
          <td id="file-main-go-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-main-go-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">package</span> main</td>
        </tr>
        <tr>
          <td id="file-main-go-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-main-go-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-main-go-LC3" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> (</td>
        </tr>
        <tr>
          <td id="file-main-go-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-main-go-LC4" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"context"</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-main-go-LC5" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"fmt"</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-main-go-LC6" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"sync"</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-main-go-LC7" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"time"</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-main-go-LC8" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-main-go-LC9" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s">"github.com/bits-and-blooms/bloom/v3"</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-main-go-LC10" class="blob-code blob-code-inner js-file-line">)</td>
        </tr>
        <tr>
          <td id="file-main-go-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-main-go-LC11" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-main-go-LC12" class="blob-code blob-code-inner js-file-line"><span class="pl-k">type</span> <span class="pl-smi">TTLBloomFilter</span> <span class="pl-k">struct</span> {</td>
        </tr>
        <tr>
          <td id="file-main-go-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-main-go-LC13" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c1">*</span>bloom.<span class="pl-smi">BloomFilter</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-main-go-LC14" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c1">ttl</span>       time.<span class="pl-smi">Duration</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-main-go-LC15" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c1">lock</span>      sync.<span class="pl-smi">RWMutex</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-main-go-LC16" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c1">workerCtx</span> context.<span class="pl-smi">Context</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-main-go-LC17" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main-go-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-main-go-LC18" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-main-go-LC19" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> (<span class="pl-s1">f</span> <span class="pl-c1">*</span><span class="pl-smi">TTLBloomFilter</span>) <span class="pl-c1">Add</span>(<span class="pl-s1">item</span> []<span class="pl-smi">byte</span>) {</td>
        </tr>
        <tr>
          <td id="file-main-go-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-main-go-LC20" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">f</span>.<span class="pl-c1">lock</span>.<span class="pl-c1">Lock</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-main-go-LC21" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">defer</span> <span class="pl-s1">f</span>.<span class="pl-c1">lock</span>.<span class="pl-c1">Unlock</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-main-go-LC22" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">f</span>.<span class="pl-c1">BloomFilter</span>.<span class="pl-c1">Add</span>(<span class="pl-s1">item</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-main-go-LC23" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main-go-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-main-go-LC24" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-main-go-LC25" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> (<span class="pl-s1">f</span> <span class="pl-c1">*</span><span class="pl-smi">TTLBloomFilter</span>) <span class="pl-c1">Test</span>(<span class="pl-s1">item</span> []<span class="pl-smi">byte</span>) <span class="pl-smi">bool</span> {</td>
        </tr>
        <tr>
          <td id="file-main-go-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-main-go-LC26" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">f</span>.<span class="pl-c1">lock</span>.<span class="pl-c1">RLock</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-main-go-LC27" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">defer</span> <span class="pl-s1">f</span>.<span class="pl-c1">lock</span>.<span class="pl-c1">RUnlock</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-main-go-LC28" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">return</span> <span class="pl-s1">f</span>.<span class="pl-c1">BloomFilter</span>.<span class="pl-c1">Test</span>(<span class="pl-s1">item</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-main-go-LC29" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main-go-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-main-go-LC30" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-main-go-LC31" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> (<span class="pl-s1">f</span> <span class="pl-c1">*</span><span class="pl-smi">TTLBloomFilter</span>) <span class="pl-c1">WithContext</span>(<span class="pl-s1">ctx</span> context.<span class="pl-smi">Context</span>) <span class="pl-c1">*</span><span class="pl-smi">TTLBloomFilter</span> {</td>
        </tr>
        <tr>
          <td id="file-main-go-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-main-go-LC32" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">f</span>.<span class="pl-c1">lock</span>.<span class="pl-c1">RLock</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-main-go-LC33" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">defer</span> <span class="pl-s1">f</span>.<span class="pl-c1">lock</span>.<span class="pl-c1">RUnlock</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-main-go-LC34" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">return</span> <span class="pl-c1">&amp;</span><span class="pl-smi">TTLBloomFilter</span>{</td>
        </tr>
        <tr>
          <td id="file-main-go-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-main-go-LC35" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">BloomFilter</span>: <span class="pl-s1">f</span>.<span class="pl-c1">Copy</span>(),</td>
        </tr>
        <tr>
          <td id="file-main-go-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-main-go-LC36" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">ttl</span>:         <span class="pl-s1">f</span>.<span class="pl-c1">ttl</span>,</td>
        </tr>
        <tr>
          <td id="file-main-go-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-main-go-LC37" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">workerCtx</span>:   <span class="pl-s1">ctx</span>,</td>
        </tr>
        <tr>
          <td id="file-main-go-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-main-go-LC38" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-main-go-LC39" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main-go-L40" class="blob-num js-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-main-go-LC40" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L41" class="blob-num js-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-main-go-LC41" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> (<span class="pl-s1">f</span> <span class="pl-c1">*</span><span class="pl-smi">TTLBloomFilter</span>) <span class="pl-c1">ExpirationWorker</span>() {</td>
        </tr>
        <tr>
          <td id="file-main-go-L42" class="blob-num js-line-number js-blob-rnum" data-line-number="42"></td>
          <td id="file-main-go-LC42" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">ctx</span> <span class="pl-c1">:=</span> <span class="pl-s1">f</span>.<span class="pl-c1">workerCtx</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L43" class="blob-num js-line-number js-blob-rnum" data-line-number="43"></td>
          <td id="file-main-go-LC43" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">if</span> <span class="pl-s1">ctx</span> <span class="pl-c1">==</span> <span class="pl-c1">nil</span> {</td>
        </tr>
        <tr>
          <td id="file-main-go-L44" class="blob-num js-line-number js-blob-rnum" data-line-number="44"></td>
          <td id="file-main-go-LC44" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">ctx</span> <span class="pl-c1">=</span> <span class="pl-s1">context</span>.<span class="pl-c1">Background</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L45" class="blob-num js-line-number js-blob-rnum" data-line-number="45"></td>
          <td id="file-main-go-LC45" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L46" class="blob-num js-line-number js-blob-rnum" data-line-number="46"></td>
          <td id="file-main-go-LC46" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">ticker</span> <span class="pl-c1">:=</span> <span class="pl-s1">time</span>.<span class="pl-c1">NewTicker</span>(<span class="pl-s1">f</span>.<span class="pl-c1">ttl</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L47" class="blob-num js-line-number js-blob-rnum" data-line-number="47"></td>
          <td id="file-main-go-LC47" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">resetFunc</span> <span class="pl-c1">:=</span> <span class="pl-k">func</span>() {</td>
        </tr>
        <tr>
          <td id="file-main-go-L48" class="blob-num js-line-number js-blob-rnum" data-line-number="48"></td>
          <td id="file-main-go-LC48" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">f</span>.<span class="pl-c1">lock</span>.<span class="pl-c1">Lock</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L49" class="blob-num js-line-number js-blob-rnum" data-line-number="49"></td>
          <td id="file-main-go-LC49" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">defer</span> <span class="pl-s1">f</span>.<span class="pl-c1">lock</span>.<span class="pl-c1">Unlock</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L50" class="blob-num js-line-number js-blob-rnum" data-line-number="50"></td>
          <td id="file-main-go-LC50" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">f</span>.<span class="pl-c1">ClearAll</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L51" class="blob-num js-line-number js-blob-rnum" data-line-number="51"></td>
          <td id="file-main-go-LC51" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L52" class="blob-num js-line-number js-blob-rnum" data-line-number="52"></td>
          <td id="file-main-go-LC52" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span> {</td>
        </tr>
        <tr>
          <td id="file-main-go-L53" class="blob-num js-line-number js-blob-rnum" data-line-number="53"></td>
          <td id="file-main-go-LC53" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">select</span> {</td>
        </tr>
        <tr>
          <td id="file-main-go-L54" class="blob-num js-line-number js-blob-rnum" data-line-number="54"></td>
          <td id="file-main-go-LC54" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">case</span> <span class="pl-c1">&lt;-</span><span class="pl-s1">ticker</span>.<span class="pl-c1">C</span>:</td>
        </tr>
        <tr>
          <td id="file-main-go-L55" class="blob-num js-line-number js-blob-rnum" data-line-number="55"></td>
          <td id="file-main-go-LC55" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">resetFunc</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L56" class="blob-num js-line-number js-blob-rnum" data-line-number="56"></td>
          <td id="file-main-go-LC56" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">case</span> <span class="pl-c1">&lt;-</span><span class="pl-s1">ctx</span>.<span class="pl-c1">Done</span>():</td>
        </tr>
        <tr>
          <td id="file-main-go-L57" class="blob-num js-line-number js-blob-rnum" data-line-number="57"></td>
          <td id="file-main-go-LC57" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">resetFunc</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L58" class="blob-num js-line-number js-blob-rnum" data-line-number="58"></td>
          <td id="file-main-go-LC58" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-k">return</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L59" class="blob-num js-line-number js-blob-rnum" data-line-number="59"></td>
          <td id="file-main-go-LC59" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L60" class="blob-num js-line-number js-blob-rnum" data-line-number="60"></td>
          <td id="file-main-go-LC60" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L61" class="blob-num js-line-number js-blob-rnum" data-line-number="61"></td>
          <td id="file-main-go-LC61" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main-go-L62" class="blob-num js-line-number js-blob-rnum" data-line-number="62"></td>
          <td id="file-main-go-LC62" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L63" class="blob-num js-line-number js-blob-rnum" data-line-number="63"></td>
          <td id="file-main-go-LC63" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> <span class="pl-s1">NewTTLBloomFilterWithContext</span>(<span class="pl-s1">ctx</span> context.<span class="pl-smi">Context</span>, <span class="pl-s1">ttl</span> time.<span class="pl-smi">Duration</span>) (<span class="pl-c1">*</span><span class="pl-smi">TTLBloomFilter</span>, context.<span class="pl-smi">CancelFunc</span>) {</td>
        </tr>
        <tr>
          <td id="file-main-go-L64" class="blob-num js-line-number js-blob-rnum" data-line-number="64"></td>
          <td id="file-main-go-LC64" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">ctx</span>, <span class="pl-s1">cancel</span> <span class="pl-c1">:=</span> <span class="pl-s1">context</span>.<span class="pl-c1">WithCancel</span>(<span class="pl-s1">ctx</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L65" class="blob-num js-line-number js-blob-rnum" data-line-number="65"></td>
          <td id="file-main-go-LC65" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">bf</span> <span class="pl-c1">:=</span> <span class="pl-c1">&amp;</span><span class="pl-smi">TTLBloomFilter</span>{</td>
        </tr>
        <tr>
          <td id="file-main-go-L66" class="blob-num js-line-number js-blob-rnum" data-line-number="66"></td>
          <td id="file-main-go-LC66" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">BloomFilter</span>: <span class="pl-s1">bloom</span>.<span class="pl-c1">NewWithEstimates</span>(<span class="pl-c1">1_000_000</span>, <span class="pl-c1">0.00001</span>),</td>
        </tr>
        <tr>
          <td id="file-main-go-L67" class="blob-num js-line-number js-blob-rnum" data-line-number="67"></td>
          <td id="file-main-go-LC67" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">ttl</span>:         <span class="pl-s1">ttl</span>,</td>
        </tr>
        <tr>
          <td id="file-main-go-L68" class="blob-num js-line-number js-blob-rnum" data-line-number="68"></td>
          <td id="file-main-go-LC68" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">workerCtx</span>:   <span class="pl-s1">ctx</span>,</td>
        </tr>
        <tr>
          <td id="file-main-go-L69" class="blob-num js-line-number js-blob-rnum" data-line-number="69"></td>
          <td id="file-main-go-LC69" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L70" class="blob-num js-line-number js-blob-rnum" data-line-number="70"></td>
          <td id="file-main-go-LC70" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">go</span> <span class="pl-s1">bf</span>.<span class="pl-c1">ExpirationWorker</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L71" class="blob-num js-line-number js-blob-rnum" data-line-number="71"></td>
          <td id="file-main-go-LC71" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">return</span> <span class="pl-s1">bf</span>, <span class="pl-s1">cancel</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L72" class="blob-num js-line-number js-blob-rnum" data-line-number="72"></td>
          <td id="file-main-go-LC72" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main-go-L73" class="blob-num js-line-number js-blob-rnum" data-line-number="73"></td>
          <td id="file-main-go-LC73" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L74" class="blob-num js-line-number js-blob-rnum" data-line-number="74"></td>
          <td id="file-main-go-LC74" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> <span class="pl-s1">NewTTLBloomFilter</span>(<span class="pl-s1">ttl</span> time.<span class="pl-smi">Duration</span>) <span class="pl-c1">*</span><span class="pl-smi">TTLBloomFilter</span> {</td>
        </tr>
        <tr>
          <td id="file-main-go-L75" class="blob-num js-line-number js-blob-rnum" data-line-number="75"></td>
          <td id="file-main-go-LC75" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">bf</span> <span class="pl-c1">:=</span> <span class="pl-c1">&amp;</span><span class="pl-smi">TTLBloomFilter</span>{</td>
        </tr>
        <tr>
          <td id="file-main-go-L76" class="blob-num js-line-number js-blob-rnum" data-line-number="76"></td>
          <td id="file-main-go-LC76" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">BloomFilter</span>: <span class="pl-s1">bloom</span>.<span class="pl-c1">NewWithEstimates</span>(<span class="pl-c1">1_000_000</span>, <span class="pl-c1">0.00001</span>),</td>
        </tr>
        <tr>
          <td id="file-main-go-L77" class="blob-num js-line-number js-blob-rnum" data-line-number="77"></td>
          <td id="file-main-go-LC77" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">ttl</span>:         <span class="pl-s1">ttl</span>,</td>
        </tr>
        <tr>
          <td id="file-main-go-L78" class="blob-num js-line-number js-blob-rnum" data-line-number="78"></td>
          <td id="file-main-go-LC78" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L79" class="blob-num js-line-number js-blob-rnum" data-line-number="79"></td>
          <td id="file-main-go-LC79" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">return</span> <span class="pl-s1">bf</span></td>
        </tr>
        <tr>
          <td id="file-main-go-L80" class="blob-num js-line-number js-blob-rnum" data-line-number="80"></td>
          <td id="file-main-go-LC80" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-main-go-L81" class="blob-num js-line-number js-blob-rnum" data-line-number="81"></td>
          <td id="file-main-go-LC81" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-main-go-L82" class="blob-num js-line-number js-blob-rnum" data-line-number="82"></td>
          <td id="file-main-go-LC82" class="blob-code blob-code-inner js-file-line"><span class="pl-k">func</span> <span class="pl-s1">main</span>() {</td>
        </tr>
        <tr>
          <td id="file-main-go-L83" class="blob-num js-line-number js-blob-rnum" data-line-number="83"></td>
          <td id="file-main-go-LC83" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">bf</span>, <span class="pl-s1">cancel</span> <span class="pl-c1">:=</span> <span class="pl-s1">NewTTLBloomFilterWithContext</span>(<span class="pl-s1">context</span>.<span class="pl-c1">Background</span>(), <span class="pl-c1">5</span><span class="pl-c1">*</span><span class="pl-s1">time</span>.<span class="pl-c1">Second</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L84" class="blob-num js-line-number js-blob-rnum" data-line-number="84"></td>
          <td id="file-main-go-LC84" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">defer</span> <span class="pl-s1">cancel</span>()</td>
        </tr>
        <tr>
          <td id="file-main-go-L85" class="blob-num js-line-number js-blob-rnum" data-line-number="85"></td>
          <td id="file-main-go-LC85" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">bf</span>.<span class="pl-c1">Add</span>([]<span class="pl-smi">byte</span>(<span class="pl-s">"test1"</span>))</td>
        </tr>
        <tr>
          <td id="file-main-go-L86" class="blob-num js-line-number js-blob-rnum" data-line-number="86"></td>
          <td id="file-main-go-LC86" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">if</span> <span class="pl-c1">!</span><span class="pl-s1">bf</span>.<span class="pl-c1">Test</span>([]<span class="pl-smi">byte</span>(<span class="pl-s">"test1"</span>)) {</td>
        </tr>
        <tr>
          <td id="file-main-go-L87" class="blob-num js-line-number js-blob-rnum" data-line-number="87"></td>
          <td id="file-main-go-LC87" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">panic</span>(<span class="pl-s">"test1 not found in bloom filter"</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L88" class="blob-num js-line-number js-blob-rnum" data-line-number="88"></td>
          <td id="file-main-go-LC88" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L89" class="blob-num js-line-number js-blob-rnum" data-line-number="89"></td>
          <td id="file-main-go-LC89" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">if</span> <span class="pl-s1">bf</span>.<span class="pl-c1">Test</span>([]<span class="pl-smi">byte</span>(<span class="pl-s">"test2"</span>)) {</td>
        </tr>
        <tr>
          <td id="file-main-go-L90" class="blob-num js-line-number js-blob-rnum" data-line-number="90"></td>
          <td id="file-main-go-LC90" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">panic</span>(<span class="pl-s">"test2 found in bloom filter"</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L91" class="blob-num js-line-number js-blob-rnum" data-line-number="91"></td>
          <td id="file-main-go-LC91" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L92" class="blob-num js-line-number js-blob-rnum" data-line-number="92"></td>
          <td id="file-main-go-LC92" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">time</span>.<span class="pl-c1">Sleep</span>(<span class="pl-c1">5</span> <span class="pl-c1">*</span> <span class="pl-s1">time</span>.<span class="pl-c1">Second</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L93" class="blob-num js-line-number js-blob-rnum" data-line-number="93"></td>
          <td id="file-main-go-LC93" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">if</span> <span class="pl-s1">bf</span>.<span class="pl-c1">Test</span>([]<span class="pl-smi">byte</span>(<span class="pl-s">"test1"</span>)) {</td>
        </tr>
        <tr>
          <td id="file-main-go-L94" class="blob-num js-line-number js-blob-rnum" data-line-number="94"></td>
          <td id="file-main-go-LC94" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">panic</span>(<span class="pl-s">"test1 found in bloom filter"</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L95" class="blob-num js-line-number js-blob-rnum" data-line-number="95"></td>
          <td id="file-main-go-LC95" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-main-go-L96" class="blob-num js-line-number js-blob-rnum" data-line-number="96"></td>
          <td id="file-main-go-LC96" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">fmt</span>.<span class="pl-c1">Println</span>(<span class="pl-s1">bf</span>.<span class="pl-c1">Cap</span>() <span class="pl-c1">/</span> <span class="pl-c1">1024.</span> <span class="pl-c1">/</span> <span class="pl-c1">1024.</span>)</td>
        </tr>
        <tr>
          <td id="file-main-go-L97" class="blob-num js-line-number js-blob-rnum" data-line-number="97"></td>
          <td id="file-main-go-LC97" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/georgepsarakis/557a125abdf6ad99df314ad16595248b/raw/e0d7eeb1b3b0282299f9e7b29f962ac54378e41f/main.go" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/georgepsarakis/557a125abdf6ad99df314ad16595248b#file-main-go" class="Link--inTextBlock">
          main.go
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>Results of this benchmark on a M2 Pro:</p><pre><code>cpu: Apple M2 Pro
BenchmarkJWTVerification_HS256_Failed
BenchmarkJWTVerification_HS256_Failed-10         &#9;  368486&#9;      3197 ns/op&#9;    2993 B/op&#9;      56 allocs/op
BenchmarkJWTVerification_HS256_BloomFilter
BenchmarkJWTVerification_HS256_BloomFilter-10    &#9;21016758&#9;        56.43 ns/op&#9;       0 B/op&#9;       0 allocs/op</code></pre><p>We observe a <strong>drastic reduction on computational time (~60x) and memory allocations dropping to 0.</strong></p><h2>Conclusion</h2><p>Bloom Filters provide an efficient way to perform set membership tests. We examined a use case where invalid JWT tokens can be cached in order to avoid further unnecessary computations on subsequent requests using the same invalid token.</p><h2>References</h2><ul><li><p><a href="https://en.wikipedia.org/wiki/Bloom_filter">https://en.wikipedia.org/wiki/Bloom_filter</a></p></li><li><p><a href="https://github.com/bits-and-blooms/bloom">https://github.com/bits-and-blooms/bloom</a></p></li><li><p><a href="https://en.wikipedia.org/wiki/Randomized_algorithm#Data_structures">https://en.wikipedia.org/wiki/Randomized_algorithm#Data_structures</a></p></li><li><p><a href="https://www.geeksforgeeks.org/dsa/introduction-to-the-probabilistic-data-structure/">https://www.geeksforgeeks.org/dsa/introduction-to-the-probabilistic-data-structure/</a></p></li><li><p><a href="https://eli.thegreenplace.net/2025/bloom-filters/">https://eli.thegreenplace.net/2025/bloom-filters/</a></p></li><li><p><a href="https://www.researchgate.net/publication/266650658_Weighted_Cache_Replace_Algorithm_for_Storage_System">https://www.researchgate.net/publication/266650658_Weighted_Cache_Replace_Algorithm_for_Storage_System</a></p><p></p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://controlflow.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Control Flow! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Learning a programming language]]></title><description><![CDATA[Useful guidelines for familiarizing with programming languages]]></description><link>https://controlflow.substack.com/p/learning-a-programming-language</link><guid isPermaLink="false">https://controlflow.substack.com/p/learning-a-programming-language</guid><dc:creator><![CDATA[George Psarakis]]></dc:creator><pubDate>Sat, 02 Mar 2024 07:35:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F49fa040d-0a5e-4e2d-814b-722e10197312_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Software engineers often need to learn more than one programming languages during their career. This requirement can arise when changing companies and working on a different stack or when a new language is being adopted gradually.</p><p>Switching to a new language is not an easy decision and it may affect the entire software development lifecycle. Time &amp; effort needs to be spent to ramp up the engineering team&#8217;s understanding of the language syntax, design/testing patterns &amp; optimal code architecture. Perhaps more importantly, the team needs to familiarize with the operational behavior of the runtime under production workloads!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://controlflow.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Control Flow! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>The more widespread adoption of service-oriented architectures and the advances in operational automation nowadays allow the use of a wider range of languages and runtimes. Some example factors that may affect this design decision can be the following: </p><ul><li><p>A runtime with efficient concurrency support can provide very high throughput with a very low resource footprint, depending on the workload characteristics (e.g. NodeJS, Go).</p></li><li><p>A strong ecosystem and community may supply mature, well-tested, efficient libraries and frameworks that can boost development considerably. For example, Python has been so far a very popular choice for building Machine Learning services and enabling Data Science research. </p></li></ul><p>Learning a new programming language and familiarizing with the runtime and the ecosystem can be both interesting and challenging at the same time. Obviously acquiring expertise requires time and frequent hands-on work on real use cases and tasks. Let&#8217;s see if we can approach learning in a way that helps us become efficient faster!</p><h2>Getting Started</h2><p><strong>Finding resources and reading material.</strong> Several languages offer abundant web-based resources for running code snippets, a structured language reference and extensive tutorials. I would recommend starting with a book that&#8217;s focused on teaching the fundamentals of the language and allows you to gradually build up your knowledge. The <code>Learning</code> series by O&#8217;Reilly is usually structured this way, but if you&#8217;re already an experienced software engineer perhaps you&#8217;d be more comfortable with more fast-paced, advanced material. I would definitely advise against skipping the fundamentals completely though, as you&#8217;ll keep stumbling on minor issues.</p><blockquote><p>Find a technical book that&#8217;s focused on teaching the language fundamentals.</p></blockquote><p>Installing the language runtime is our next step, as we need to be able to execute any code snippets built during the learning process. While you can use a browser-based, language playground, you might find it beneficial to familiarize with runtime installation and its behavior.</p><blockquote><p>Prefer a local installation of the language runtime.</p></blockquote><p><strong>Setup your editor/IDE to work with the specific language.</strong> A recommendation here is that your configuration allows you to quickly jump to type &amp; function definitions of standard or third-party libraries and read the code. You can see an example with Jetbrains Pycharm <a href="https://www.jetbrains.com/help/pycharm/viewing-definition.html">here</a>. There are some significant benefits of having this capability:</p><ol><li><p>You can read  the documentation and actual code for a standard library function, without leaving your editor window. <strong>The standard library tends to be also highly optimized and idiomatic, since it&#8217;s maintained by experts on the language.</strong></p></li><li><p>If you have enabled a debugger, you can do start a step-by-step debugging session to confirm how the code works.</p></li></ol><p><strong>Start a small project.</strong> While writing simple functions, loops, if statements is definitely a good first step, you&#8217;ll probably need a small toy project, such as a Todo List manager or something similar that requires CRUD operations and working with data.</p><h2>The Basics</h2><p>First things to cover:</p><ul><li><p>Primitive types</p></li><li><p>Variable initialization</p></li><li><p>Arithmetic and logical operators</p></li><li><p>If-else statements</p></li><li><p>Loops</p></li><li><p>Iterables</p></li></ul><blockquote><p>While not ideal for production-ready applications, translating already well-understood code from a different language is still useful for learning, since you&#8217;ll start mapping already familiar concepts right away!</p></blockquote><p>Mathematical problems are usually the easiest to implement at first, e.g. calculating the sum or the median of an array of integers which will require some use of loops, conditional statements and data structures like arrays. It&#8217;s better to start with <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a> at first and avoid any kind of state management. Usually such problems are ideal since they can be modelled using a procedural approach. <a href="https://en.wikipedia.org/wiki/Procedural_programming">Procedural programming</a> is universally available across languages and even on heavily object-oriented languages (e.g. Java) you can define functions as static methods attached to classes.</p><blockquote><p>Do not spend effort on idiomatic syntax and performance optimizations at this stage.</p></blockquote><p>You can then proceed with learning about custom type &amp; function definitions, inheritance and object model (if applicable).</p><h2>More Advanced Topics</h2><ul><li><p><strong>Writing tests:</strong> familiarizing with test runners and assertion libraries. Some languages have built-in testing frameworks some others don&#8217;t.</p></li><li><p><strong>Errors/exceptions and stack traces:</strong> being able to identify the root cause for a failure is essential for your development workflow and production deployments alike.</p></li><li><p><strong>Mutable and immutable types:</strong> mutability is an important concept and differs among languages. It affects how code is structured and when not thoroughly understood can lead to serious bugs or memory issues.</p></li><li><p><strong>Concurrency model:</strong> most languages support concurrency either via green or OS threads, multi-processing, async I/O. It&#8217;s useful to familiarize with the fundamentals, just to be aware of what capabilities are supported.</p></li><li><p><strong>Variable scope:</strong> some languages can create locally scoped variables in statements and blocks. Incorrect scope understanding can become a source of errors.</p></li><li><p><strong><a href="https://en.wikipedia.org/wiki/Closure_(computer_programming)">Closures</a></strong></p></li><li><p><strong>Error-prone anti-patterns:</strong> for example you can find <a href="https://docs.python-guide.org/writing/gotchas/">here</a> a list of common Python gotchas.</p></li></ul><h2>Common Mistakes &amp; How to Avoid Them</h2><p><em>Reinvention</em></p><p>The uncertainty of entering an unknown ecosystem can often lead to some tendency to reinvent. If you find yourself implementing something seemingly very fundamental, you may need to take a step back and do some research first. Unless you&#8217;re solving a very unique problem, the chances are that there are already available libraries that can help partially or fully address your requirements.</p><p><em>Translation</em></p><p>You can sometimes notice that a codebase is heavily influenced by a language different than the one it&#8217;s being written in. It takes some time to get used to another language&#8217;s optimal code architecture &amp; patterns. How do you know if you&#8217;re writing something in the recommended/most popular way? Well, sometimes it won&#8217;t be easy to understand whether something seems too difficult because <em>it shouldn&#8217;t be done this way </em>or because<em> you&#8217;re just struggling due to inexperience</em>. Sometimes linter tooling can help point you to the right direction, but it&#8217;ll require mostly reading (a lot!) existing code from the standard library and very popular OSS projects, as well as articles from language experts. </p><p><em>Full Software Development Lifecycle</em></p><p>Do not underestimate the effort and learning curve to make the code testable, in addition to learning the whereabouts of the testing frameworks. In-depth knowledge of the testing frameworks is necessary in order to give you confidence that the code works as expected. Although your knowledge on testing practices is definitely transferrable, what often differs greatly is testing frameworks, stubbing/mocking libraries and injection patterns, and of course assertions. </p><p>Different performance characteristics and runtime design may also require different production stack. For example, NodeJS is very performant for async I/O but is single-threaded when it comes to CPU-bound operations and the same applies to Python with ASGI. Thus, production-ready application servers must be capable of spawning multiple sub-processes in order to take advantage of multi-core machines.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://controlflow.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Control Flow! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Introduction to Asynchronous Tasks Architecture]]></title><description><![CDATA[Design patterns, best practices and architectural insights for async task execution]]></description><link>https://controlflow.substack.com/p/introduction-to-asynchronous-tasks</link><guid isPermaLink="false">https://controlflow.substack.com/p/introduction-to-asynchronous-tasks</guid><dc:creator><![CDATA[George Psarakis]]></dc:creator><pubDate>Sun, 02 Jan 2022 12:25:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F49fa040d-0a5e-4e2d-814b-722e10197312_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Asynchronous tasks are commonplace in backend and infrastructure engineering. This is the first in a series of articles aiming to present suggestions and insights on architecting and maintaining effective asynchronous task frameworks and pipelines.</p><p>In the upcoming articles the following topics will be explored:</p><ul><li><p><strong>Message Structure and Serialization Formats</strong></p><ul><li><p>Headers &amp; Versioning</p></li><li><p>Schema Validation</p></li><li><p>JSON, YAML, Thrift, Avro, Protocol Buffers</p></li><li><p>Language-specific marshalling</p></li><li><p>Security: Signing and Encryption</p></li></ul></li><li><p><strong>Essential Data Structures</strong></p><ul><li><p>FIFO/LIFO/Priority Queues</p></li><li><p>Sorted Sets</p></li><li><p>Sharded Queues</p></li></ul></li><li><p><strong>Messaging Patterns</strong></p><ul><li><p>Event Notification</p></li><li><p>Topics &amp; Streams</p></li><li><p>Task Queue</p></li><li><p>Pub/Sub</p></li></ul></li><li><p><strong>Message Delivery</strong></p><ul><li><p>Fanout</p></li><li><p>Early / Late &amp; Negative Acknowledgement</p></li><li><p>Failure Handling with Dead-Letter Queues</p></li><li><p>At-least-once/Exactly-once/At-most-once Guarantees</p></li><li><p>Deduplication</p></li></ul></li><li><p><strong>Message Brokers</strong></p><ul><li><p>RabbitMQ</p></li><li><p>Redis</p></li><li><p>Kafka</p></li><li><p>AWS SQS</p></li><li><p>RDBMS (MySQL/PostgreSQL)</p></li></ul></li><li><p><strong>Task Design</strong></p><ul><li><p>Idempotence &amp; Optimal Parameter Selection</p></li><li><p>Timeouts</p></li><li><p>Error Handling &amp; Retries</p></li><li><p>Acknowledgement Timeout</p></li></ul></li><li><p><strong>Task Processing</strong></p><ul><li><p>Worker Pool Concepts &amp; Types</p></li><li><p>Context &amp; Tracing</p></li><li><p>Horizontal Scalability &amp; Auto-Scaling</p></li><li><p>Interdependent Tasks - Directed Acyclic Graphs</p></li><li><p>Scheduled / Delayed Tasks</p></li><li><p>Circuit Breaker Pattern</p></li><li><p>Rate Limiting</p></li></ul></li><li><p><strong>Frameworks, Services and Workflow Management Platforms</strong></p><ul><li><p><a href="https://github.com/resque/resque">Resque</a>, <a href="https://github.com/mperham/sidekiq">Sidekiq</a>, <a href="https://github.com/celery/celery">Celery</a>, <a href="https://github.com/contribsys/faktory">Faktory</a></p></li><li><p><a href="https://aws.amazon.com/lambda/">AWS Lambda</a></p></li><li><p><a href="https://airflow.apache.org/">Apache Airflow</a>, <a href="https://github.com/spotify/luigi">Luigi</a></p></li></ul></li></ul><p>The above topics should provide a comprehensive theoretical background but how applicable are these concepts to actual use cases? Throughout the article series we&#8217;ll be using a sample application comprising several processes, to help us visualize how each architectural pattern addresses real-world scenarios. Our application will be an implementation of a very common System Design question, the <em>URL Shortener Service</em>.</p><p>The main goal of the service is to provide one or more unique, shorter URLs that redirect to the target URL:</p><pre><code>GET https://url-shortener-service.io/q2csXrZC

HTTP/1.1 301 Moved Permanently
location: https://controlflow.substack.com/async-task-architecture</code></pre><p>This is a seemingly simple operation, but let&#8217;s try to lay out some of the features and  functional requirements for a SaaS offering and determine where async task execution is applicable.</p><h4><strong>Authentication &amp; Authorization</strong></h4><p><em>Email address verification during signup</em></p><p>An email containing the verification URL is sent to the email address of the new user account.</p><p><em>Password Change/Reset Requests</em></p><p>Users will be notified on password changes and must receive a link for password resets.</p><h4>Redirect Setup</h4><p>When a new redirect is configured, the change must be propagated to the redirect proxy service, which is likely using a cache of valid URLs. Likewise, when a redirect is disabled/removed, the cache must be updated to stop serving requests for this short URL.</p><h4>Analytics</h4><p>The service collects analytics for each redirect, such as total views, view count aggregated by referrer domain or user agent.</p><p>The redirect operation should have very low latency, thus the service must forward the HTTP request information to a queue or stream for async processing.</p><h4>Paid Accounts</h4><p>Our service will have paid features such as using a custom domain for shortened URLs and will offer a free tier that limits the total active redirect URLs or the total views per month.</p><p>Cost calculations occur asynchronously and warning notifications about reaching the end of the free tier quota are also sent via email in the background.</p><h4>Billing</h4><p>Assuming a usage-based billing plan, the corresponding amount must be calculated and charged on the account&#8217;s credit card each month. A new invoice is issued and the billing contact receives it as an email attachment.</p><p>The users may also want to configure billing alerts in order to be informed early about sudden increases in charges.</p><p>The above operations are not triggered by a user action, but instead are executed on regular intervals in the background.</p><div><hr></div><p><em>What&#8217;s next?</em></p><p>The next article in the series will discuss <em><strong>Message Structure and Serialization Formats.</strong></em></p>]]></content:encoded></item><item><title><![CDATA[Types of Technical Interviews]]></title><description><![CDATA[The different flavors of technical-oriented assessments]]></description><link>https://controlflow.substack.com/p/types-of-technical-interviews</link><guid isPermaLink="false">https://controlflow.substack.com/p/types-of-technical-interviews</guid><dc:creator><![CDATA[George Psarakis]]></dc:creator><pubDate>Sun, 26 Dec 2021 12:32:06 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F49fa040d-0a5e-4e2d-814b-722e10197312_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Interviewing at a tech company will often require an assessment focused on evaluating the technical skills of a candidate. The exact interview format often varies from simple, abstract problems to full-blown applications. I&#8217;ll try to enumerate some of the different interview types and discuss their strengths and weaknesses, both from interviewer&#8217;s and candidate&#8217;s perspective.</p><h2>Coding Challenge</h2><p>In a coding challenge, the candidate will be given a relatively simple problem, that needs to be translated to working code to be solved. Someone may now ask, <em>isn&#8217;t that called an algorithmic challenge?</em> As you&#8217;ll see next, I reserve this term for challenges where designing and understanding the algorithm itself is a substantial part of the interview.</p><p>Some problems that fall into this category:</p><ul><li><p><a href="https://rosettacode.org/wiki/FizzBuzz">FizzBuzz</a></p></li><li><p>Count the occurrences of each string in an array of strings.</p></li><li><p>Find the common elements between two arrays of integers.</p></li></ul><p>These problems sound simple but they can provide significant insights into someone&#8217;s capacity to effectively communicate their thoughts and display their methodology to problem-solving in general. In addition, there is often an expectation to write unit tests to verify the solution, along with identifying and covering edge cases in the code. </p><p>Although not usually crafted for performance-related discussions, there&#8217;s still room for such questions in the everyday engineering context. Are we applying micro-optimizations versus favoring readability and maintainability for non-performance-critical code? Are we using a sub-optimal custom implementation that could be replaced by a standard library function?</p><p>Another interesting aspect is testing the knowledge depth and experience of a programming language. Are they knowledgeable about the standard library and language constructs? Do they write non-idiomatic or even error-prone expressions? Are they familiar with the error handling and unit testing fundamentals? Note that language selection is often open to a large set of popular languages, but certain companies will narrow the choices down to a smaller subset or even a single language, if they consider these fundamental to the organization and a prerequisite for any position.</p><p>You may wonder what happens when the interviewer doesn&#8217;t have experience with the language chosen by the candidate. Although a not-so-ideal scenario, an interviewer can still assess the ability of the candidate to explain technical matters to someone experienced in software engineering in general, but having a specific knowledge gap. Being able to narrow down the scope of shared information in this case is also a sign of experience. If you have mentored or collaborated with other engineers closely, you likely had the chance to explain your approach on multiple occasions.</p><div><hr></div><p>&#128993; <strong>Scalability/Performance</strong></p><p>&#128993; <strong>Testing</strong></p><p>&#128993; <strong>Problem-Solving</strong></p><p>&#128994; <strong>Language Proficiency/Ecosystem</strong></p><p>&#128994; <strong>Practicality</strong></p><p>&#128308;  <strong>Systems Thinking</strong></p><h2>Algorithmic Challenge</h2><p>In this case, the candidate is requested to provide an algorithm for solving a difficult problem, such as Tree traversals or other operations, Graph searches, sorting. The solution usually requires a deep understanding of data structures, graph theory, set theory and mathematics. Apart from the inherent difficulty, these problems most likely have performance-related components, which must be discussed during the interview in the form of analysis on space and time complexity. </p><p>Although pseudo-code may be applicable, or even requested as an initial step, most interviews will also require writing working code as well, and even reach the stage of delivering unit tests along with the solution. You may now wonder if that&#8217;s a more difficult <em>Coding Challenge</em>. There is indeed an overlap, but due to time restrictions, the interviewers will likely not have enough time to dive deeper into all the focus areas that were mentioned in the previous section.</p><p>A significant drawback of algorithmic challenges is that they may require prior knowledge or exposure to a specific Computer Science problem (e.g. detecting loops in linked lists). Although working with the interviewer to see how you approach problem-solving still plays an important role, there is a chance that some candidates will not go very far in the discussion unless they have a <em>breakthrough moment</em>.</p><p>Interviewers may also face a problem with becoming biased when knowing the solution beforehand. Inevitably the solution seems obvious over time. This effect can be mitigated, by alternating interview questions after a fixed period of time, e.g. every quarter.</p><p>There is a major debate on the value of difficult algorithmic problems within an interview scope. They are frequently regarded as not being in touch with everyday engineering practices and possibly dismissing valuable experience of other important aspects of software engineering. A counter-argument may be that they reveal the candidate&#8217;s exposure to highly-scalable, performance-critical applications where space and time complexity matters to the extent of rendering a solution non-functional. In addition, a strong CS background is actually required in some positions. For example, if you are interviewing for a position in a team developing a NoSQL database system, you&#8217;ll have to display some understanding of how <a href="https://en.wikipedia.org/wiki/Tree_(data_structure)">Trees</a> work.</p><div><hr></div><p>&#128994; <strong>Scalability/Performance</strong></p><p>&#128993; <strong>Testing</strong></p><p>&#128994; <strong>Problem-Solving</strong></p><p>&#128993; <strong>Language Proficiency/Ecosystem</strong></p><p>&#128993; <strong>Practicality</strong></p><p>&#128308;  <strong>Systems Thinking</strong></p><h2>Project Assignment</h2><p>While the two previous types are almost exclusively performed synchronously in collaboration with the interviewers, a project is usually given in the form of an assignment. It is often criticised as requiring a significant time investment on behalf of the candidate, though this varies on the scope of the project: some assignments can be fully completed in 1 or 2 hours, others will imply an expectation of spending 14-20 hours within a calendar week for a high-quality deliverable.</p><p>The goal is to simulate a real-world feature and evaluate the candidate&#8217;s experience on several important aspects of software engineering, such as language ecosystem knowledge, framework experience (e.g. React, Rails), Continuous Integration and testing, documentation. The usual requirement is to create (or modify) a service with an HTTP interface or write a CLI tool.</p><p>Usually, the deliverable is the complete application code either as a private repository or as a compressed archive. Candidates are expected to write clear and concise documentation on how their app is deployed or used in the command-line. For Git repositories, interviewers may also want to take notice of version control specifics, such as commit messages, sequence and content.</p><p>The project specifications may also require that a specific third-party API is utilized. Interactions with several services are commonplace in today&#8217;s architectures that depend heavily on Infrastructure-as-a-Service providers for core operations (e.g. object storage with AWS S3/Google Cloud Storage) and integrate with other service vendors for their actual business logic, for example, transactional email or payment gateways.</p><p>Upon successful completion of the assignment, there is usually another technical interview round where the candidate presents the solution to the interviewers with some follow-up questions. The candidate may also be asked to implement additional functionality during the interview, which tests both their understanding of the delivered solution and their ability to adapt to new requirements along with their communication and collaboration skills.</p><p>An interesting variant of the technical assignment is to be granted access to a draft of the project solution and apply enhancements or new features there. The <a href="https://en.wikipedia.org/wiki/Code_review">Code Review</a> workflow may also be followed: the candidate notes some comments in a change request and is able to communicate with the interviewers asynchronously in writing. During the interview each comment is discussed and any agreed suggestions are then implemented by the candidate. An example of this variant is <a href="https://about.gitlab.com/handbook/hiring/interviewing/technical/">GitLab&#8217;s technical assignment</a>.</p><div><hr></div><p>&#128993; <strong>Scalability/Performance</strong></p><p>&#128994; <strong>Testing</strong></p><p>&#128994; <strong>Problem-Solving</strong></p><p>&#128994; <strong>Language Proficiency/Ecosystem</strong></p><p>&#128994; <strong>Practicality</strong></p><p>&#128993;  <strong>Systems Thinking</strong></p><h2>Conclusion</h2><p>The approaches mentioned here display several differences, but what they do have in common is that communication always plays a key part. As a candidate, you&#8217;ll need to explain your ideas, ask for clarifications and work together with the interviewer to reach the optimal solution. As an interviewer, you should also focus on evaluating how a candidate deals with unknowns, adapts to new information, communicates and approaches problem-solving in general.</p>]]></content:encoded></item></channel></rss>