Skip to content

Instantly share code, notes, and snippets.

@sillypog
sillypog / retain_best_cache.cpp
Last active August 2, 2022 20:28
A cache where lowest ranked items are evicted first.
/**
* Speed up retrieval of rankable objects with a cache.
*
* We have a primary data store which implements the DataSource interface.
* Any class implementing this interface is likely to be slow as it has to
* fetch the data from disk or across the network. Therefore, it will be
* useful to temporarily store some of that data in a faster, in memory
* cache. This cache is not big enough to store all of the data from the
* primary store though.
*
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>BleacherReport articles</title>
<link href="http://bleacherreport.com/"/>
<link rel="self" href="http://feed.bleacherreport.com/articles"/>
<updated>2018-07-24T18:30:02Z</updated>
<id>urn:uuid:6ccdb64c-9ee8-47c5-bae4-9e2fb9fae183</id>
<category term="Sport"/>
@sillypog
sillypog / trie.ex
Created May 30, 2018 05:12
Checking for multiple children in a trie node
def check_char(["3" | t], current_node) do
if check_char(["b" | t], current_node) do
check_char(["e" | t], current_node)
else
false
end
end
@sillypog
sillypog / trie.ex
Created May 30, 2018 05:10
Searching a trie of characters for a string
def valid_word?("", _), do: true
def valid_word?(word, tree) do
chars = String.codepoints(word)
case check_char(chars, tree) do
false ->
false
_ ->
[_ | t] = chars
valid_word?(Enum.join(t), tree)
end
@sillypog
sillypog / trie.ex
Created May 30, 2018 05:09
Building a trie of characters from a list of words
def build_tree(word_list) do
Enum.reduce(word_list, %{}, fn(word, tree) ->
word
|> String.codepoints
|> place_chars(tree)
end)
end
def place_chars([], current_node), do: current_node
def place_chars([h | t], current_node) do
@sillypog
sillypog / profanity.exs
Created May 30, 2018 05:03
Tree representation of profanity list
%{
"a" => %{"r" => %{"s" => %{"e" => %{"n" => %{"i" => %{"c" => :leaf}}}}}},
"b" => %{
"l" => %{"o" => %{"o" => %{"m" => %{"e" => %{"r" => %{"s" => :leaf}}}}}},
"o" => %{
"s" => %{"o" => %{"m" => :leaf}},
"u" => %{"n" => %{"d" => %{"e" => %{"r" => :leaf}}}}
}
},
"f" => %{"u" => %{"s" => %{"t" => %{"i" => %{"l" => %{"u" => %{"g" => %{"s" => :leaf}}}}}}}},
@sillypog
sillypog / gist:630877eb663efcf47f063217b19cd3d3
Created December 1, 2016 02:08
Fragment SQL injection warning
iex(3)> where_string = "device_id = AAA OR login_id = 123"
"device_id = AAA OR login_id = 123"
iex(4)> query = from u in Portmeirion.User, limit: 1, select: %{warehouse_id: u.warehouse_id}, where: fragment(^where_string)
** (ArgumentError) to prevent sql injection, only a keyword list may be interpolated as the first argument to `fragment/1` with the `^` operator, got `"device_id = AAA OR login_id = 123"`
(ecto) lib/ecto/query/builder.ex:512: Ecto.Query.Builder.keyword!/1
@sillypog
sillypog / mix.exs
Created December 1, 2016 01:30
Portmeirion mix.exs
defp deps do
[{:phoenix, "~> 1.2"},
{:phoenix_ecto, "~> 3.0"},
...
{:ecto, "~> 2.1.0-rc.3", override: true},
]
end
@sillypog
sillypog / gist:a153755dd14566c0011d01aa9e49f6bf
Last active December 2, 2016 20:40
Portmeirion.IdentifyController SQL
SELECT warehouse_id
FROM users as u
FULL JOIN devices AS d ON d.user_id = u.id
WHERE login_id = ? OR device_id = ? OR prism_id = ?
ORDER BY u.login_id, d.device_id, u.prism_id
LIMIT 1;
@sillypog
sillypog / identify_controller.ex
Last active November 30, 2016 00:57
Portmeirion.IdentifyController V5
defp where_clause(query, params) do
allowed_params = ~w(login_id facebook_id device_id prism_id)
key_values = params
|> Enum.filter(fn({key, _}) -> Enum.member?(allowed_params, key) end)
|> Enum.map(fn({key, value}) -> {String.to_existing_atom(key), cast_param(key, value)} end) # or_where expects list of tuples
|> Enum.sort # Ensure device_id is always first if present
where_fragment(query, key_values)
end