/src/couchdb/couch_compress.erl

https://github.com/grapestack/couchdb · Erlang · 73 lines · 46 code · 13 blank · 14 comment · 0 complexity · 215eda12d32c1a11db1fc6c31bea6f3d MD5 · raw file

  1. % Licensed under the Apache License, Version 2.0 (the "License"); you may not
  2. % use this file except in compliance with the License. You may obtain a copy of
  3. % the License at
  4. %
  5. % http://www.apache.org/licenses/LICENSE-2.0
  6. %
  7. % Unless required by applicable law or agreed to in writing, software
  8. % distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  9. % WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  10. % License for the specific language governing permissions and limitations under
  11. % the License.
  12. -module(couch_compress).
  13. -export([compress/2, decompress/1, is_compressed/1]).
  14. -export([get_compression_method/0]).
  15. -include("couch_db.hrl").
  16. % binaries compressed with snappy have their first byte set to this value
  17. -define(SNAPPY_PREFIX, 1).
  18. % binaries that are a result of an erlang:term_to_binary/1,2 call have this
  19. % value as their first byte
  20. -define(TERM_PREFIX, 131).
  21. get_compression_method() ->
  22. case couch_config:get("couchdb", "file_compression") of
  23. undefined ->
  24. ?DEFAULT_COMPRESSION;
  25. Method1 ->
  26. case string:tokens(Method1, "_") of
  27. [Method] ->
  28. list_to_existing_atom(Method);
  29. [Method, Level] ->
  30. {list_to_existing_atom(Method), list_to_integer(Level)}
  31. end
  32. end.
  33. compress(Term, none) ->
  34. ?term_to_bin(Term);
  35. compress(Term, {deflate, Level}) ->
  36. term_to_binary(Term, [{minor_version, 1}, {compressed, Level}]);
  37. compress(Term, snappy) ->
  38. Bin = ?term_to_bin(Term),
  39. try
  40. {ok, CompressedBin} = snappy:compress(Bin),
  41. case byte_size(CompressedBin) < byte_size(Bin) of
  42. true ->
  43. <<?SNAPPY_PREFIX, CompressedBin/binary>>;
  44. false ->
  45. Bin
  46. end
  47. catch exit:snappy_nif_not_loaded ->
  48. Bin
  49. end.
  50. decompress(<<?SNAPPY_PREFIX, Rest/binary>>) ->
  51. {ok, TermBin} = snappy:decompress(Rest),
  52. binary_to_term(TermBin);
  53. decompress(<<?TERM_PREFIX, _/binary>> = Bin) ->
  54. binary_to_term(Bin).
  55. is_compressed(<<?SNAPPY_PREFIX, _/binary>>) ->
  56. true;
  57. is_compressed(<<?TERM_PREFIX, _/binary>>) ->
  58. true;
  59. is_compressed(Term) when not is_binary(Term) ->
  60. false.