Logback and space in the XML configuration

Please see this issue that I created for LogBack and was accepted to be taken care of in v1.3.0:

https://jira.qos.ch/browse/LOGBACK-1288GK

The fix should allow for a stack trace or some warning message if the level value is incorrect as it was when I had inadvertently used a space character as a suffix as in “WARN “ instead of “WARN” and it led to the library defaulting to “DEBUG”.

 

 

InetAddress, InetSocketAddress and multiple IP addresses assignment to a single host

InetAddress: This address maps to a single IP address for a host name even though the host name might resolve to multiple IP addresses.

One way of creating an InetAddress:

Here the “host” argument can be either a string representation of the IP Address (as in “x.x.x.x.” for IPv4) or a host name. If it is an IP Address then an InetAddress instance is returned with that IP. In such cases, the InetAddress instance would be bound to the IP specified in the host. If that host has multiple IP addresses then this InetAddress instance would remain bound to the IP address passed in. That returned instance could be an instance of the two subclasses of InetAddress for IPv4 and IPv6.

=> This constructor, if passed an IP address would invoke the InetAddress.getByName(String host) with the IP address and there would not be any reverse lookups.

Java 8 Streams: difference between map and flatMap

Difference between map() and flatMap():
The map() operates on the individual elements of the stream and returns a value as a Stream with the results. The flatMap() operates on the individual elements of the stream and returns a value as a Stream with the results. In this they are similar.
However the map() takes in a function that returns any R (could be a Stream as well) whereas the flatMap() operation takes in a function that returns a Stream.

CRTP

Streams employ the CRTP (Curiously Recurring Template Pattern).

For instance:

 

Regular Expressions and the void in a string (zero-length matches)

While attempting to do a substitution of word characters   “[a-zA-Z0-9_]” in a string, I noticed using a “\w*” pattern lead to 2 matches:

  1. One for the string
  2. Another for the void at the end of the string

For instance: see: https://regex101.com/r/ptz8Cm/1

The explanation is at: http://www.regular-expressions.info/zerolength.html

In short, we should use “\w+” instead of “\w*” so that zero-length matches are avoided.

Note: if you make the quantifier lazy as in https://regex101.com/r/ptz8Cm/2 then you have 3 matches.

 

 

 

 

CDN and “Cache-Control: max-age”

If we ever use “max-age” for content that is partially dynamic in the sense that it may or may not change in “X” minutes and we use a CDN to cache that and we also have a “max-age” header then we need to remember to do this:

  1. Ensure that the max-age is counted down by the CDN each and every time it is accessed
  2. Or, if it is not counted down then ensure that the HTTP “Date:” header also should not change as well

The reasoning is that the clients (browsers etc.) would use these two values to decide on refreshing the cache.

Consider an OCSP response which is served through a CDN. We also know that the OCSP response has a “nextUpdate” temporal value and the RFC 5019 clearly states that the “max-age” should be less (or equal to since it seems that the clients allow for equality as a positive case as well) than the “nextUpdate“.

The issue is when the “max-age” is not counted down by the CDN and the value in the “Date:” header is – we get an issue where the OCSP response might be stale but it is not timed out of the cache either for validation or a fetch.

Levenshtein Part 2: Dynamic Programming

Proceeding from the earlier post on the same topic, we have the following code for a Dynamic Programming bottom-up approach to the Levenshtein “Edit Distance” algorithm where all the weights are simply “1” for insert, delete, substitute operations. Note that this would be also referred to the “tabular” approach as well since we fill up a matrix as we go along.

In a later post, we would attempt to reduce the space requirement from O(m.n) to a constant. In another post, we would provide a way to configure the weights and thereby providing weighted edges to the DAG.

 

And the test code:

Levenshtein: elementary recursion – a gateway to DP

This is my first post on Levenshtein Algorithm: a way to calculate the edit distance between two strings. A way to calculate the cost to transmute a string1 to a string2.

The comments in the codebase are useful for comprehension on their own. I start with the recursing and building a matrix where the answer (the cost to transmute or convert str1 into str2) lies at index [m][n] for the first implementation. For the second case, the cost would be at index [0][0].

This is the gateway to elucidating DP through the implementation of this algorithm. We would implement in ways that classify as DP (both memoization and tabulation) as well as plain and simple recursion or iteration with no DP components. We start with vanilla recursion in the following codebase. Please review the comments in the codebase to understand why this is not DP. A future post would elucidate DP.

 

A snippet of the test code: