The current shared_ptr implementation is efficient, but does not support
polymorphic types.
Rename it in order to make room for a polymorphic shared_ptr.
size of the sstring _ascii_prefix should also be added when computing
item footprint. Without this change, reclaimer would end up evicting
more than needed.
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
We don't really need to copy keys as the parser is not reused until
we're done.
Also, in case of a single key we don't use map_reduce() which
saves us one allocation (reducer).
Improves memaslap UDP posix throughput on my laptop by 40% (from 73k to 105k).
When item is created we cache flags and size part of the response so
that there's no need to call expensive string formatting in get(). The
down side is that this pollutes "item" object with protocol-specific
field, but since ASCII is the only protocol which is supported now and
it's not like we can't fix it later, I think it's fine.
There is a separate DB per core, each serving a subset of the key
space. From the outside in appears to behave as one DB.
item_key type was changed to include the hash so that we calculate the
hash only once. The same hash is used for sharding and hashing. No
need for store_hash<> option on unordered_set<> any more.
Some seastar-specific and hashtable-specific stats were moved from the
general "stats" command into "stats hash", which shows per-core
statistics.
Fix UDP for memcache with native stack
memcached: apps/memcached/memcached.cc:807:
void memcache::assert_resolved(future<>): Assertion `f.available()'
failed.
Tomek writes:
UDP path relied on the fact that handle() could not block, because
the output stream does not block, and passed references to variables
which live on stack. Since you now can block in handle_get(), this
no longer holds. We should chnage that, ie allocate conversation
state like we do in TCP.
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Some packets, like arp replies, are broadcast to all cpus for handling,
but only packet structure is copied for each cpu, the actual packet data
is the same for all of them. Currently networking stack mangles a
packet data during its travel up the stack while doing ntoh()
translations which cannot obviously work for broadcaster packets. This
patches fixes the code to not modify packet data while doing ntoh(), but
do it in a stack allocated copy of a data instead.
The current implementation uses a sort of "manual reference counting"; any
place which may be the last one using the connection checks if it is indeed
the last one, and if so, deletes the connection object.
With recent changes this has become unwields, as there are too many cases
to track.
To fix, we separate the connection into two streams: a read() stream that
is internally serialized (only one request is parsed at a time) and that
returns when there are no more requests to parse, and a respond() stream
that is also internally serialized, and termiantes when the last response
has been written. The caller then waits on the two streams with when_all().
Expired timer cancellation is broken since timer_set assumes that a
timer that is being canceled is not expired yet. This patch fixes the
problem by moving expired timers management outside timer_set and
letting the code that uses it to managed cancellation of expired timers.
In memcached it can never happen, in core each queued timer gets expired
flag that tells if timer is queued in a timer set or in expired timer
list.
std::unordred_map does it by default for std::string. We switched to
boost::intrusive::unordered_set<>, which does not do it by default for
any key. I see ~4% improvement in throughput with this.
When client closes the connection in one direction, make httpd close the
other direction too. This way, httpd will send back a <FIN> packet to
client after receiving client's <FIN> packet.
It implements a very simple reclaimer. When triggered tries to free
around 5 MB of data. This assumes that this amount is more than anyone
would want to allocate between low-memory event is detected and the
reclaimer task runs. This amount was chosen arbitrarily and I am not
sure if this amount is right.
The protocol is called the "memcache protocol" but the server should
follow the same naming convention as httpd does.
It should not be a big deal but it annoys the hell out of simple people
like myself who have their brain hard-wired to type the final "d"...
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
Transmission of data is not atomic so we cannot replace item's fields
in-place. This can lead to inconsistencies in "get" responses. We
should rather allocate a new item object replacing the one which is in
the cache.