couchbase 3.1.1-universal-darwin-20 → 3.2.0-universal-darwin-20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/CMakeLists.txt +3 -1
- data/ext/build_version.hxx.in +1 -1
- data/ext/cmake/Testing.cmake +1 -0
- data/ext/cmake/ThirdPartyDependencies.cmake +6 -0
- data/ext/cmake/VersionInfo.cmake +3 -0
- data/ext/couchbase/bucket.hxx +47 -28
- data/ext/couchbase/cbsasl/client.h +1 -1
- data/ext/couchbase/cbsasl/context.cc +1 -1
- data/ext/couchbase/cbsasl/context.h +3 -3
- data/ext/couchbase/cbsasl/mechanism.cc +5 -8
- data/ext/couchbase/cbsasl/mechanism.h +1 -4
- data/ext/couchbase/cbsasl/plain/plain.cc +1 -1
- data/ext/couchbase/cbsasl/scram-sha/scram-sha.cc +30 -36
- data/ext/couchbase/cluster.hxx +40 -22
- data/ext/couchbase/cluster_options.hxx +7 -1
- data/ext/couchbase/configuration.hxx +37 -16
- data/ext/couchbase/couchbase.cxx +1145 -291
- data/ext/couchbase/error_map.hxx +1 -1
- data/ext/couchbase/errors.hxx +25 -17
- data/ext/couchbase/io/dns_client.hxx +3 -3
- data/ext/couchbase/io/dns_codec.hxx +4 -5
- data/ext/couchbase/io/dns_config.hxx +5 -6
- data/ext/couchbase/io/dns_message.hxx +3 -3
- data/ext/couchbase/io/http_command.hxx +70 -35
- data/ext/couchbase/io/http_session.hxx +4 -3
- data/ext/couchbase/io/http_session_manager.hxx +28 -19
- data/ext/couchbase/io/mcbp_command.hxx +51 -19
- data/ext/couchbase/io/mcbp_context.hxx +1 -1
- data/ext/couchbase/io/mcbp_parser.hxx +4 -4
- data/ext/couchbase/io/mcbp_session.hxx +91 -101
- data/ext/couchbase/io/query_cache.hxx +2 -2
- data/ext/couchbase/io/retry_orchestrator.hxx +2 -4
- data/ext/couchbase/io/retry_reason.hxx +2 -2
- data/ext/couchbase/io/retry_strategy.hxx +1 -6
- data/ext/couchbase/io/streams.hxx +7 -7
- data/ext/couchbase/metrics/logging_meter.hxx +228 -0
- data/ext/couchbase/metrics/logging_meter_options.hxx +28 -0
- data/ext/couchbase/metrics/meter.hxx +49 -0
- data/ext/couchbase/metrics/noop_meter.hxx +43 -0
- data/ext/couchbase/operations.hxx +4 -0
- data/ext/couchbase/operations/analytics_dataset_create.hxx +16 -12
- data/ext/couchbase/operations/analytics_dataset_drop.hxx +11 -11
- data/ext/couchbase/operations/analytics_dataset_get_all.hxx +6 -6
- data/ext/couchbase/operations/analytics_dataverse_create.hxx +10 -11
- data/ext/couchbase/operations/analytics_dataverse_drop.hxx +10 -11
- data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +9 -11
- data/ext/couchbase/operations/analytics_index_create.hxx +14 -13
- data/ext/couchbase/operations/analytics_index_drop.hxx +18 -12
- data/ext/couchbase/operations/analytics_index_get_all.hxx +8 -6
- data/ext/couchbase/operations/analytics_link.hxx +39 -0
- data/ext/couchbase/operations/analytics_link_azure_blob_external.hxx +145 -0
- data/ext/couchbase/operations/analytics_link_connect.hxx +14 -12
- data/ext/couchbase/operations/analytics_link_couchbase_remote.hxx +220 -0
- data/ext/couchbase/operations/analytics_link_create.hxx +128 -0
- data/ext/couchbase/operations/analytics_link_disconnect.hxx +11 -12
- data/ext/couchbase/operations/analytics_link_drop.hxx +130 -0
- data/ext/couchbase/operations/analytics_link_get_all.hxx +160 -0
- data/ext/couchbase/operations/analytics_link_replace.hxx +128 -0
- data/ext/couchbase/operations/analytics_link_s3_external.hxx +122 -0
- data/ext/couchbase/operations/bucket_create.hxx +8 -8
- data/ext/couchbase/operations/bucket_drop.hxx +5 -5
- data/ext/couchbase/operations/bucket_flush.hxx +5 -5
- data/ext/couchbase/operations/bucket_get.hxx +7 -7
- data/ext/couchbase/operations/bucket_get_all.hxx +7 -5
- data/ext/couchbase/operations/bucket_settings.hxx +40 -49
- data/ext/couchbase/operations/bucket_update.hxx +8 -8
- data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +7 -7
- data/ext/couchbase/operations/collection_create.hxx +11 -11
- data/ext/couchbase/operations/collection_drop.hxx +12 -10
- data/ext/couchbase/operations/collections_manifest_get.hxx +3 -3
- data/ext/couchbase/operations/design_document.hxx +2 -2
- data/ext/couchbase/operations/document_analytics.hxx +29 -36
- data/ext/couchbase/operations/document_append.hxx +3 -3
- data/ext/couchbase/operations/document_decrement.hxx +3 -3
- data/ext/couchbase/operations/document_exists.hxx +2 -2
- data/ext/couchbase/operations/document_get.hxx +3 -3
- data/ext/couchbase/operations/document_get_and_lock.hxx +5 -3
- data/ext/couchbase/operations/document_get_and_touch.hxx +5 -3
- data/ext/couchbase/operations/document_get_projected.hxx +10 -11
- data/ext/couchbase/operations/document_increment.hxx +3 -3
- data/ext/couchbase/operations/document_insert.hxx +3 -3
- data/ext/couchbase/operations/document_lookup_in.hxx +12 -18
- data/ext/couchbase/operations/document_mutate_in.hxx +13 -18
- data/ext/couchbase/operations/document_prepend.hxx +3 -3
- data/ext/couchbase/operations/document_query.hxx +39 -41
- data/ext/couchbase/operations/document_remove.hxx +3 -3
- data/ext/couchbase/operations/document_replace.hxx +3 -3
- data/ext/couchbase/operations/document_search.hxx +56 -61
- data/ext/couchbase/operations/document_touch.hxx +3 -3
- data/ext/couchbase/operations/document_unlock.hxx +3 -3
- data/ext/couchbase/operations/document_upsert.hxx +3 -3
- data/ext/couchbase/operations/document_view.hxx +23 -23
- data/ext/couchbase/operations/group_drop.hxx +5 -5
- data/ext/couchbase/operations/group_get.hxx +7 -7
- data/ext/couchbase/operations/group_get_all.hxx +6 -6
- data/ext/couchbase/operations/group_upsert.hxx +11 -11
- data/ext/couchbase/operations/http_noop.hxx +6 -6
- data/ext/couchbase/operations/mcbp_noop.hxx +3 -3
- data/ext/couchbase/operations/query_index_build_deferred.hxx +6 -6
- data/ext/couchbase/operations/query_index_create.hxx +10 -8
- data/ext/couchbase/operations/query_index_drop.hxx +8 -8
- data/ext/couchbase/operations/query_index_get_all.hxx +43 -39
- data/ext/couchbase/operations/rbac.hxx +40 -63
- data/ext/couchbase/operations/role_get_all.hxx +6 -6
- data/ext/couchbase/operations/scope_create.hxx +10 -10
- data/ext/couchbase/operations/scope_drop.hxx +9 -9
- data/ext/couchbase/operations/scope_get_all.hxx +8 -8
- data/ext/couchbase/operations/search_get_stats.hxx +5 -3
- data/ext/couchbase/operations/search_index.hxx +6 -15
- data/ext/couchbase/operations/search_index_analyze_document.hxx +11 -11
- data/ext/couchbase/operations/search_index_control_ingest.hxx +9 -9
- data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +9 -9
- data/ext/couchbase/operations/search_index_control_query.hxx +9 -9
- data/ext/couchbase/operations/search_index_drop.hxx +11 -9
- data/ext/couchbase/operations/search_index_get.hxx +11 -9
- data/ext/couchbase/operations/search_index_get_all.hxx +11 -11
- data/ext/couchbase/operations/search_index_get_documents_count.hxx +10 -10
- data/ext/couchbase/operations/search_index_get_stats.hxx +10 -8
- data/ext/couchbase/operations/search_index_upsert.hxx +12 -10
- data/ext/couchbase/operations/user_drop.hxx +5 -5
- data/ext/couchbase/operations/user_get.hxx +7 -7
- data/ext/couchbase/operations/user_get_all.hxx +6 -6
- data/ext/couchbase/operations/user_upsert.hxx +9 -9
- data/ext/couchbase/operations/view_index_drop.hxx +10 -10
- data/ext/couchbase/operations/view_index_get.hxx +13 -15
- data/ext/couchbase/operations/view_index_get_all.hxx +17 -20
- data/ext/couchbase/operations/view_index_upsert.hxx +9 -7
- data/ext/couchbase/origin.hxx +14 -10
- data/ext/couchbase/platform/backtrace.c +1 -1
- data/ext/couchbase/platform/base64.cc +5 -5
- data/ext/couchbase/platform/base64.h +2 -5
- data/ext/couchbase/protocol/client_opcode.hxx +7 -4
- data/ext/couchbase/protocol/client_request.hxx +2 -2
- data/ext/couchbase/protocol/client_response.hxx +41 -16
- data/ext/couchbase/protocol/cmd_append.hxx +17 -16
- data/ext/couchbase/protocol/cmd_cluster_map_change_notification.hxx +4 -4
- data/ext/couchbase/protocol/cmd_decrement.hxx +10 -11
- data/ext/couchbase/protocol/cmd_exists.hxx +12 -15
- data/ext/couchbase/protocol/cmd_get.hxx +11 -14
- data/ext/couchbase/protocol/cmd_get_and_lock.hxx +10 -12
- data/ext/couchbase/protocol/cmd_get_and_touch.hxx +10 -12
- data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +13 -18
- data/ext/couchbase/protocol/cmd_get_collection_id.hxx +12 -15
- data/ext/couchbase/protocol/cmd_get_collections_manifest.hxx +12 -16
- data/ext/couchbase/protocol/cmd_get_error_map.hxx +14 -17
- data/ext/couchbase/protocol/cmd_hello.hxx +8 -10
- data/ext/couchbase/protocol/cmd_increment.hxx +9 -10
- data/ext/couchbase/protocol/cmd_insert.hxx +9 -9
- data/ext/couchbase/protocol/cmd_lookup_in.hxx +12 -13
- data/ext/couchbase/protocol/cmd_mutate_in.hxx +11 -11
- data/ext/couchbase/protocol/cmd_noop.hxx +16 -20
- data/ext/couchbase/protocol/cmd_prepend.hxx +9 -10
- data/ext/couchbase/protocol/cmd_remove.hxx +10 -13
- data/ext/couchbase/protocol/cmd_replace.hxx +7 -7
- data/ext/couchbase/protocol/cmd_sasl_auth.hxx +8 -10
- data/ext/couchbase/protocol/cmd_sasl_list_mechs.hxx +10 -15
- data/ext/couchbase/protocol/cmd_sasl_step.hxx +10 -12
- data/ext/couchbase/protocol/cmd_select_bucket.hxx +14 -18
- data/ext/couchbase/protocol/cmd_touch.hxx +8 -11
- data/ext/couchbase/protocol/cmd_unlock.hxx +10 -14
- data/ext/couchbase/protocol/cmd_upsert.hxx +8 -8
- data/ext/couchbase/protocol/datatype.hxx +3 -3
- data/ext/couchbase/protocol/durability_level.hxx +2 -2
- data/ext/couchbase/protocol/frame_info_id.hxx +4 -4
- data/ext/couchbase/protocol/hello_feature.hxx +2 -2
- data/ext/couchbase/protocol/magic.hxx +2 -2
- data/ext/couchbase/protocol/server_opcode.hxx +2 -2
- data/ext/couchbase/protocol/server_request.hxx +1 -1
- data/ext/couchbase/protocol/status.hxx +4 -7
- data/ext/couchbase/protocol/unsigned_leb128.h +5 -20
- data/ext/couchbase/service_type.hxx +4 -4
- data/ext/couchbase/tracing/constants.hxx +261 -0
- data/ext/couchbase/tracing/noop_tracer.hxx +50 -0
- data/ext/couchbase/tracing/request_tracer.hxx +77 -0
- data/ext/couchbase/tracing/threshold_logging_options.hxx +64 -0
- data/ext/couchbase/tracing/threshold_logging_tracer.hxx +366 -0
- data/ext/couchbase/utils/byteswap.hxx +1 -1
- data/ext/couchbase/utils/connection_string.hxx +21 -1
- data/ext/couchbase/utils/name_codec.hxx +41 -0
- data/ext/couchbase/utils/url_codec.hxx +236 -0
- data/ext/couchbase/version.hxx +1 -1
- data/ext/test/CMakeLists.txt +1 -0
- data/ext/test/test_native_trivial_query.cxx +60 -0
- data/ext/third_party/hdr_histogram_c/CMakeLists.txt +84 -0
- data/ext/third_party/hdr_histogram_c/COPYING.txt +121 -0
- data/ext/third_party/hdr_histogram_c/LICENSE.txt +41 -0
- data/ext/third_party/hdr_histogram_c/config.cmake.in +6 -0
- data/ext/third_party/hdr_histogram_c/src/CMakeLists.txt +83 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_atomic.h +146 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_encoding.c +322 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_encoding.h +79 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_endian.h +116 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram.c +1196 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram.h +516 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log.c +1290 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log.h +236 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log_no_op.c +171 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_interval_recorder.c +227 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_interval_recorder.h +109 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_malloc.h +19 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_tests.h +22 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_thread.c +108 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_thread.h +55 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_time.c +98 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_time.h +49 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_writer_reader_phaser.c +143 -0
- data/ext/third_party/hdr_histogram_c/src/hdr_writer_reader_phaser.h +51 -0
- data/lib/couchbase/cluster.rb +1 -0
- data/lib/couchbase/errors.rb +3 -0
- data/lib/couchbase/libcouchbase.bundle +0 -0
- data/lib/couchbase/management/analytics_index_manager.rb +920 -226
- data/lib/couchbase/management/bucket_manager.rb +207 -69
- data/lib/couchbase/management/collection_manager.rb +173 -61
- data/lib/couchbase/management/query_index_manager.rb +357 -169
- data/lib/couchbase/options.rb +75 -3
- data/lib/couchbase/scope.rb +102 -0
- data/lib/couchbase/utils/time.rb +4 -0
- data/lib/couchbase/version.rb +6 -6
- metadata +48 -5
@@ -0,0 +1,1290 @@
|
|
1
|
+
/**
|
2
|
+
* hdr_histogram_log.c
|
3
|
+
* Written by Michael Barker and released to the public domain,
|
4
|
+
* as explained at http://creativecommons.org/publicdomain/zero/1.0/
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <stdint.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <stdbool.h>
|
10
|
+
#include <inttypes.h>
|
11
|
+
#include <stdio.h>
|
12
|
+
#include <string.h>
|
13
|
+
#if defined(_MSC_VER)
|
14
|
+
#undef HAVE_UNISTD_H
|
15
|
+
#endif
|
16
|
+
#include <zlib.h>
|
17
|
+
#include <errno.h>
|
18
|
+
#include <time.h>
|
19
|
+
|
20
|
+
#include "hdr_encoding.h"
|
21
|
+
#include "hdr_histogram.h"
|
22
|
+
#include "hdr_histogram_log.h"
|
23
|
+
#include "hdr_tests.h"
|
24
|
+
|
25
|
+
#if defined(_MSC_VER)
|
26
|
+
#include <intsafe.h>
|
27
|
+
typedef SSIZE_T ssize_t;
|
28
|
+
#pragma comment(lib, "ws2_32.lib")
|
29
|
+
#pragma warning(push)
|
30
|
+
#pragma warning(disable: 4996)
|
31
|
+
#endif
|
32
|
+
|
33
|
+
#include "hdr_endian.h"
|
34
|
+
|
35
|
+
#ifndef HDR_MALLOC_INCLUDE
|
36
|
+
#define HDR_MALLOC_INCLUDE "hdr_malloc.h"
|
37
|
+
#endif
|
38
|
+
|
39
|
+
#include HDR_MALLOC_INCLUDE
|
40
|
+
|
41
|
+
/* Private prototypes useful for the logger */
|
42
|
+
int32_t counts_index_for(const struct hdr_histogram* h, int64_t value);
|
43
|
+
|
44
|
+
|
45
|
+
#define FAIL_AND_CLEANUP(label, error_name, error) \
|
46
|
+
do \
|
47
|
+
{ \
|
48
|
+
error_name = error; \
|
49
|
+
goto label; \
|
50
|
+
} \
|
51
|
+
while (0)
|
52
|
+
|
53
|
+
/* ######## ## ## ###### ####### ######## #### ## ## ###### */
|
54
|
+
/* ## ### ## ## ## ## ## ## ## ## ### ## ## ## */
|
55
|
+
/* ## #### ## ## ## ## ## ## ## #### ## ## */
|
56
|
+
/* ###### ## ## ## ## ## ## ## ## ## ## ## ## ## #### */
|
57
|
+
/* ## ## #### ## ## ## ## ## ## ## #### ## ## */
|
58
|
+
/* ## ## ### ## ## ## ## ## ## ## ## ### ## ## */
|
59
|
+
/* ######## ## ## ###### ####### ######## #### ## ## ###### */
|
60
|
+
|
61
|
+
static const uint32_t V0_ENCODING_COOKIE = 0x1c849308;
|
62
|
+
static const uint32_t V0_COMPRESSION_COOKIE = 0x1c849309;
|
63
|
+
|
64
|
+
static const uint32_t V1_ENCODING_COOKIE = 0x1c849301;
|
65
|
+
static const uint32_t V1_COMPRESSION_COOKIE = 0x1c849302;
|
66
|
+
|
67
|
+
static const uint32_t V2_ENCODING_COOKIE = 0x1c849303;
|
68
|
+
static const uint32_t V2_COMPRESSION_COOKIE = 0x1c849304;
|
69
|
+
|
70
|
+
static uint32_t get_cookie_base(uint32_t cookie)
|
71
|
+
{
|
72
|
+
return (cookie & ~0xf0U);
|
73
|
+
}
|
74
|
+
|
75
|
+
static uint32_t word_size_from_cookie(uint32_t cookie)
|
76
|
+
{
|
77
|
+
return (cookie & 0xf0U) >> 4U;
|
78
|
+
}
|
79
|
+
|
80
|
+
const char* hdr_strerror(int errnum)
|
81
|
+
{
|
82
|
+
switch (errnum)
|
83
|
+
{
|
84
|
+
case HDR_COMPRESSION_COOKIE_MISMATCH:
|
85
|
+
return "Compression cookie mismatch";
|
86
|
+
case HDR_ENCODING_COOKIE_MISMATCH:
|
87
|
+
return "Encoding cookie mismatch";
|
88
|
+
case HDR_DEFLATE_INIT_FAIL:
|
89
|
+
return "Deflate initialisation failed";
|
90
|
+
case HDR_DEFLATE_FAIL:
|
91
|
+
return "Deflate failed";
|
92
|
+
case HDR_INFLATE_INIT_FAIL:
|
93
|
+
return "Inflate initialisation failed";
|
94
|
+
case HDR_INFLATE_FAIL:
|
95
|
+
return "Inflate failed";
|
96
|
+
case HDR_LOG_INVALID_VERSION:
|
97
|
+
return "Log - invalid version in log header";
|
98
|
+
case HDR_TRAILING_ZEROS_INVALID:
|
99
|
+
return "Invalid number of trailing zeros";
|
100
|
+
case HDR_VALUE_TRUNCATED:
|
101
|
+
return "Truncated value found when decoding";
|
102
|
+
case HDR_ENCODED_INPUT_TOO_LONG:
|
103
|
+
return "The encoded input exceeds the size of the histogram";
|
104
|
+
default:
|
105
|
+
return strerror(errnum);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
static void strm_init(z_stream* strm)
|
110
|
+
{
|
111
|
+
memset(strm, 0, sizeof(z_stream));
|
112
|
+
}
|
113
|
+
|
114
|
+
union uint64_dbl_cvt
|
115
|
+
{
|
116
|
+
uint64_t l;
|
117
|
+
double d;
|
118
|
+
};
|
119
|
+
|
120
|
+
static double int64_bits_to_double(int64_t i)
|
121
|
+
{
|
122
|
+
union uint64_dbl_cvt x;
|
123
|
+
|
124
|
+
x.l = (uint64_t) i;
|
125
|
+
return x.d;
|
126
|
+
}
|
127
|
+
|
128
|
+
static uint64_t double_to_int64_bits(double d)
|
129
|
+
{
|
130
|
+
union uint64_dbl_cvt x;
|
131
|
+
|
132
|
+
x.d = d;
|
133
|
+
return x.l;
|
134
|
+
}
|
135
|
+
|
136
|
+
#pragma pack(push, 1)
|
137
|
+
typedef struct /*__attribute__((__packed__))*/
|
138
|
+
{
|
139
|
+
uint32_t cookie;
|
140
|
+
int32_t significant_figures;
|
141
|
+
int64_t lowest_discernible_value;
|
142
|
+
int64_t highest_trackable_value;
|
143
|
+
int64_t total_count;
|
144
|
+
int64_t counts[1];
|
145
|
+
} encoding_flyweight_v0_t;
|
146
|
+
|
147
|
+
typedef struct /*__attribute__((__packed__))*/
|
148
|
+
{
|
149
|
+
uint32_t cookie;
|
150
|
+
int32_t payload_len;
|
151
|
+
int32_t normalizing_index_offset;
|
152
|
+
int32_t significant_figures;
|
153
|
+
int64_t lowest_discernible_value;
|
154
|
+
int64_t highest_trackable_value;
|
155
|
+
uint64_t conversion_ratio_bits;
|
156
|
+
uint8_t counts[1];
|
157
|
+
} encoding_flyweight_v1_t;
|
158
|
+
|
159
|
+
typedef struct /*__attribute__((__packed__))*/
|
160
|
+
{
|
161
|
+
uint32_t cookie;
|
162
|
+
int32_t length;
|
163
|
+
uint8_t data[1];
|
164
|
+
} compression_flyweight_t;
|
165
|
+
#pragma pack(pop)
|
166
|
+
|
167
|
+
#define SIZEOF_ENCODING_FLYWEIGHT_V0 (sizeof(encoding_flyweight_v0_t) - sizeof(int64_t))
|
168
|
+
#define SIZEOF_ENCODING_FLYWEIGHT_V1 (sizeof(encoding_flyweight_v1_t) - sizeof(uint8_t))
|
169
|
+
#define SIZEOF_COMPRESSION_FLYWEIGHT (sizeof(compression_flyweight_t) - sizeof(uint8_t))
|
170
|
+
|
171
|
+
int hdr_encode_compressed(
|
172
|
+
struct hdr_histogram* h,
|
173
|
+
uint8_t** compressed_histogram,
|
174
|
+
size_t* compressed_len)
|
175
|
+
{
|
176
|
+
encoding_flyweight_v1_t* encoded = NULL;
|
177
|
+
compression_flyweight_t* compressed = NULL;
|
178
|
+
int i;
|
179
|
+
int result = 0;
|
180
|
+
int data_index = 0;
|
181
|
+
int32_t payload_len;
|
182
|
+
uLong encoded_size;
|
183
|
+
uLongf dest_len;
|
184
|
+
size_t compressed_size;
|
185
|
+
|
186
|
+
int32_t len_to_max = counts_index_for(h, h->max_value) + 1;
|
187
|
+
int32_t counts_limit = len_to_max < h->counts_len ? len_to_max : h->counts_len;
|
188
|
+
|
189
|
+
const size_t encoded_len = SIZEOF_ENCODING_FLYWEIGHT_V1 + MAX_BYTES_LEB128 * (size_t) counts_limit;
|
190
|
+
if ((encoded = (encoding_flyweight_v1_t*) hdr_calloc(encoded_len, sizeof(uint8_t))) == NULL)
|
191
|
+
{
|
192
|
+
FAIL_AND_CLEANUP(cleanup, result, ENOMEM);
|
193
|
+
}
|
194
|
+
|
195
|
+
for (i = 0; i < counts_limit;)
|
196
|
+
{
|
197
|
+
int64_t value = h->counts[i];
|
198
|
+
i++;
|
199
|
+
|
200
|
+
if (value == 0)
|
201
|
+
{
|
202
|
+
int32_t zeros = 1;
|
203
|
+
|
204
|
+
while (i < counts_limit && 0 == h->counts[i])
|
205
|
+
{
|
206
|
+
zeros++;
|
207
|
+
i++;
|
208
|
+
}
|
209
|
+
|
210
|
+
data_index += zig_zag_encode_i64(&encoded->counts[data_index], -zeros);
|
211
|
+
}
|
212
|
+
else
|
213
|
+
{
|
214
|
+
data_index += zig_zag_encode_i64(&encoded->counts[data_index], value);
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
payload_len = data_index;
|
219
|
+
encoded_size = SIZEOF_ENCODING_FLYWEIGHT_V1 + data_index;
|
220
|
+
|
221
|
+
encoded->cookie = htobe32(V2_ENCODING_COOKIE | 0x10U);
|
222
|
+
encoded->payload_len = htobe32(payload_len);
|
223
|
+
encoded->normalizing_index_offset = htobe32(h->normalizing_index_offset);
|
224
|
+
encoded->significant_figures = htobe32(h->significant_figures);
|
225
|
+
encoded->lowest_discernible_value = htobe64(h->lowest_discernible_value);
|
226
|
+
encoded->highest_trackable_value = htobe64(h->highest_trackable_value);
|
227
|
+
encoded->conversion_ratio_bits = htobe64(double_to_int64_bits(h->conversion_ratio));
|
228
|
+
|
229
|
+
|
230
|
+
/* Estimate the size of the compressed histogram. */
|
231
|
+
dest_len = compressBound(encoded_size);
|
232
|
+
compressed_size = SIZEOF_COMPRESSION_FLYWEIGHT + dest_len;
|
233
|
+
|
234
|
+
if ((compressed = (compression_flyweight_t*) hdr_malloc(compressed_size)) == NULL)
|
235
|
+
{
|
236
|
+
FAIL_AND_CLEANUP(cleanup, result, ENOMEM);
|
237
|
+
}
|
238
|
+
|
239
|
+
if (Z_OK != compress(compressed->data, &dest_len, (Bytef*) encoded, encoded_size))
|
240
|
+
{
|
241
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_DEFLATE_FAIL);
|
242
|
+
}
|
243
|
+
|
244
|
+
compressed->cookie = htobe32(V2_COMPRESSION_COOKIE | 0x10U);
|
245
|
+
compressed->length = htobe32((int32_t)dest_len);
|
246
|
+
|
247
|
+
*compressed_histogram = (uint8_t*) compressed;
|
248
|
+
*compressed_len = SIZEOF_COMPRESSION_FLYWEIGHT + dest_len;
|
249
|
+
|
250
|
+
cleanup:
|
251
|
+
hdr_free(encoded);
|
252
|
+
if (result == HDR_DEFLATE_FAIL)
|
253
|
+
{
|
254
|
+
hdr_free(compressed);
|
255
|
+
}
|
256
|
+
|
257
|
+
return result;
|
258
|
+
}
|
259
|
+
|
260
|
+
/* ######## ######## ###### ####### ######## #### ## ## ###### */
|
261
|
+
/* ## ## ## ## ## ## ## ## ## ## ### ## ## ## */
|
262
|
+
/* ## ## ## ## ## ## ## ## ## #### ## ## */
|
263
|
+
/* ## ## ###### ## ## ## ## ## ## ## ## ## ## #### */
|
264
|
+
/* ## ## ## ## ## ## ## ## ## ## #### ## ## */
|
265
|
+
/* ## ## ## ## ## ## ## ## ## ## ## ### ## ## */
|
266
|
+
/* ######## ######## ###### ####### ######## #### ## ## ###### */
|
267
|
+
|
268
|
+
static void apply_to_counts_16(struct hdr_histogram* h, const int16_t* counts_data, const int32_t counts_limit)
|
269
|
+
{
|
270
|
+
int i;
|
271
|
+
for (i = 0; i < counts_limit; i++)
|
272
|
+
{
|
273
|
+
h->counts[i] = be16toh(counts_data[i]);
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
static void apply_to_counts_32(struct hdr_histogram* h, const int32_t* counts_data, const int32_t counts_limit)
|
278
|
+
{
|
279
|
+
int i;
|
280
|
+
for (i = 0; i < counts_limit; i++)
|
281
|
+
{
|
282
|
+
h->counts[i] = be32toh(counts_data[i]);
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
static void apply_to_counts_64(struct hdr_histogram* h, const int64_t* counts_data, const int32_t counts_limit)
|
287
|
+
{
|
288
|
+
int i;
|
289
|
+
for (i = 0; i < counts_limit; i++)
|
290
|
+
{
|
291
|
+
h->counts[i] = be64toh(counts_data[i]);
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
static int apply_to_counts_zz(struct hdr_histogram* h, const uint8_t* counts_data, const int32_t data_limit)
|
296
|
+
{
|
297
|
+
int64_t data_index = 0;
|
298
|
+
int32_t counts_index = 0;
|
299
|
+
int64_t value;
|
300
|
+
|
301
|
+
while (data_index < data_limit && counts_index < h->counts_len)
|
302
|
+
{
|
303
|
+
data_index += zig_zag_decode_i64(&counts_data[data_index], &value);
|
304
|
+
|
305
|
+
if (value < 0)
|
306
|
+
{
|
307
|
+
int64_t zeros = -value;
|
308
|
+
|
309
|
+
if (value <= INT32_MIN || counts_index + zeros > h->counts_len)
|
310
|
+
{
|
311
|
+
return HDR_TRAILING_ZEROS_INVALID;
|
312
|
+
}
|
313
|
+
|
314
|
+
counts_index += (int32_t) zeros;
|
315
|
+
}
|
316
|
+
else
|
317
|
+
{
|
318
|
+
h->counts[counts_index] = value;
|
319
|
+
counts_index++;
|
320
|
+
}
|
321
|
+
}
|
322
|
+
|
323
|
+
if (data_index > data_limit)
|
324
|
+
{
|
325
|
+
return HDR_VALUE_TRUNCATED;
|
326
|
+
}
|
327
|
+
else if (data_index < data_limit)
|
328
|
+
{
|
329
|
+
return HDR_ENCODED_INPUT_TOO_LONG;
|
330
|
+
}
|
331
|
+
|
332
|
+
return 0;
|
333
|
+
}
|
334
|
+
|
335
|
+
static int apply_to_counts(
|
336
|
+
struct hdr_histogram* h, const int32_t word_size, const uint8_t* counts_data, const int32_t counts_limit)
|
337
|
+
{
|
338
|
+
switch (word_size)
|
339
|
+
{
|
340
|
+
case 2:
|
341
|
+
apply_to_counts_16(h, (const int16_t*) counts_data, counts_limit);
|
342
|
+
return 0;
|
343
|
+
|
344
|
+
case 4:
|
345
|
+
apply_to_counts_32(h, (const int32_t*) counts_data, counts_limit);
|
346
|
+
return 0;
|
347
|
+
|
348
|
+
case 8:
|
349
|
+
apply_to_counts_64(h, (const int64_t*) counts_data, counts_limit);
|
350
|
+
return 0;
|
351
|
+
|
352
|
+
case 1:
|
353
|
+
return apply_to_counts_zz(h, counts_data, counts_limit);
|
354
|
+
|
355
|
+
default:
|
356
|
+
return -1;
|
357
|
+
}
|
358
|
+
}
|
359
|
+
|
360
|
+
static int hdr_decode_compressed_v0(
|
361
|
+
compression_flyweight_t* compression_flyweight,
|
362
|
+
size_t length,
|
363
|
+
struct hdr_histogram** histogram)
|
364
|
+
{
|
365
|
+
struct hdr_histogram* h = NULL;
|
366
|
+
int result = 0;
|
367
|
+
uint8_t* counts_array = NULL;
|
368
|
+
encoding_flyweight_v0_t encoding_flyweight;
|
369
|
+
z_stream strm;
|
370
|
+
uint32_t encoding_cookie;
|
371
|
+
int32_t compressed_len, word_size, significant_figures, counts_array_len;
|
372
|
+
int64_t lowest_discernible_value, highest_trackable_value;
|
373
|
+
|
374
|
+
strm_init(&strm);
|
375
|
+
if (inflateInit(&strm) != Z_OK)
|
376
|
+
{
|
377
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL);
|
378
|
+
}
|
379
|
+
|
380
|
+
compressed_len = be32toh(compression_flyweight->length);
|
381
|
+
|
382
|
+
if (compressed_len < 0 || (length - SIZEOF_COMPRESSION_FLYWEIGHT) < (size_t)compressed_len)
|
383
|
+
{
|
384
|
+
FAIL_AND_CLEANUP(cleanup, result, EINVAL);
|
385
|
+
}
|
386
|
+
|
387
|
+
strm.next_in = compression_flyweight->data;
|
388
|
+
strm.avail_in = (uInt) compressed_len;
|
389
|
+
strm.next_out = (uint8_t *) &encoding_flyweight;
|
390
|
+
strm.avail_out = SIZEOF_ENCODING_FLYWEIGHT_V0;
|
391
|
+
|
392
|
+
if (inflate(&strm, Z_SYNC_FLUSH) != Z_OK)
|
393
|
+
{
|
394
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL);
|
395
|
+
}
|
396
|
+
|
397
|
+
encoding_cookie = get_cookie_base(be32toh(encoding_flyweight.cookie));
|
398
|
+
if (V0_ENCODING_COOKIE != encoding_cookie)
|
399
|
+
{
|
400
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_ENCODING_COOKIE_MISMATCH);
|
401
|
+
}
|
402
|
+
|
403
|
+
word_size = word_size_from_cookie(be32toh(encoding_flyweight.cookie));
|
404
|
+
lowest_discernible_value = be64toh(encoding_flyweight.lowest_discernible_value);
|
405
|
+
highest_trackable_value = be64toh(encoding_flyweight.highest_trackable_value);
|
406
|
+
significant_figures = be32toh(encoding_flyweight.significant_figures);
|
407
|
+
|
408
|
+
if (hdr_init(
|
409
|
+
lowest_discernible_value,
|
410
|
+
highest_trackable_value,
|
411
|
+
significant_figures,
|
412
|
+
&h) != 0)
|
413
|
+
{
|
414
|
+
FAIL_AND_CLEANUP(cleanup, result, ENOMEM);
|
415
|
+
}
|
416
|
+
|
417
|
+
counts_array_len = h->counts_len * word_size;
|
418
|
+
if ((counts_array = (uint8_t*) hdr_calloc(1, (size_t) counts_array_len)) == NULL)
|
419
|
+
{
|
420
|
+
FAIL_AND_CLEANUP(cleanup, result, ENOMEM);
|
421
|
+
}
|
422
|
+
|
423
|
+
strm.next_out = counts_array;
|
424
|
+
strm.avail_out = (uInt) counts_array_len;
|
425
|
+
|
426
|
+
if (inflate(&strm, Z_FINISH) != Z_STREAM_END)
|
427
|
+
{
|
428
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL);
|
429
|
+
}
|
430
|
+
|
431
|
+
apply_to_counts(h, word_size, counts_array, h->counts_len);
|
432
|
+
|
433
|
+
hdr_reset_internal_counters(h);
|
434
|
+
h->normalizing_index_offset = 0;
|
435
|
+
h->conversion_ratio = 1.0;
|
436
|
+
|
437
|
+
cleanup:
|
438
|
+
(void)inflateEnd(&strm);
|
439
|
+
hdr_free(counts_array);
|
440
|
+
|
441
|
+
if (result != 0)
|
442
|
+
{
|
443
|
+
hdr_free(h);
|
444
|
+
}
|
445
|
+
else if (NULL == *histogram)
|
446
|
+
{
|
447
|
+
*histogram = h;
|
448
|
+
}
|
449
|
+
else
|
450
|
+
{
|
451
|
+
hdr_add(*histogram, h);
|
452
|
+
hdr_free(h);
|
453
|
+
}
|
454
|
+
|
455
|
+
return result;
|
456
|
+
}
|
457
|
+
|
458
|
+
static int hdr_decode_compressed_v1(
|
459
|
+
compression_flyweight_t* compression_flyweight,
|
460
|
+
size_t length,
|
461
|
+
struct hdr_histogram** histogram)
|
462
|
+
{
|
463
|
+
struct hdr_histogram* h = NULL;
|
464
|
+
int result = 0;
|
465
|
+
uint8_t* counts_array = NULL;
|
466
|
+
encoding_flyweight_v1_t encoding_flyweight;
|
467
|
+
z_stream strm;
|
468
|
+
uint32_t encoding_cookie;
|
469
|
+
int32_t compressed_length, word_size, significant_figures, counts_limit, counts_array_len;
|
470
|
+
int64_t lowest_discernible_value, highest_trackable_value;
|
471
|
+
|
472
|
+
strm_init(&strm);
|
473
|
+
if (inflateInit(&strm) != Z_OK)
|
474
|
+
{
|
475
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL);
|
476
|
+
}
|
477
|
+
|
478
|
+
compressed_length = be32toh(compression_flyweight->length);
|
479
|
+
|
480
|
+
if (compressed_length < 0 || length - SIZEOF_COMPRESSION_FLYWEIGHT < (size_t)compressed_length)
|
481
|
+
{
|
482
|
+
FAIL_AND_CLEANUP(cleanup, result, EINVAL);
|
483
|
+
}
|
484
|
+
|
485
|
+
strm.next_in = compression_flyweight->data;
|
486
|
+
strm.avail_in = (uInt) compressed_length;
|
487
|
+
strm.next_out = (uint8_t *) &encoding_flyweight;
|
488
|
+
strm.avail_out = SIZEOF_ENCODING_FLYWEIGHT_V1;
|
489
|
+
|
490
|
+
if (inflate(&strm, Z_SYNC_FLUSH) != Z_OK)
|
491
|
+
{
|
492
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL);
|
493
|
+
}
|
494
|
+
|
495
|
+
encoding_cookie = get_cookie_base(be32toh(encoding_flyweight.cookie));
|
496
|
+
if (V1_ENCODING_COOKIE != encoding_cookie)
|
497
|
+
{
|
498
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_ENCODING_COOKIE_MISMATCH);
|
499
|
+
}
|
500
|
+
|
501
|
+
word_size = word_size_from_cookie(be32toh(encoding_flyweight.cookie));
|
502
|
+
counts_limit = be32toh(encoding_flyweight.payload_len) / word_size;
|
503
|
+
lowest_discernible_value = be64toh(encoding_flyweight.lowest_discernible_value);
|
504
|
+
highest_trackable_value = be64toh(encoding_flyweight.highest_trackable_value);
|
505
|
+
significant_figures = be32toh(encoding_flyweight.significant_figures);
|
506
|
+
|
507
|
+
if (hdr_init(
|
508
|
+
lowest_discernible_value,
|
509
|
+
highest_trackable_value,
|
510
|
+
significant_figures,
|
511
|
+
&h) != 0)
|
512
|
+
{
|
513
|
+
FAIL_AND_CLEANUP(cleanup, result, ENOMEM);
|
514
|
+
}
|
515
|
+
|
516
|
+
/* Give the temp uncompressed array a little bif of extra */
|
517
|
+
counts_array_len = counts_limit * word_size;
|
518
|
+
|
519
|
+
if ((counts_array = (uint8_t*) hdr_calloc(1, (size_t) counts_array_len)) == NULL)
|
520
|
+
{
|
521
|
+
FAIL_AND_CLEANUP(cleanup, result, ENOMEM);
|
522
|
+
}
|
523
|
+
|
524
|
+
strm.next_out = counts_array;
|
525
|
+
strm.avail_out = (uInt) counts_array_len;
|
526
|
+
|
527
|
+
if (inflate(&strm, Z_FINISH) != Z_STREAM_END)
|
528
|
+
{
|
529
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL);
|
530
|
+
}
|
531
|
+
|
532
|
+
apply_to_counts(h, word_size, counts_array, counts_limit);
|
533
|
+
|
534
|
+
h->normalizing_index_offset = be32toh(encoding_flyweight.normalizing_index_offset);
|
535
|
+
h->conversion_ratio = int64_bits_to_double(be64toh(encoding_flyweight.conversion_ratio_bits));
|
536
|
+
hdr_reset_internal_counters(h);
|
537
|
+
|
538
|
+
cleanup:
|
539
|
+
(void)inflateEnd(&strm);
|
540
|
+
hdr_free(counts_array);
|
541
|
+
|
542
|
+
if (result != 0)
|
543
|
+
{
|
544
|
+
hdr_free(h);
|
545
|
+
}
|
546
|
+
else if (NULL == *histogram)
|
547
|
+
{
|
548
|
+
*histogram = h;
|
549
|
+
}
|
550
|
+
else
|
551
|
+
{
|
552
|
+
hdr_add(*histogram, h);
|
553
|
+
hdr_free(h);
|
554
|
+
}
|
555
|
+
|
556
|
+
return result;
|
557
|
+
}
|
558
|
+
|
559
|
+
static int hdr_decode_compressed_v2(
|
560
|
+
compression_flyweight_t* compression_flyweight,
|
561
|
+
size_t length,
|
562
|
+
struct hdr_histogram** histogram)
|
563
|
+
{
|
564
|
+
struct hdr_histogram* h = NULL;
|
565
|
+
int result = 0;
|
566
|
+
int rc = 0;
|
567
|
+
uint8_t* counts_array = NULL;
|
568
|
+
encoding_flyweight_v1_t encoding_flyweight;
|
569
|
+
z_stream strm;
|
570
|
+
uint32_t encoding_cookie;
|
571
|
+
int32_t compressed_length, counts_limit, significant_figures;
|
572
|
+
int64_t lowest_discernible_value, highest_trackable_value;
|
573
|
+
|
574
|
+
strm_init(&strm);
|
575
|
+
if (inflateInit(&strm) != Z_OK)
|
576
|
+
{
|
577
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL);
|
578
|
+
}
|
579
|
+
|
580
|
+
compressed_length = be32toh(compression_flyweight->length);
|
581
|
+
|
582
|
+
if (compressed_length < 0 || length - SIZEOF_COMPRESSION_FLYWEIGHT < (size_t)compressed_length)
|
583
|
+
{
|
584
|
+
FAIL_AND_CLEANUP(cleanup, result, EINVAL);
|
585
|
+
}
|
586
|
+
|
587
|
+
strm.next_in = compression_flyweight->data;
|
588
|
+
strm.avail_in = (uInt) compressed_length;
|
589
|
+
strm.next_out = (uint8_t *) &encoding_flyweight;
|
590
|
+
strm.avail_out = SIZEOF_ENCODING_FLYWEIGHT_V1;
|
591
|
+
|
592
|
+
if (inflate(&strm, Z_SYNC_FLUSH) != Z_OK)
|
593
|
+
{
|
594
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL);
|
595
|
+
}
|
596
|
+
|
597
|
+
encoding_cookie = get_cookie_base(be32toh(encoding_flyweight.cookie));
|
598
|
+
if (V2_ENCODING_COOKIE != encoding_cookie)
|
599
|
+
{
|
600
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_ENCODING_COOKIE_MISMATCH);
|
601
|
+
}
|
602
|
+
|
603
|
+
counts_limit = be32toh(encoding_flyweight.payload_len);
|
604
|
+
lowest_discernible_value = be64toh(encoding_flyweight.lowest_discernible_value);
|
605
|
+
highest_trackable_value = be64toh(encoding_flyweight.highest_trackable_value);
|
606
|
+
significant_figures = be32toh(encoding_flyweight.significant_figures);
|
607
|
+
|
608
|
+
rc = hdr_init(lowest_discernible_value, highest_trackable_value, significant_figures, &h);
|
609
|
+
if (rc)
|
610
|
+
{
|
611
|
+
FAIL_AND_CLEANUP(cleanup, result, rc);
|
612
|
+
}
|
613
|
+
|
614
|
+
/* Make sure there at least 9 bytes to read */
|
615
|
+
/* if there is a corrupt value at the end */
|
616
|
+
/* of the array we won't read corrupt data or crash. */
|
617
|
+
if ((counts_array = (uint8_t*) hdr_calloc(1, (size_t) counts_limit + 9)) == NULL)
|
618
|
+
{
|
619
|
+
FAIL_AND_CLEANUP(cleanup, result, ENOMEM);
|
620
|
+
}
|
621
|
+
|
622
|
+
strm.next_out = counts_array;
|
623
|
+
strm.avail_out = (uInt) counts_limit;
|
624
|
+
|
625
|
+
if (inflate(&strm, Z_FINISH) != Z_STREAM_END)
|
626
|
+
{
|
627
|
+
FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL);
|
628
|
+
}
|
629
|
+
|
630
|
+
rc = apply_to_counts_zz(h, counts_array, counts_limit);
|
631
|
+
if (rc)
|
632
|
+
{
|
633
|
+
FAIL_AND_CLEANUP(cleanup, result, rc);
|
634
|
+
}
|
635
|
+
|
636
|
+
h->normalizing_index_offset = be32toh(encoding_flyweight.normalizing_index_offset);
|
637
|
+
h->conversion_ratio = int64_bits_to_double(be64toh(encoding_flyweight.conversion_ratio_bits));
|
638
|
+
hdr_reset_internal_counters(h);
|
639
|
+
|
640
|
+
cleanup:
|
641
|
+
(void)inflateEnd(&strm);
|
642
|
+
hdr_free(counts_array);
|
643
|
+
|
644
|
+
if (result != 0)
|
645
|
+
{
|
646
|
+
hdr_free(h);
|
647
|
+
}
|
648
|
+
else if (NULL == *histogram)
|
649
|
+
{
|
650
|
+
*histogram = h;
|
651
|
+
}
|
652
|
+
else
|
653
|
+
{
|
654
|
+
hdr_add(*histogram, h);
|
655
|
+
hdr_free(h);
|
656
|
+
}
|
657
|
+
|
658
|
+
return result;
|
659
|
+
}
|
660
|
+
|
661
|
+
int hdr_decode_compressed(
|
662
|
+
uint8_t* buffer, size_t length, struct hdr_histogram** histogram)
|
663
|
+
{
|
664
|
+
uint32_t compression_cookie;
|
665
|
+
compression_flyweight_t* compression_flyweight;
|
666
|
+
|
667
|
+
if (length < SIZEOF_COMPRESSION_FLYWEIGHT)
|
668
|
+
{
|
669
|
+
return EINVAL;
|
670
|
+
}
|
671
|
+
|
672
|
+
compression_flyweight = (compression_flyweight_t*) buffer;
|
673
|
+
|
674
|
+
compression_cookie = get_cookie_base(be32toh(compression_flyweight->cookie));
|
675
|
+
if (V0_COMPRESSION_COOKIE == compression_cookie)
|
676
|
+
{
|
677
|
+
return hdr_decode_compressed_v0(compression_flyweight, length, histogram);
|
678
|
+
}
|
679
|
+
else if (V1_COMPRESSION_COOKIE == compression_cookie)
|
680
|
+
{
|
681
|
+
return hdr_decode_compressed_v1(compression_flyweight, length, histogram);
|
682
|
+
}
|
683
|
+
else if (V2_COMPRESSION_COOKIE == compression_cookie)
|
684
|
+
{
|
685
|
+
return hdr_decode_compressed_v2(compression_flyweight, length, histogram);
|
686
|
+
}
|
687
|
+
|
688
|
+
return HDR_COMPRESSION_COOKIE_MISMATCH;
|
689
|
+
}
|
690
|
+
|
691
|
+
/* ## ## ######## #### ######## ######## ######## */
|
692
|
+
/* ## ## ## ## ## ## ## ## ## ## */
|
693
|
+
/* ## ## ## ## ## ## ## ## ## ## */
|
694
|
+
/* ## ## ## ######## ## ## ###### ######## */
|
695
|
+
/* ## ## ## ## ## ## ## ## ## ## */
|
696
|
+
/* ## ## ## ## ## ## ## ## ## ## */
|
697
|
+
/* ### ### ## ## #### ## ######## ## ## */
|
698
|
+
|
699
|
+
int hdr_log_writer_init(struct hdr_log_writer* writer)
|
700
|
+
{
|
701
|
+
(void)writer;
|
702
|
+
return 0;
|
703
|
+
}
|
704
|
+
|
705
|
+
#define LOG_VERSION "1.2"
|
706
|
+
#define LOG_MAJOR_VERSION 1
|
707
|
+
|
708
|
+
static int print_user_prefix(FILE* f, const char* prefix)
|
709
|
+
{
|
710
|
+
if (!prefix)
|
711
|
+
{
|
712
|
+
return 0;
|
713
|
+
}
|
714
|
+
|
715
|
+
return fprintf(f, "#[%s]\n", prefix);
|
716
|
+
}
|
717
|
+
|
718
|
+
static int print_version(FILE* f, const char* version)
|
719
|
+
{
|
720
|
+
return fprintf(f, "#[Histogram log format version %s]\n", version);
|
721
|
+
}
|
722
|
+
|
723
|
+
static int print_time(FILE* f, hdr_timespec* timestamp)
|
724
|
+
{
|
725
|
+
char time_str[128];
|
726
|
+
struct tm date_time;
|
727
|
+
|
728
|
+
if (!timestamp)
|
729
|
+
{
|
730
|
+
return 0;
|
731
|
+
}
|
732
|
+
|
733
|
+
#if defined(__WINDOWS__)
|
734
|
+
_gmtime32_s(&date_time, ×tamp->tv_sec);
|
735
|
+
#else
|
736
|
+
gmtime_r(×tamp->tv_sec, &date_time);
|
737
|
+
#endif
|
738
|
+
|
739
|
+
strftime(time_str, 128, "%a %b %X %Z %Y", &date_time);
|
740
|
+
|
741
|
+
return fprintf(
|
742
|
+
f, "#[StartTime: %.3f (seconds since epoch), %s]\n",
|
743
|
+
hdr_timespec_as_double(timestamp), time_str);
|
744
|
+
}
|
745
|
+
|
746
|
+
static int print_header(FILE* f)
|
747
|
+
{
|
748
|
+
return fprintf(f, "\"StartTimestamp\",\"EndTimestamp\",\"Interval_Max\",\"Interval_Compressed_Histogram\"\n");
|
749
|
+
}
|
750
|
+
|
751
|
+
/* Example log */
|
752
|
+
/* #[Logged with jHiccup version 2.0.3-SNAPSHOT] */
|
753
|
+
/* #[Histogram log format version 1.01] */
|
754
|
+
/* #[StartTime: 1403476110.183 (seconds since epoch), Mon Jun 23 10:28:30 NZST 2014] */
|
755
|
+
/* "StartTimestamp","EndTimestamp","Interval_Max","Interval_Compressed_Histogram" */
|
756
|
+
int hdr_log_write_header(
|
757
|
+
struct hdr_log_writer* writer, FILE* file,
|
758
|
+
const char* user_prefix, hdr_timespec* timestamp)
|
759
|
+
{
|
760
|
+
(void)writer;
|
761
|
+
|
762
|
+
if (print_user_prefix(file, user_prefix) < 0)
|
763
|
+
{
|
764
|
+
return EIO;
|
765
|
+
}
|
766
|
+
if (print_version(file, LOG_VERSION) < 0)
|
767
|
+
{
|
768
|
+
return EIO;
|
769
|
+
}
|
770
|
+
if (print_time(file, timestamp) < 0)
|
771
|
+
{
|
772
|
+
return EIO;
|
773
|
+
}
|
774
|
+
if (print_header(file) < 0)
|
775
|
+
{
|
776
|
+
return EIO;
|
777
|
+
}
|
778
|
+
|
779
|
+
return 0;
|
780
|
+
}
|
781
|
+
|
782
|
+
int hdr_log_write(
|
783
|
+
struct hdr_log_writer* writer,
|
784
|
+
FILE* file,
|
785
|
+
const hdr_timespec* start_timestamp,
|
786
|
+
const hdr_timespec* end_timestamp,
|
787
|
+
struct hdr_histogram* histogram)
|
788
|
+
{
|
789
|
+
uint8_t* compressed_histogram = NULL;
|
790
|
+
size_t compressed_len = 0;
|
791
|
+
char* encoded_histogram = NULL;
|
792
|
+
int rc = 0;
|
793
|
+
int result = 0;
|
794
|
+
size_t encoded_len;
|
795
|
+
|
796
|
+
(void)writer;
|
797
|
+
|
798
|
+
rc = hdr_encode_compressed(histogram, &compressed_histogram, &compressed_len);
|
799
|
+
if (rc != 0)
|
800
|
+
{
|
801
|
+
FAIL_AND_CLEANUP(cleanup, result, rc);
|
802
|
+
}
|
803
|
+
|
804
|
+
encoded_len = hdr_base64_encoded_len(compressed_len);
|
805
|
+
encoded_histogram = (char*) hdr_calloc(encoded_len + 1, sizeof(char));
|
806
|
+
|
807
|
+
rc = hdr_base64_encode(
|
808
|
+
compressed_histogram, compressed_len, encoded_histogram, encoded_len);
|
809
|
+
if (rc != 0)
|
810
|
+
{
|
811
|
+
FAIL_AND_CLEANUP(cleanup, result, rc);
|
812
|
+
}
|
813
|
+
|
814
|
+
if (fprintf(
|
815
|
+
file, "%.3f,%.3f,%" PRIu64 ".0,%s\n",
|
816
|
+
hdr_timespec_as_double(start_timestamp),
|
817
|
+
hdr_timespec_as_double(end_timestamp),
|
818
|
+
hdr_max(histogram),
|
819
|
+
encoded_histogram) < 0)
|
820
|
+
{
|
821
|
+
result = EIO;
|
822
|
+
}
|
823
|
+
|
824
|
+
cleanup:
|
825
|
+
hdr_free(compressed_histogram);
|
826
|
+
hdr_free(encoded_histogram);
|
827
|
+
|
828
|
+
return result;
|
829
|
+
}
|
830
|
+
|
831
|
+
int hdr_log_write_entry(
|
832
|
+
struct hdr_log_writer* writer,
|
833
|
+
FILE* file,
|
834
|
+
struct hdr_log_entry* entry,
|
835
|
+
struct hdr_histogram* histogram)
|
836
|
+
{
|
837
|
+
uint8_t* compressed_histogram = NULL;
|
838
|
+
size_t compressed_len = 0;
|
839
|
+
char* encoded_histogram = NULL;
|
840
|
+
int rc = 0;
|
841
|
+
int result = 0;
|
842
|
+
size_t encoded_len;
|
843
|
+
int has_tag = 0;
|
844
|
+
const char* tag_prefix;
|
845
|
+
const char* tag_value;
|
846
|
+
const char* tag_separator;
|
847
|
+
|
848
|
+
(void)writer;
|
849
|
+
|
850
|
+
rc = hdr_encode_compressed(histogram, &compressed_histogram, &compressed_len);
|
851
|
+
if (rc != 0)
|
852
|
+
{
|
853
|
+
FAIL_AND_CLEANUP(cleanup, result, rc);
|
854
|
+
}
|
855
|
+
|
856
|
+
encoded_len = hdr_base64_encoded_len(compressed_len);
|
857
|
+
encoded_histogram = (char*) hdr_calloc(encoded_len + 1, sizeof(char));
|
858
|
+
|
859
|
+
rc = hdr_base64_encode(
|
860
|
+
compressed_histogram, compressed_len, encoded_histogram, encoded_len);
|
861
|
+
if (rc != 0)
|
862
|
+
{
|
863
|
+
FAIL_AND_CLEANUP(cleanup, result, rc);
|
864
|
+
}
|
865
|
+
|
866
|
+
has_tag = NULL != entry->tag && 0 < entry->tag_len;
|
867
|
+
tag_prefix = has_tag ? "Tag=" : "";
|
868
|
+
tag_value = has_tag ? entry->tag : "";
|
869
|
+
tag_separator = has_tag ? "," : "";
|
870
|
+
|
871
|
+
if (fprintf(
|
872
|
+
file, "%s%.*s%s%.3f,%.3f,%" PRIu64 ".0,%s\n",
|
873
|
+
tag_prefix, (int) entry->tag_len, tag_value, tag_separator,
|
874
|
+
hdr_timespec_as_double(&entry->start_timestamp),
|
875
|
+
hdr_timespec_as_double(&entry->interval),
|
876
|
+
hdr_max(histogram),
|
877
|
+
encoded_histogram) < 0)
|
878
|
+
{
|
879
|
+
result = EIO;
|
880
|
+
}
|
881
|
+
|
882
|
+
cleanup:
|
883
|
+
hdr_free(compressed_histogram);
|
884
|
+
hdr_free(encoded_histogram);
|
885
|
+
|
886
|
+
return result;
|
887
|
+
}
|
888
|
+
|
889
|
+
/* ######## ######## ### ######## ######## ######## */
|
890
|
+
/* ## ## ## ## ## ## ## ## ## ## */
|
891
|
+
/* ## ## ## ## ## ## ## ## ## ## */
|
892
|
+
/* ######## ###### ## ## ## ## ###### ######## */
|
893
|
+
/* ## ## ## ######### ## ## ## ## ## */
|
894
|
+
/* ## ## ## ## ## ## ## ## ## ## */
|
895
|
+
/* ## ## ######## ## ## ######## ######## ## ## */
|
896
|
+
|
897
|
+
int hdr_log_reader_init(struct hdr_log_reader* reader)
|
898
|
+
{
|
899
|
+
reader->major_version = 0;
|
900
|
+
reader->minor_version = 0;
|
901
|
+
reader->start_timestamp.tv_sec = 0;
|
902
|
+
reader->start_timestamp.tv_nsec = 0;
|
903
|
+
|
904
|
+
return 0;
|
905
|
+
}
|
906
|
+
|
907
|
+
static void scan_log_format(struct hdr_log_reader* reader, const char* line)
|
908
|
+
{
|
909
|
+
const char* format = "#[Histogram log format version %d.%d]";
|
910
|
+
sscanf(line, format, &reader->major_version, &reader->minor_version);
|
911
|
+
}
|
912
|
+
|
913
|
+
static void scan_start_time(struct hdr_log_reader* reader, const char* line)
|
914
|
+
{
|
915
|
+
const char* format = "#[StartTime: %lf [^\n]";
|
916
|
+
double timestamp = 0.0;
|
917
|
+
|
918
|
+
if (sscanf(line, format, ×tamp) == 1)
|
919
|
+
{
|
920
|
+
hdr_timespec_from_double(&reader->start_timestamp, timestamp);
|
921
|
+
}
|
922
|
+
}
|
923
|
+
|
924
|
+
static void scan_header_line(struct hdr_log_reader* reader, const char* line)
|
925
|
+
{
|
926
|
+
scan_log_format(reader, line);
|
927
|
+
scan_start_time(reader, line);
|
928
|
+
}
|
929
|
+
|
930
|
+
static bool validate_log_version(struct hdr_log_reader* reader)
|
931
|
+
{
|
932
|
+
return reader->major_version == LOG_MAJOR_VERSION &&
|
933
|
+
(reader->minor_version == 0 || reader->minor_version == 1 ||
|
934
|
+
reader->minor_version == 2 || reader->minor_version == 3);
|
935
|
+
}
|
936
|
+
|
937
|
+
#define HEADER_LINE_LENGTH 128
|
938
|
+
|
939
|
+
int hdr_log_read_header(struct hdr_log_reader* reader, FILE* file)
|
940
|
+
{
|
941
|
+
char line[HEADER_LINE_LENGTH]; /* TODO: check for overflow. */
|
942
|
+
|
943
|
+
bool parsing_header = true;
|
944
|
+
|
945
|
+
do
|
946
|
+
{
|
947
|
+
int c = fgetc(file);
|
948
|
+
ungetc(c, file);
|
949
|
+
|
950
|
+
switch (c)
|
951
|
+
{
|
952
|
+
|
953
|
+
case '#':
|
954
|
+
if (fgets(line, HEADER_LINE_LENGTH, file) == NULL)
|
955
|
+
{
|
956
|
+
return EIO;
|
957
|
+
}
|
958
|
+
|
959
|
+
scan_header_line(reader, line);
|
960
|
+
break;
|
961
|
+
|
962
|
+
case '"':
|
963
|
+
if (fgets(line, HEADER_LINE_LENGTH, file) == NULL)
|
964
|
+
{
|
965
|
+
return EIO;
|
966
|
+
}
|
967
|
+
|
968
|
+
parsing_header = false;
|
969
|
+
break;
|
970
|
+
|
971
|
+
default:
|
972
|
+
parsing_header = false;
|
973
|
+
}
|
974
|
+
}
|
975
|
+
while (parsing_header);
|
976
|
+
|
977
|
+
if (!validate_log_version(reader))
|
978
|
+
{
|
979
|
+
return HDR_LOG_INVALID_VERSION;
|
980
|
+
}
|
981
|
+
|
982
|
+
return 0;
|
983
|
+
}
|
984
|
+
|
985
|
+
int hdr_log_read(
|
986
|
+
struct hdr_log_reader* reader, FILE* file, struct hdr_histogram** histogram,
|
987
|
+
hdr_timespec* timestamp, hdr_timespec* interval)
|
988
|
+
{
|
989
|
+
int result;
|
990
|
+
struct hdr_log_entry log_entry;
|
991
|
+
memset(&log_entry, 0, sizeof(log_entry));
|
992
|
+
|
993
|
+
result = hdr_log_read_entry(reader, file, &log_entry, histogram);
|
994
|
+
|
995
|
+
if (0 == result)
|
996
|
+
{
|
997
|
+
if (NULL != timestamp)
|
998
|
+
{
|
999
|
+
memcpy(timestamp, &log_entry.start_timestamp, sizeof(*timestamp));
|
1000
|
+
}
|
1001
|
+
if (NULL != interval)
|
1002
|
+
{
|
1003
|
+
memcpy(interval, &log_entry.interval, sizeof(*interval));
|
1004
|
+
}
|
1005
|
+
}
|
1006
|
+
|
1007
|
+
return result;
|
1008
|
+
}
|
1009
|
+
|
1010
|
+
static int read_ahead(FILE* f, const char* prefix, size_t prefix_len)
|
1011
|
+
{
|
1012
|
+
size_t i;
|
1013
|
+
for (i = 0; i < prefix_len; i++)
|
1014
|
+
{
|
1015
|
+
if (prefix[i] != fgetc(f))
|
1016
|
+
{
|
1017
|
+
return 0;
|
1018
|
+
}
|
1019
|
+
}
|
1020
|
+
|
1021
|
+
return 1;
|
1022
|
+
}
|
1023
|
+
|
1024
|
+
static int read_ahead_timestamp(FILE* f, hdr_timespec* timestamp, char expected_terminator)
|
1025
|
+
{
|
1026
|
+
int c;
|
1027
|
+
int is_seconds = 1;
|
1028
|
+
long sec = 0;
|
1029
|
+
long nsec = 0;
|
1030
|
+
long nsec_multipler = 1000000000;
|
1031
|
+
|
1032
|
+
while (EOF != (c = fgetc(f)))
|
1033
|
+
{
|
1034
|
+
if (expected_terminator == c)
|
1035
|
+
{
|
1036
|
+
timestamp->tv_sec = sec;
|
1037
|
+
timestamp->tv_nsec = (nsec * nsec_multipler);
|
1038
|
+
return 1;
|
1039
|
+
}
|
1040
|
+
else if ('.' == c)
|
1041
|
+
{
|
1042
|
+
is_seconds = 0;
|
1043
|
+
}
|
1044
|
+
else if ('0' <= c && c <= '9')
|
1045
|
+
{
|
1046
|
+
if (is_seconds)
|
1047
|
+
{
|
1048
|
+
sec = (sec * 10) + (c - '0');
|
1049
|
+
}
|
1050
|
+
else
|
1051
|
+
{
|
1052
|
+
nsec = (nsec * 10) + (c - '0');
|
1053
|
+
nsec_multipler /= 10;
|
1054
|
+
}
|
1055
|
+
}
|
1056
|
+
else
|
1057
|
+
{
|
1058
|
+
return 0;
|
1059
|
+
}
|
1060
|
+
}
|
1061
|
+
|
1062
|
+
return 0;
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
enum parse_log_state {
|
1066
|
+
INIT, TAG, BEGIN_TIMESTAMP, INTERVAL, MAX, HISTOGRAM, DONE
|
1067
|
+
};
|
1068
|
+
|
1069
|
+
int hdr_log_read_entry(
|
1070
|
+
struct hdr_log_reader* reader, FILE* file, struct hdr_log_entry *entry, struct hdr_histogram** histogram)
|
1071
|
+
{
|
1072
|
+
enum parse_log_state state = INIT;
|
1073
|
+
size_t capacity = 1024;
|
1074
|
+
size_t base64_len = 0;
|
1075
|
+
size_t tag_offset = 0;
|
1076
|
+
char* base64_histogram = hdr_calloc(capacity, sizeof(char));
|
1077
|
+
size_t compressed_len = 0;
|
1078
|
+
uint8_t* compressed_histogram = NULL;
|
1079
|
+
int result = -EINVAL;
|
1080
|
+
|
1081
|
+
(void)reader;
|
1082
|
+
|
1083
|
+
if (NULL == entry)
|
1084
|
+
{
|
1085
|
+
return -EINVAL;
|
1086
|
+
}
|
1087
|
+
|
1088
|
+
do
|
1089
|
+
{
|
1090
|
+
int c;
|
1091
|
+
|
1092
|
+
switch (state)
|
1093
|
+
{
|
1094
|
+
case INIT:
|
1095
|
+
c = fgetc(file);
|
1096
|
+
if ('T' == c)
|
1097
|
+
{
|
1098
|
+
if (read_ahead(file, "ag=", 3))
|
1099
|
+
{
|
1100
|
+
state = TAG;
|
1101
|
+
}
|
1102
|
+
else
|
1103
|
+
{
|
1104
|
+
FAIL_AND_CLEANUP(cleanup, result, -EINVAL);
|
1105
|
+
}
|
1106
|
+
}
|
1107
|
+
else if ('0' <= c && c <= '9')
|
1108
|
+
{
|
1109
|
+
ungetc(c, file);
|
1110
|
+
state = BEGIN_TIMESTAMP;
|
1111
|
+
}
|
1112
|
+
else if ('\r' == c || '\n' == c)
|
1113
|
+
{
|
1114
|
+
/* Skip over trailing/preceding new lines. */
|
1115
|
+
}
|
1116
|
+
else if (EOF == c)
|
1117
|
+
{
|
1118
|
+
FAIL_AND_CLEANUP(cleanup, result, EOF);
|
1119
|
+
}
|
1120
|
+
else
|
1121
|
+
{
|
1122
|
+
FAIL_AND_CLEANUP(cleanup, result, -EINVAL);
|
1123
|
+
}
|
1124
|
+
break;
|
1125
|
+
case TAG:
|
1126
|
+
c = fgetc(file);
|
1127
|
+
if (',' == c)
|
1128
|
+
{
|
1129
|
+
if (NULL != entry->tag && tag_offset < entry->tag_len)
|
1130
|
+
{
|
1131
|
+
entry->tag[tag_offset] = '\0';
|
1132
|
+
}
|
1133
|
+
state = BEGIN_TIMESTAMP;
|
1134
|
+
}
|
1135
|
+
else if ('\r' == c || '\n' == c || EOF == c)
|
1136
|
+
{
|
1137
|
+
FAIL_AND_CLEANUP(cleanup, result, -EINVAL);
|
1138
|
+
}
|
1139
|
+
else
|
1140
|
+
{
|
1141
|
+
if (NULL != entry->tag && tag_offset < entry->tag_len)
|
1142
|
+
{
|
1143
|
+
entry->tag[tag_offset] = (char) c;
|
1144
|
+
tag_offset++;
|
1145
|
+
}
|
1146
|
+
}
|
1147
|
+
break;
|
1148
|
+
case BEGIN_TIMESTAMP:
|
1149
|
+
if (read_ahead_timestamp(file, &entry->start_timestamp, ','))
|
1150
|
+
{
|
1151
|
+
state = INTERVAL;
|
1152
|
+
}
|
1153
|
+
else
|
1154
|
+
{
|
1155
|
+
FAIL_AND_CLEANUP(cleanup, result, -EINVAL);
|
1156
|
+
}
|
1157
|
+
break;
|
1158
|
+
case INTERVAL:
|
1159
|
+
if (read_ahead_timestamp(file, &entry->interval, ','))
|
1160
|
+
{
|
1161
|
+
state = MAX;
|
1162
|
+
}
|
1163
|
+
else
|
1164
|
+
{
|
1165
|
+
FAIL_AND_CLEANUP(cleanup, result, -EINVAL);
|
1166
|
+
}
|
1167
|
+
break;
|
1168
|
+
case MAX:
|
1169
|
+
if (read_ahead_timestamp(file, &entry->max, ','))
|
1170
|
+
{
|
1171
|
+
state = HISTOGRAM;
|
1172
|
+
}
|
1173
|
+
else
|
1174
|
+
{
|
1175
|
+
FAIL_AND_CLEANUP(cleanup, result, -EINVAL);
|
1176
|
+
}
|
1177
|
+
break;
|
1178
|
+
case HISTOGRAM:
|
1179
|
+
c = fgetc(file);
|
1180
|
+
if (c != '\r' && c != '\n' && c != EOF)
|
1181
|
+
{
|
1182
|
+
if (base64_len == capacity)
|
1183
|
+
{
|
1184
|
+
capacity *= 2;
|
1185
|
+
base64_histogram = hdr_realloc(base64_histogram, capacity * sizeof(char));
|
1186
|
+
if (NULL == base64_histogram)
|
1187
|
+
{
|
1188
|
+
FAIL_AND_CLEANUP(cleanup, result, -ENOMEM);
|
1189
|
+
}
|
1190
|
+
}
|
1191
|
+
base64_histogram[base64_len++] = (char) c;
|
1192
|
+
}
|
1193
|
+
else
|
1194
|
+
{
|
1195
|
+
state = DONE;
|
1196
|
+
}
|
1197
|
+
break;
|
1198
|
+
|
1199
|
+
default:
|
1200
|
+
FAIL_AND_CLEANUP(cleanup, result, -EINVAL);
|
1201
|
+
}
|
1202
|
+
}
|
1203
|
+
while (DONE != state);
|
1204
|
+
|
1205
|
+
compressed_histogram = hdr_calloc(base64_len, sizeof(uint8_t));
|
1206
|
+
compressed_len = hdr_base64_decoded_len(base64_len);
|
1207
|
+
|
1208
|
+
result = hdr_base64_decode(
|
1209
|
+
base64_histogram, base64_len, compressed_histogram, compressed_len);
|
1210
|
+
if (result != 0)
|
1211
|
+
{
|
1212
|
+
goto cleanup;
|
1213
|
+
}
|
1214
|
+
|
1215
|
+
result = hdr_decode_compressed(compressed_histogram, compressed_len, histogram);
|
1216
|
+
|
1217
|
+
cleanup:
|
1218
|
+
hdr_free(base64_histogram);
|
1219
|
+
hdr_free(compressed_histogram);
|
1220
|
+
return result;
|
1221
|
+
}
|
1222
|
+
|
1223
|
+
|
1224
|
+
int hdr_log_encode(struct hdr_histogram* histogram, char** encoded_histogram)
|
1225
|
+
{
|
1226
|
+
char *encoded_histogram_tmp = NULL;
|
1227
|
+
uint8_t* compressed_histogram = NULL;
|
1228
|
+
size_t compressed_len = 0;
|
1229
|
+
int rc = 0;
|
1230
|
+
int result = 0;
|
1231
|
+
size_t encoded_len;
|
1232
|
+
|
1233
|
+
rc = hdr_encode_compressed(histogram, &compressed_histogram, &compressed_len);
|
1234
|
+
if (rc != 0)
|
1235
|
+
{
|
1236
|
+
FAIL_AND_CLEANUP(cleanup, result, rc);
|
1237
|
+
}
|
1238
|
+
|
1239
|
+
encoded_len = hdr_base64_encoded_len(compressed_len);
|
1240
|
+
encoded_histogram_tmp = (char*) hdr_calloc(encoded_len + 1, sizeof(char));
|
1241
|
+
|
1242
|
+
rc = hdr_base64_encode(
|
1243
|
+
compressed_histogram, compressed_len, encoded_histogram_tmp, encoded_len);
|
1244
|
+
if (rc != 0)
|
1245
|
+
{
|
1246
|
+
hdr_free(encoded_histogram_tmp);
|
1247
|
+
FAIL_AND_CLEANUP(cleanup, result, rc);
|
1248
|
+
}
|
1249
|
+
|
1250
|
+
*encoded_histogram = encoded_histogram_tmp;
|
1251
|
+
|
1252
|
+
cleanup:
|
1253
|
+
hdr_free(compressed_histogram);
|
1254
|
+
|
1255
|
+
return result;
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
int hdr_log_decode(struct hdr_histogram** histogram, char* base64_histogram, size_t base64_len)
|
1259
|
+
{
|
1260
|
+
int r;
|
1261
|
+
uint8_t* compressed_histogram = NULL;
|
1262
|
+
int result = 0;
|
1263
|
+
|
1264
|
+
size_t compressed_len = hdr_base64_decoded_len(base64_len);
|
1265
|
+
compressed_histogram = (uint8_t*) hdr_malloc(sizeof(uint8_t)*compressed_len);
|
1266
|
+
memset(compressed_histogram, 0, compressed_len);
|
1267
|
+
|
1268
|
+
r = hdr_base64_decode(
|
1269
|
+
base64_histogram, base64_len, compressed_histogram, compressed_len);
|
1270
|
+
|
1271
|
+
if (r != 0)
|
1272
|
+
{
|
1273
|
+
FAIL_AND_CLEANUP(cleanup, result, r);
|
1274
|
+
}
|
1275
|
+
|
1276
|
+
r = hdr_decode_compressed(compressed_histogram, compressed_len, histogram);
|
1277
|
+
if (r != 0)
|
1278
|
+
{
|
1279
|
+
FAIL_AND_CLEANUP(cleanup, result, r);
|
1280
|
+
}
|
1281
|
+
|
1282
|
+
cleanup:
|
1283
|
+
hdr_free(compressed_histogram);
|
1284
|
+
|
1285
|
+
return result;
|
1286
|
+
}
|
1287
|
+
|
1288
|
+
#if defined(_MSC_VER)
|
1289
|
+
#pragma warning(pop)
|
1290
|
+
#endif
|