Skip to content

Commit

Permalink
Move serialized dictionary feature behind the flag.
Browse files Browse the repository at this point in the history
BROTLI_SHARED_DICTIONARY_SERIALIZED enum value is a part of API,
but it should not be used (will cause failures).
Changing how serialized dictionaries work won't be considered as an API change, until this feature is enabled.
Enabling this feature in the future will be considered as a "compatible" change.

PiperOrigin-RevId: 558091676
  • Loading branch information
eustas authored and copybara-github committed Aug 18, 2023
1 parent 0f2157c commit 3ebb2d3
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 9 deletions.
12 changes: 9 additions & 3 deletions c/common/shared_dictionary.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
extern "C" {
#endif

#if defined(BROTLI_EXPERIMENTAL)

#define BROTLI_NUM_ENCODED_LENGTHS (SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH \
- SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH + 1)

Expand Down Expand Up @@ -442,6 +444,8 @@ static BROTLI_BOOL DecodeSharedDictionary(
return ParseDictionary(encoded, size, dict);
}

#endif /* BROTLI_EXPERIMENTAL */

void BrotliSharedDictionaryDestroyInstance(
BrotliSharedDictionary* dict) {
if (!dict) {
Expand All @@ -464,19 +468,21 @@ BROTLI_BOOL BrotliSharedDictionaryAttach(
if (!dict) {
return BROTLI_FALSE;
}
#if defined(BROTLI_EXPERIMENTAL)
if (type == BROTLI_SHARED_DICTIONARY_SERIALIZED) {
return DecodeSharedDictionary(data, data_size, dict);
} else if (type == BROTLI_SHARED_DICTIONARY_RAW) {
}
#endif /* BROTLI_EXPERIMENTAL */
if (type == BROTLI_SHARED_DICTIONARY_RAW) {
if (dict->num_prefix >= SHARED_BROTLI_MAX_COMPOUND_DICTS) {
return BROTLI_FALSE;
}
dict->prefix_size[dict->num_prefix] = data_size;
dict->prefix[dict->num_prefix] = data;
dict->num_prefix++;
return BROTLI_TRUE;
} else {
return BROTLI_FALSE;
}
return BROTLI_FALSE;
}

BrotliSharedDictionary* BrotliSharedDictionaryCreateInstance(
Expand Down
17 changes: 14 additions & 3 deletions c/enc/encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
/* Implementation of Brotli compressor. */

#include <brotli/encode.h>
#include <brotli/shared_dictionary.h>
#include <brotli/types.h>

#include <stdlib.h> /* free, malloc */
#include <string.h> /* memcpy, memset */
Expand Down Expand Up @@ -1707,8 +1709,12 @@ BrotliEncoderPreparedDictionary* BrotliEncoderPrepareDictionary(
const uint8_t data[BROTLI_ARRAY_PARAM(size)], int quality,
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
ManagedDictionary* managed_dictionary = NULL;
if (type != BROTLI_SHARED_DICTIONARY_RAW &&
type != BROTLI_SHARED_DICTIONARY_SERIALIZED) {
BROTLI_BOOL type_is_known = BROTLI_FALSE;
type_is_known |= (type == BROTLI_SHARED_DICTIONARY_RAW);
#if defined(BROTLI_EXPERIMENTAL)
type_is_known |= (type == BROTLI_SHARED_DICTIONARY_SERIALIZED);
#endif /* BROTLI_EXPERIMENTAL */
if (!type_is_known) {
return NULL;
}
managed_dictionary =
Expand All @@ -1719,7 +1725,9 @@ BrotliEncoderPreparedDictionary* BrotliEncoderPrepareDictionary(
if (type == BROTLI_SHARED_DICTIONARY_RAW) {
managed_dictionary->dictionary = (uint32_t*)CreatePreparedDictionary(
&managed_dictionary->memory_manager_, data, size);
} else {
}
#if defined(BROTLI_EXPERIMENTAL)
if (type == BROTLI_SHARED_DICTIONARY_SERIALIZED) {
SharedEncoderDictionary* dict = (SharedEncoderDictionary*)BrotliAllocate(
&managed_dictionary->memory_manager_, sizeof(SharedEncoderDictionary));
managed_dictionary->dictionary = (uint32_t*)dict;
Expand All @@ -1732,6 +1740,9 @@ BrotliEncoderPreparedDictionary* BrotliEncoderPrepareDictionary(
}
}
}
#else /* BROTLI_EXPERIMENTAL */
(void)quality;
#endif /* BROTLI_EXPERIMENTAL */
if (managed_dictionary->dictionary == NULL) {
BrotliDestroyManagedDictionary(managed_dictionary);
return NULL;
Expand Down
4 changes: 4 additions & 0 deletions c/enc/encoder_dict.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ static void BrotliDestroyEncoderDictionary(MemoryManager* m,
BrotliTrieFree(m, &dict->trie);
}

#if defined(BROTLI_EXPERIMENTAL)
/* Word length must be at least 4 bytes */
static uint32_t Hash(const uint8_t* data, int bits) {
uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32;
Expand Down Expand Up @@ -481,6 +482,7 @@ static BROTLI_BOOL ComputeDictionary(MemoryManager* m, int quality,

return BROTLI_TRUE;
}
#endif /* BROTLI_EXPERIMENTAL */

void BrotliInitSharedEncoderDictionary(SharedEncoderDictionary* dict) {
dict->magic = kSharedDictionaryMagic;
Expand All @@ -501,6 +503,7 @@ void BrotliInitSharedEncoderDictionary(SharedEncoderDictionary* dict) {
dict->max_quality = BROTLI_MAX_QUALITY;
}

#if defined(BROTLI_EXPERIMENTAL)
/* TODO(eustas): make sure that tooling will warn user if not all the cutoff
transforms are available (for low-quality encoder). */
static BROTLI_BOOL InitCustomSharedEncoderDictionary(
Expand Down Expand Up @@ -586,6 +589,7 @@ BROTLI_BOOL BrotliInitCustomSharedEncoderDictionary(
BrotliSharedDictionaryDestroyInstance(decoded_dict);
return success;
}
#endif /* BROTLI_EXPERIMENTAL */

void BrotliCleanupSharedEncoderDictionary(MemoryManager* m,
SharedEncoderDictionary* dict) {
Expand Down
5 changes: 5 additions & 0 deletions c/enc/encoder_dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ typedef struct BrotliTrie {
BrotliTrieNode root;
} BrotliTrie;

#if defined(BROTLI_EXPERIMENTAL)
BROTLI_INTERNAL const BrotliTrieNode* BrotliTrieSub(const BrotliTrie* trie,
const BrotliTrieNode* node, uint8_t c);
#endif /* BROTLI_EXPERIMENTAL */

/* Dictionary data (words and transforms) for 1 possible context */
typedef struct BrotliEncoderDictionary {
const BrotliDictionary* words;
Expand Down Expand Up @@ -129,12 +132,14 @@ typedef struct ManagedDictionary {
BROTLI_INTERNAL void BrotliInitSharedEncoderDictionary(
SharedEncoderDictionary* dict);

#if defined(BROTLI_EXPERIMENTAL)
/* Initializes to shared dictionary that will be parsed from
encoded_dict. Requires that you keep the encoded_dict buffer
around, parts of data will point to it. */
BROTLI_INTERNAL BROTLI_BOOL BrotliInitCustomSharedEncoderDictionary(
MemoryManager* m, const uint8_t* encoded_dict, size_t size,
int quality, SharedEncoderDictionary* dict);
#endif /* BROTLI_EXPERIMENTAL */

BROTLI_INTERNAL void BrotliCleanupSharedEncoderDictionary(
MemoryManager* m, SharedEncoderDictionary* dict);
Expand Down
5 changes: 4 additions & 1 deletion c/enc/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
extern "C" {
#endif

#define MAX_PERM_ALLOCATED 128
/* TODO(eustas): fine-tune for "many slots" case */
#define MAX_NEW_ALLOCATED 64
#define MAX_NEW_FREED 64
#define MAX_PERM_ALLOCATED \
(BROTLI_ENCODER_MEMORY_MANAGER_SLOTS - MAX_NEW_ALLOCATED - MAX_NEW_FREED)

#define PERM_ALLOCATED_OFFSET 0
#define NEW_ALLOCATED_OFFSET MAX_PERM_ALLOCATED
Expand Down Expand Up @@ -68,6 +70,7 @@ void BrotliWipeOutMemoryManager(MemoryManager* m) {

static void SortPointers(void** items, const size_t n) {
/* Shell sort. */
/* TODO(eustas): fine-tune for "many slots" case */
static const size_t gaps[] = {23, 10, 4, 1};
int g = 0;
for (; g < 4; ++g) {
Expand Down
10 changes: 9 additions & 1 deletion c/enc/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ extern "C" {
#define BROTLI_ENCODER_EXIT_ON_OOM
#endif

#if !defined(BROTLI_ENCODER_EXIT_ON_OOM)
#if defined(BROTLI_EXPERIMENTAL)
#define BROTLI_ENCODER_MEMORY_MANAGER_SLOTS 6144
#else /* BROTLI_EXPERIMENTAL */
#define BROTLI_ENCODER_MEMORY_MANAGER_SLOTS 256
#endif /* BROTLI_EXPERIMENTAL */
#endif /* BROTLI_ENCODER_EXIT_ON_OOM */

typedef struct MemoryManager {
brotli_alloc_func alloc_func;
brotli_free_func free_func;
Expand All @@ -33,7 +41,7 @@ typedef struct MemoryManager {
size_t perm_allocated;
size_t new_allocated;
size_t new_freed;
void* pointers[256];
void* pointers[BROTLI_ENCODER_MEMORY_MANAGER_SLOTS];
#endif /* BROTLI_ENCODER_EXIT_ON_OOM */
} MemoryManager;

Expand Down
2 changes: 2 additions & 0 deletions c/enc/static_dict.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ static BROTLI_BOOL BrotliFindAllStaticDictionaryMatchesFor(
const BrotliEncoderDictionary* dictionary, const uint8_t* data,
size_t min_length, size_t max_length, uint32_t* matches) {
BROTLI_BOOL has_found_match = BROTLI_FALSE;
#if defined(BROTLI_EXPERIMENTAL)
if (dictionary->has_words_heavy) {
const BrotliTrieNode* node = &dictionary->trie.root;
size_t l = 0;
Expand All @@ -93,6 +94,7 @@ static BROTLI_BOOL BrotliFindAllStaticDictionaryMatchesFor(
}
return has_found_match;
}
#endif /* BROTLI_EXPERIMENTAL */
{
size_t offset = dictionary->buckets[Hash(data)];
BROTLI_BOOL end = !offset;
Expand Down
5 changes: 4 additions & 1 deletion c/include/brotli/shared_dictionary.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ typedef struct BrotliSharedDictionaryStruct BrotliSharedDictionary;
typedef enum BrotliSharedDictionaryType {
/** Raw LZ77 prefix dictionary. */
BROTLI_SHARED_DICTIONARY_RAW = 0,
/** Serialized shared dictionary. */
/** Serialized shared dictionary.
*
* DO NOT USE: methods accepting this value will fail.
*/
BROTLI_SHARED_DICTIONARY_SERIALIZED = 1
} BrotliSharedDictionaryType;

Expand Down

0 comments on commit 3ebb2d3

Please sign in to comment.