summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Arthur <paul.arthur@flowerysong.com>2013-06-11 12:37:58 -0400
committerPaul Arthur <paul.arthur@flowerysong.com>2013-06-12 13:46:39 -0400
commit05009329cf9e5ad8601b01844716d6d5ed244daa (patch)
treefcd3a0eeaf8ff22bef07e456be60ec67f52101da /lib
parenta957ab19cdf3e86fe78a4bf82f287d8c622cf67e (diff)
downloadampache-api.tar.gz
ampache-api.tar.bz2
ampache-api.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')
-rw-r--r--lib/class/query.class.php57
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;
}
/**