{"id":15362296,"url":"https://github.com/gyson/sortable","last_synced_at":"2025-07-15T11:05:57.488Z","repository":{"id":57550587,"uuid":"160346231","full_name":"gyson/sortable","owner":"gyson","description":" Sortable is a library to provide serialization with order reserved.","archived":false,"fork":false,"pushed_at":"2019-07-13T19:28:51.000Z","size":18,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-19T14:18:38.748Z","etag":null,"topics":["serialization","sortable"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gyson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-04T11:21:49.000Z","updated_at":"2023-04-11T02:15:34.000Z","dependencies_parsed_at":"2022-09-01T11:10:35.317Z","dependency_job_id":null,"html_url":"https://github.com/gyson/sortable","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gyson/sortable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyson%2Fsortable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyson%2Fsortable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyson%2Fsortable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyson%2Fsortable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gyson","download_url":"https://codeload.github.com/gyson/sortable/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyson%2Fsortable/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265430397,"owners_count":23763998,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["serialization","sortable"],"created_at":"2024-10-01T12:59:59.814Z","updated_at":"2025-07-15T11:05:57.465Z","avatar_url":"https://github.com/gyson.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sortable\n\nSortable is a library to provide serialization with order reserved.\n\nInspired by FoundationDB's [tuple layer][1] and [sext library][2].\n\n## Goal\n\nDesign a simple, fast and space-efficiency serialization solution with order reserved for key-value storage use case.\n\n- Simple / Limited Scope: only support list of binaries, floats and integers (scalar types).\n- Fast: it's 5~10 times faster than alternative [sext library][2] measured by simple benchmarks.\n- Space-efficiency: binary format is designed to be space-efficiency.\n    ```elixir\n    iex(1)\u003e Sortable.encode [\"hello\", 2019, 4, 1]\n    \u003c\u003c31, 104, 101, 108, 108, 111, 0, 205, 7, 227, 80, 77\u003e\u003e\n\n    iex(2)\u003e :sext.encode [\"hello\", 2019, 4, 1]\n    \u003c\u003c17, 18, 180, 89, 109, 150, 203, 120, 8, 10, 0, 0, 15, 198, 10, 0, 0, 0, 8, 10, 0, 0, 0, 2, 2\u003e\u003e\n    ```\n\n## Example\n\n```elixir\n{:ok, db} = :rocksdb.open('#{__DIR__}/rocks.test', create_if_missing: true)\n\n:rocksdb.put(db, Sortable.encode([\"folder\", 2018, 1, 1, \"key-1\"]), \"value-1\", [])\n:rocksdb.put(db, Sortable.encode([\"folder\", 2018, 1, 2, \"key-2\"]), \"value-2\", [])\n:rocksdb.put(db, Sortable.encode([\"folder\", 2019, 3, 1, \"key-3\"]), \"value-3\", [])\n\n# retrieve everyhing in 2018\n\n{:ok, iterator} =\n  :rocksdb.iterator(db,\n    iterate_lower_bound: Sortable.encode([\"folder\", 2018]),\n    iterate_upper_bound: Sortable.encode([\"folder\", 2019])\n  )\n\n{:ok, _, \"value-1\"} = :rocksdb.iterator_move(iterator, :first)\n{:ok, _, \"value-2\"} = :rocksdb.iterator_move(iterator, :next)\n{:error, :invalid_iterator} = :rocksdb.iterator_move(iterator, :next)\n\n:rocksdb.iterator_close(iterator)\n```\n\n## Ordering\n\nIt does not follow erlang term order because it seperates order of integers and floats to eliminate cast trouble from [sext][2].\n\nGenerally, order is `binary` \u003c `float` \u003c `integer` (order by name).\n\nFor example,\n\n```elixir\nSortable.encode([\"hi\"]) \u003c Sortable.encode([0.0]) \u003c Sortable.encode([0])\n```\n\n## Installation\n\nThe package can be installed by adding `sortable` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:sortable, \"~\u003e 0.1.0\"}\n  ]\nend\n```\n\nDocumentation can be found at [https://hexdocs.pm/sortable](https://hexdocs.pm/sortable).\n\n## Optimization\n\nRun `ERL_COMPILER_OPTIONS=bin_opt_info mix compile` to ensure binary parsing is optimized.\n\n## Benchmarks\n\nSimple benchmarks for comparison with alternative [sext library][2]:\n\n```\nOperating System: macOS\"\nCPU Information: Intel(R) Core(TM) i7-3720QM CPU @ 2.60GHz\nNumber of Available Cores: 8\nAvailable memory: 16 GB\nElixir 1.8.1\nErlang 21.2.4\n\nBenchmark suite executing with the following configuration:\nwarmup: 2 s\ntime: 5 s\nmemory time: 2 s\nparallel: 1\ninputs: none specified\nEstimated total run time: 36 s\n\n\nBenchmarking :sext.decode...\nBenchmarking :sext.encode...\nBenchmarking Sortable.decode...\nBenchmarking Sortable.encode...\n\nName                      ips        average  deviation         median         99th %\nSortable.decode        510.02        1.96 ms    ±14.32%        1.84 ms        2.94 ms\nSortable.encode        479.97        2.08 ms    ±15.96%        1.94 ms        3.09 ms\n:sext.encode            95.23       10.50 ms    ±10.36%       10.07 ms       13.90 ms\n:sext.decode            54.13       18.47 ms     ±8.85%       17.59 ms       22.78 ms\n\nComparison:\nSortable.decode        510.02\nSortable.encode        479.97 - 1.06x slower\n:sext.encode            95.23 - 5.36x slower\n:sext.decode            54.13 - 9.42x slower\n\nMemory usage statistics:\n\nName               Memory usage\nSortable.decode         1.27 MB\nSortable.encode         0.97 MB - 0.76x memory usage\n:sext.encode            3.18 MB - 2.50x memory usage\n:sext.decode            9.72 MB - 7.65x memory usage\n\n**All measurements for memory usage were the same**\n```\n\n## License\n\nMIT\n\n[1]: https://github.com/apple/foundationdb/blob/master/design/tuple.md\n[2]: https://github.com/uwiger/sext\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyson%2Fsortable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgyson%2Fsortable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyson%2Fsortable/lists"}