diff options
author | Paul Arthur <paul.arthur@flowerysong.com> | 2013-06-11 12:37:58 -0400 |
---|---|---|
committer | Paul Arthur <paul.arthur@flowerysong.com> | 2013-06-12 13:46:39 -0400 |
commit | 05009329cf9e5ad8601b01844716d6d5ed244daa (patch) | |
tree | fcd3a0eeaf8ff22bef07e456be60ec67f52101da /lib/class | |
parent | a957ab19cdf3e86fe78a4bf82f287d8c622cf67e (diff) | |
download | ampache-05009329cf9e5ad8601b01844716d6d5ed244daa.tar.gz ampache-05009329cf9e5ad8601b01844716d6d5ed244daa.tar.bz2 ampache-05009329cf9e5ad8601b01844716d6d5ed244daa.zip |
Add naive compaction for Query serializationapi
Can be very efficient with the right input, but probably has
degenerative cases where it increases the size. Worst-case size
increase is one character per ID in the result set, so it shouldn't be
an issue.
String lengths for a large search result that was unstorable before:
serialize: 1991874
json_encode: 756249
cooked: 244
And some with more discontinuity:
serialize: 1772238
json_encode: 674751
cooked: 37950
serialize: 164942
json_encode: 65771
cooked: 25369
Diffstat (limited to 'lib/class')
-rw-r--r-- | lib/class/query.class.php | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/lib/class/query.class.php b/lib/class/query.class.php index d586d726..857adf61 100644 --- a/lib/class/query.class.php +++ b/lib/class/query.class.php @@ -225,12 +225,65 @@ class Query { $db_results = Dba::write($sql); } + /** + * _serialize + * + * Attempts to produce a more compact representation for large result + * sets by collapsing ranges. + */ private static function _serialize($data) { - return serialize($data); + if (count($data) > 1000) { + sort($data); + $last = -17; + $in_range = false; + $idx = -1; + $cooked = array(); + foreach ($data as $id) { + if ($id == ($last + 1)) { + if ($in_range) { + $cooked[$idx][1] = $id; + } + else { + $in_range = true; + $cooked[$idx] = array($last, $id); + } + } + else { + $in_range = false; + $idx++; + $cooked[$idx] = $id; + } + $last = $id; + } + $data = json_encode($cooked); + debug_event('Query', 'cooked serialize length: ' . strlen($data), 5); + } + else { + $data = json_encode($data); + } + + return $data; } + /* + * _unserialize + * + * Reverses serialization. + */ private static function _unserialize($data) { - return unserialize($data); + $raw = array(); + $cooked = json_decode($data); + foreach ($cooked as $grain) { + if (is_array($grain)) { + foreach(range($grain[0], $grain[1]) as $id) { + $raw[] = $id; + } + } + else { + $raw[] = $grain; + } + } + return $raw; } /** |