SurveyJSON size reduction/optimization

SurveyJSON was storing a lot of redundant information (every setting on
every single section/question/answer, which, in most cases, will simply
take on the default values). This was bloating the surveyJSON property in
the db, and equally as importantly, slowing down Survey because it had to
do a lot of JSON parsing on the serialised surveyJSON object.

We now factor out and store the current section/question/answer defaults
along with the surveyJSON data itself, which means that we only needs to
store properties that differ from the defaults. This results is a massive
reduction in the size of the serialized surveyJSON stored in the database,
as well as a speed-up in json parsing time.

The compression/uncompression happens transparently to the rest of Survey.
This commit is contained in:
Patrick Donelan 2009-06-19 08:07:18 +00:00
parent d26ce5b447
commit cbc308c55a
4 changed files with 192 additions and 21 deletions

View file

@ -21,7 +21,7 @@ my $session = WebGUI::Test->session;
#----------------------------------------------------------------------------
# Tests
my $tests = 137;
my $tests = 140;
plan tests => $tests + 1 + 3;
#----------------------------------------------------------------------------
@ -158,6 +158,46 @@ cmp_deeply(
'newAnswer data structure is okay'
);
####################################################
#
# freeze, compress, uncompress
#
####################################################
{
my $sJSON = WebGUI::Asset::Wobject::Survey::SurveyJSON->new($session);
my $mold = {
answer => $sJSON->newAnswer,
question => $sJSON->newQuestion,
section => $sJSON->newSection,
};
cmp_deeply(from_json($sJSON->freeze), {
sections => [ {} ],
mold => $mold,
}, 'got back appropriate frozen object for empty survey');
# Set a few non-standard properties on the (default) 0th Section
my $nonStandardSProps = { variable => 'S0', logical => '0 but true' };
$sJSON->update( [0], $nonStandardSProps );
# Create a question, and set some other non-standard properties
$sJSON->newObject( [0] );
my $nonStandardQProps = { randomizeAnswers => 1, textInButton => '1', text => 'blah' };
$sJSON->update( [0, 0], $nonStandardQProps );
# And create an answer
$sJSON->updateQuestionAnswers( [0], 'Country' );
$nonStandardQProps->{questionType} = 'Country';
my $nonStandardAProps = { value => 0, terminal => '' };
$sJSON->update( [0, 0, 0], $nonStandardAProps );
$nonStandardSProps->{questions} = [$nonStandardQProps];
$nonStandardQProps->{answers} = [$nonStandardAProps];
cmp_deeply(from_json($sJSON->freeze)->{sections}, $sJSON->compress, 'freeze returns sections via compress');
cmp_deeply($sJSON->compress, [$nonStandardSProps], 'molded data only contains non-standard properties');
cmp_deeply($sJSON->uncompress($sJSON->compress), $sJSON->{_sections}, 'uncompress completes the round-trip');
}
####################################################
#
# new, part 2
@ -199,23 +239,16 @@ $sJSON2 = WebGUI::Asset::Wobject::Survey::SurveyJSON->new($session,
cmp_deeply(
$sJSON2->sections,
[
{
superhashof {
type => 'section',
logical => 0, # this is added from the default-created mold
},
],
'new: If the JSON has a section, a new one will not be added',
'new: If the JSON has a section, a new one will not be added (but mold defaults will be)',
);
undef $sJSON2;
####################################################
#
# freeze
#
####################################################
like( $surveyJSON->freeze, qr/"survey":\{\}/, 'freeze: got back something that looks like JSON, not a thorough check');
####################################################
#
# newObject