Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proof of Concept: Automatically store strings as raw values #938

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions lib/dalli/protocol/value_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ class ValueSerializer
# Looks like most clients use bit 0 to indicate native language serialization
FLAG_SERIALIZED = 0x1

ENCODING_FLAGS = {
Encoding::UTF_8 => 0x4,
Encoding::US_ASCII => 0x8,
Encoding::BINARY => 0x0,
}.freeze
ENCODING_INDEX = {
0x4 => Encoding::UTF_8,
0x8 => Encoding::US_ASCII,
}.freeze
ENCODING_MASK = ENCODING_FLAGS.values.inject(:|)

attr_accessor :serialization_options

def initialize(protocol_options)
Expand All @@ -27,8 +38,15 @@ def initialize(protocol_options)
end

def store(value, req_options, bitflags)
do_serialize = !(req_options && req_options[:raw])
if do_serialize = !(req_options && req_options[:raw])
# We compare value.class to make sure not to match String subclasses
if String == value.class && encoding_flag = ENCODING_FLAGS[value.encoding]
do_serialize = false
end
end

store_value = do_serialize ? serialize_value(value) : value.to_s
bitflags |= encoding_flag if encoding_flag
bitflags |= FLAG_SERIALIZED if do_serialize
[store_value, bitflags]
end
Expand All @@ -44,7 +62,11 @@ def store(value, req_options, bitflags)

def retrieve(value, bitflags)
serialized = (bitflags & FLAG_SERIALIZED) != 0
serialized ? serializer.load(value) : value
payload = serialized ? serializer.load(value) : value
if encoding = ENCODING_INDEX[bitflags & ENCODING_MASK]
payload.force_encoding(encoding)
end
payload
rescue TypeError => e
filter_type_error(e)
rescue ArgumentError => e
Expand Down