Skip to content

Commit

Permalink
0.25.2
Browse files Browse the repository at this point in the history
  • Loading branch information
traversc committed Nov 6, 2021
1 parent f51dbf0 commit f67de52
Show file tree
Hide file tree
Showing 51 changed files with 297 additions and 289 deletions.
1 change: 0 additions & 1 deletion .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
rebuild.sh
.*\.tar\.gz
^local
^tests
^benchmark_results
rticle
.Rhistory
Expand Down
87 changes: 25 additions & 62 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
# NOTE: This workflow is overkill for most R packages
# check-standard.yaml is likely a better choice
# usethis::use_github_action("check-standard") will install it.
# Workflow derived from https://github.com/r-lib/actions/tree/master/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
#
# For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag.
# https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions
# NOTE: This workflow is overkill for most R packages and
# check-standard.yaml is likely a better choice.
# usethis::use_github_action("check-standard") will install it.
on:
push:
branches:
- main
- master
branches: [main, master]
pull_request:
branches:
- main
- master
branches: [main, master]

name: R-CMD-check

Expand All @@ -27,75 +23,42 @@ jobs:
matrix:
config:
- {os: macOS-latest, r: 'release'}

- {os: windows-latest, r: 'release'}
- {os: windows-latest, r: '3.6'}
- {os: ubuntu-16.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest", http-user-agent: "R/4.0.0 (ubuntu-16.04) R (4.0.0 x86_64-pc-linux-gnu x86_64 linux-gnu) on GitHub Actions" }
- {os: ubuntu-16.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
- {os: ubuntu-16.04, r: 'oldrel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
- {os: ubuntu-16.04, r: '3.5', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
- {os: ubuntu-16.04, r: '3.4', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
- {os: ubuntu-16.04, r: '3.3', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
# Use 3.6 to trigger usage of RTools35
# - {os: windows-latest, r: '3.6'}

# Use older ubuntu to maximise backward compatibility
- {os: ubuntu-18.04, r: 'devel', http-user-agent: 'release'}
- {os: ubuntu-18.04, r: 'release'}
- {os: ubuntu-18.04, r: 'oldrel-1'}
- {os: ubuntu-18.04, r: 'oldrel-2'}
- {os: ubuntu-18.04, r: 'oldrel-3'}
# - {os: ubuntu-18.04, r: 'oldrel-4'}

env:
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
_R_CHECK_FORCE_SUGGESTS_: false
RSPM: ${{ matrix.config.rspm }}
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes

steps:
- name: Windows CRLF fix
run: git config --global core.autocrlf false

- uses: actions/checkout@v2

- uses: r-lib/actions/setup-pandoc@v1

- uses: r-lib/actions/setup-r@v1
with:
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
use-public-rspm: true

- uses: r-lib/actions/setup-pandoc@v1

- name: Query dependencies
run: |
install.packages('remotes')
saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2)
writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
shell: Rscript {0}

- name: Cache R packages
if: runner.os != 'Windows'
uses: actions/cache@v2
- uses: r-lib/actions/setup-r-dependencies@v1
with:
path: ${{ env.R_LIBS_USER }}
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-

- name: Install system dependencies
if: runner.os == 'Linux'
run: |
while read -r cmd
do
eval sudo $cmd
done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "16.04"))')
- name: Install dependencies
run: |
remotes::install_deps(dependencies = TRUE)
remotes::install_cran("rcmdcheck")
shell: Rscript {0}

- name: Session info
run: |
options(width = 100)
pkgs <- installed.packages()[, "Package"]
sessioninfo::session_info(pkgs, include_base = TRUE)
shell: Rscript {0}
extra-packages: rcmdcheck

- name: Check
env:
_R_CHECK_CRAN_INCOMING_: false
run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check")
shell: Rscript {0}
- uses: r-lib/actions/check-r-package@v1

- name: Show testthat output
if: always()
Expand Down
26 changes: 0 additions & 26 deletions .travis.yml

This file was deleted.

5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Version 0.25.2 (2021-11-6)
* Update autoconf to version 2.6.9 (autoupdate; autoreconf --warnings=obsolete)
* Include tests/ folder in build/check process
* Add `encode_source` and `decode_source` -- helper functions for inlining files and documents

Version 0.25.1 (2021-7-20)
* Add `qcache` helper function
* Remove immediate binding expansion, as it is not part of the R API (comments from CRAN/Luke Tierney). Instead, use the `findVarsInFrame` function to extract immediate bindings from environments.
Expand Down
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: qs
Type: Package
Title: Quick Serialization of R Objects
Version: 0.25.1
Date: 2021-7-24
Version: 0.25.2
Date: 2021-11-7
Authors@R: c(
person("Travers", "Ching", email = "traversc@gmail.com", role = c("aut", "cre", "cph")),
person("Yann", "Collet", role = c("ctb", "cph"), comment = "Yann Collet is the author of the bundled zstd, lz4 and xxHash code"),
Expand All @@ -24,7 +24,7 @@ Imports:
Rcpp, RApiSerialize, stringfish (>= 0.15.1)
LinkingTo: Rcpp, RApiSerialize, stringfish
RoxygenNote: 7.1.1
Suggests: knitr, rmarkdown
Suggests: knitr, rmarkdown, teststhat, dplyr, data.table
VignetteBuilder: knitr
Copyright: This package includes code from the 'zstd' library owned by Facebook, Inc. and created by Yann Collet; the 'lz4' library created and owned by Yann Collet; xxHash library created and owned by Yann Collet; and code derived from the 'Blosc' library created and owned by Francesc Alted.
URL: https://github.com/traversc/qs
Expand Down
20 changes: 11 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ check: $(BUILD)
R CMD check --as-cran $<

check-cran: $(BUILD)
# R --interactive --no-save --args $< <<<'rhub::check_for_cran(commandArgs(T)[1])'
# Rscript -e "rhub::check_on_solaris()"
Rscript -e 'rhub::check("$(BUILD)", platform = c("ubuntu-gcc-devel", "windows-x86_64-devel", "solaris-x86-patched", "linux-x86_64-rocker-gcc-san"))'
Rscript -e 'rhub::check("$(BUILD)", platform = c("ubuntu-gcc-devel", "windows-x86_64-devel", "solaris-x86-patched", "macos-m1-bigsur-release"))'

check-solaris: $(BUILD)
Rscript -e 'rhub::check("$(BUILD)", platform = c("solaris-x86-patched"))'

check-m1: $(BUILD)
Rscript -e 'rhub::check("$(BUILD)", platform = c("macos-m1-bigsur-release"))'

build:
autoconf
Expand Down Expand Up @@ -51,16 +55,14 @@ vignette:
sed -r -i 's/\((.+)\.png/\(vignettes\/\1\.png/' README.md

test:
Rscript tests/qsavemload_testing.R
Rscript tests/correctness_testing.R filestream
Rscript tests/correctness_testing.R fd
Rscript tests/correctness_testing.R memory
Rscript tests/regression_testing.R
Rscript inst/extra_tests/regression_testing.R

testext:
Rscript tests/correctness_testing_extended.R

testqsavem:
Rscript tests/qsavemload_testing.R
Rscript inst/extra_tests/correctness_testing_extended.R

bench:
Rscript tests/benchmark_testing.R
Rscript inst/extra_tests/benchmark_testing.R
4 changes: 3 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ export("qsave",
"qsavem",
"qreadm",
"qload",
"qcache")
"qcache",
"encode_source",
"decode_source")
8 changes: 4 additions & 4 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ base85_decode <- function(encoded_string) {
.Call(`_qs_base85_decode`, encoded_string)
}

base91_encode <- function(rawdata) {
.Call(`_qs_base91_encode`, rawdata)
c_base91_encode <- function(rawdata) {
.Call(`_qs_c_base91_encode`, rawdata)
}

base91_decode <- function(encoded_string) {
.Call(`_qs_base91_decode`, encoded_string)
c_base91_decode <- function(encoded_string) {
.Call(`_qs_c_base91_decode`, encoded_string)
}

is_big_endian <- function() {
Expand Down
107 changes: 107 additions & 0 deletions R/ascii_encoding.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#' Z85 Encoding
#'
#' Encodes binary data (a raw vector) as ascii text using Z85 encoding format
#' @usage base85_encode(rawdata)
#' @param rawdata A raw vector
#' @return A string representation of the raw vector.
#' @details
#' Z85 is a binary to ascii encoding format created by Pieter Hintjens in 2010 and is part of the ZeroMQ RFC.
#' The encoding has a dictionary using 85 out of 94 printable ASCII characters.
#' There are other base 85 encoding schemes, including Ascii85, which is popularized and used by Adobe.
#' Z85 is distinguished by its choice of dictionary, which is suitable for easier inclusion into source code for many programming languages.
#' The dictionary excludes all quote marks and other control characters, and requires no special treatment in R and most other languages.
#' Note: although the official specification restricts input length to multiples of four bytes, the implementation here works with any input length.
#' The overhead (extra bytes used relative to binary) is 25\%. In comparison, base 64 encoding has an overhead of 33.33\%.

#' @references https://rfc.zeromq.org/spec/32/
#' @name base85_encode
NULL

#' Z85 Decoding
#'
#' Decodes a Z85 encoded string back to binary
#' @usage base85_decode(encoded_string)
#' @param encoded_string A string
#' @return The original raw vector.
#' @name base85_decode
NULL

#' basE91 Encoding
#'
#' Encodes binary data (a raw vector) as ascii text using basE91 encoding format
#' @usage base91_encode(rawdata, quote_character = "\"")
#' @param rawdata A raw vector
#' @param quote_character The character to use in the encoding, replacing the double quote character. Must be a single quote "'", double quote "\"" or dash "-".
#' @return A string representation of the raw vector.
#' @details
#' basE91 (capital E for stylization) is a binary to ascii encoding format created by Joachim Henke in 2005.
#' The overhead (extra bytes used relative to binary) is 22.97\% on average. In comparison, base 64 encoding has an overhead of 33.33\%.
#' The original encoding uses a dictionary of 91 out of 94 printable ASCII characters excluding - (dash), \ (backslash) and ' (single quote).
#' The original encoding does include double quote characters, which are less than ideal for strings in R. Therefore,
#' you can use the `quote_character` parameter to substitute dash or single quote.
#' @references http://base91.sourceforge.net/
base91_encode <- function(rawdata, quote_character = "\"") {
if(!quote_character %in% c("\"", "'", "-")) {
stop("quote_character must be a dash, single quote or double quote.")
}
result <- .Call(`_qs_c_base91_encode`, rawdata)
gsub("\"", quote_character, result)
}

#' basE91 Decoding
#'
#' Decodes a basE91 encoded string back to binary
#' @usage base91_decode(encoded_string)
#' @param encoded_string A string
#' @return The original raw vector.
base91_decode <- function(encoded_string) {
stopifnot(length(encoded_string) == 1)
has_double_quote <- grepl("\"", encoded_string)
has_single_quote <- grepl("'", encoded_string)
has_dash <- grepl("-", encoded_string)
if(has_double_quote + has_single_quote + has_dash > 1) {
stop("Format error: dash, single quote and double quote characters are mutually exclusive for base91 encoding.")
}
encoded_string <- gsub("'", "\"", encoded_string)
encoded_string <- gsub("-", "\"", encoded_string)
.Call(`_qs_c_base91_decode`, encoded_string)
}

#' Encode and compress a file or string
#'
#' A helper function for encoding and compressing a file or string to ascii using `base91_encode` and `qserialize` with the highest compression level.
#' @usage encode_source(file = NULL, string = NULL, width = 120)
#' @param file The file to encode (if `string` is not NULL)
#' @param string The string to encode (if `file` is not NULL)
#' @param width The output will be broken up into individual strings, with `width` being the longest allowable string.
#' @return A CharacterVector in base91 representing the compressed original file or string.
encode_source <- function(file = NULL, string = NULL, width = 120) {
if(!is.null(file)) {
n <- file.info(file)$size
x <- readChar(con = file, nchars=n, useBytes = TRUE)
} else if(!is.null(string)) {
x <- string
} else {
stop("either file or string must not be NULL.")
}
x <- qserialize(x, preset = "custom", algorithm = "zstd", compress_level = 22)
x <- base91_encode(x, "'")
starts <- seq(1,nchar(x), by=width)
x <- sapply(starts, function(i) {
substr(x, i, i+width-1)
})
x
}

#' Decode a compressed string
#'
#' A helper function for encoding and compressing a file or string to ascii using `base91_encode` and `qserialize` with the highest compression level.
#' @usage decode_source(string)
#' @param string The string to decode
#' @return The original (decoded) string.
decode_source <- function(string) {
x <- paste0(string, collapse = "")
x <- base91_decode(x)
qdeserialize(x)
}

Loading

0 comments on commit f67de52

Please sign in to comment.