Skip to content

Commit 874a216

Browse files
authored
api option to deserialize fingerprints separately (#59)
the `binary_fuse(8|16)_deserialize_header` functions only deserialize the core struct fields, but do not `malloc` new memory for the Fingerprints nor do they set the Fingerprints pointer. This places memory control in the hands of the user, and facilitates use cases such as a memory mapped file. the existing `binary_fuse(8|16)_deserialize` functions are unaffected but call the new functions internally to avoid code duplication. resolves #58
1 parent 3c0fd15 commit 874a216

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

include/binaryfusefilter.h

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -784,12 +784,12 @@ static inline void binary_fuse8_serialize(const binary_fuse8_t *filter, char *bu
784784
memcpy(buffer, filter->Fingerprints, filter->ArrayLength * sizeof(uint8_t));
785785
}
786786

787-
// deserialize a filter from a buffer, returns true on success, false on failure.
788-
// The output will be reallocated, so the caller should call binary_fuse16_free(filter) before
789-
// if the filter was already allocated. The caller needs to call binary_fuse16_free(filter) after.
790-
// The number of bytes read is binary_fuse16_serialization_bytes(output).
791-
// Native endianess only.
792-
static inline bool binary_fuse16_deserialize(binary_fuse16_t * filter, const char *buffer) {
787+
// deserialize the main struct fields of a filter from a buffer, returns the buffer position
788+
// immediately after those fields. If you used binary_fuse16_seriliaze the return value will point at
789+
// the start of the `Fingerprints` array. Use this option if you want to allocate your own memory or
790+
// perhaps have the memory `mmap`ed to a file. Nothing is allocated. Do not call binary_fuse16_free
791+
// on the returned pointer. Native endianess only.
792+
static inline const char* binary_fuse16_deserialize_header(binary_fuse16_t* filter, const char* buffer) {
793793
memcpy(&filter->Seed, buffer, sizeof(filter->Seed));
794794
buffer += sizeof(filter->Seed);
795795
memcpy(&filter->SegmentLength, buffer, sizeof(filter->SegmentLength));
@@ -801,21 +801,30 @@ static inline bool binary_fuse16_deserialize(binary_fuse16_t * filter, const cha
801801
buffer += sizeof(filter->SegmentCountLength);
802802
memcpy(&filter->ArrayLength, buffer, sizeof(filter->ArrayLength));
803803
buffer += sizeof(filter->ArrayLength);
804+
return buffer;
805+
}
806+
807+
// deserialize a filter from a buffer, returns true on success, false on failure.
808+
// The output will be reallocated, so the caller should call binary_fuse16_free(filter) before
809+
// if the filter was already allocated. The caller needs to call binary_fuse16_free(filter) after.
810+
// The number of bytes read is binary_fuse16_serialization_bytes(output).
811+
// Native endianess only.
812+
static inline bool binary_fuse16_deserialize(binary_fuse16_t * filter, const char *buffer) {
813+
const char* fingerprints = binary_fuse16_deserialize_header(filter, buffer);
804814
filter->Fingerprints = (uint16_t*)malloc(filter->ArrayLength * sizeof(uint16_t));
805815
if(filter->Fingerprints == NULL) {
806816
return false;
807817
}
808-
memcpy(filter->Fingerprints, buffer, filter->ArrayLength * sizeof(uint16_t));
818+
memcpy(filter->Fingerprints, fingerprints, filter->ArrayLength * sizeof(uint16_t));
809819
return true;
810820
}
811821

812-
813-
// deserialize a filter from a buffer, returns true on success, false on failure.
814-
// The output will be reallocated, so the caller should call binary_fuse8_free(filter) before
815-
// if the filter was already allocated. The caller needs to call binary_fuse8_free(filter) after.
816-
// The number of bytes read is binary_fuse8_serialization_bytes(output).
817-
// Native endianess only.
818-
static inline bool binary_fuse8_deserialize(binary_fuse8_t * filter, const char *buffer) {
822+
// deserialize the main struct fields of a filter from a buffer, returns the buffer position
823+
// immediately after those fields. If you used binary_fuse8_seriliaze the return value will point at
824+
// the start of the `Fingerprints` array. Use this option if you want to allocate your own memory or
825+
// perhaps have the memory `mmap`ed to a file. Nothing is allocated. Do not call binary_fuse8_free
826+
// on the returned pointer. Native endianess only.
827+
static inline const char* binary_fuse8_deserialize_header(binary_fuse8_t* filter, const char* buffer) {
819828
memcpy(&filter->Seed, buffer, sizeof(filter->Seed));
820829
buffer += sizeof(filter->Seed);
821830
memcpy(&filter->SegmentLength, buffer, sizeof(filter->SegmentLength));
@@ -827,11 +836,21 @@ static inline bool binary_fuse8_deserialize(binary_fuse8_t * filter, const char
827836
buffer += sizeof(filter->SegmentCountLength);
828837
memcpy(&filter->ArrayLength, buffer, sizeof(filter->ArrayLength));
829838
buffer += sizeof(filter->ArrayLength);
839+
return buffer;
840+
}
841+
842+
// deserialize a filter from a buffer, returns true on success, false on failure.
843+
// The output will be reallocated, so the caller should call binary_fuse8_free(filter) before
844+
// if the filter was already allocated. The caller needs to call binary_fuse8_free(filter) after.
845+
// The number of bytes read is binary_fuse8_serialization_bytes(output).
846+
// Native endianess only.
847+
static inline bool binary_fuse8_deserialize(binary_fuse8_t * filter, const char *buffer) {
848+
const char* fingerprints = binary_fuse8_deserialize_header(filter, buffer);
830849
filter->Fingerprints = (uint8_t*)malloc(filter->ArrayLength * sizeof(uint8_t));
831850
if(filter->Fingerprints == NULL) {
832851
return false;
833852
}
834-
memcpy(filter->Fingerprints, buffer, filter->ArrayLength * sizeof(uint8_t));
853+
memcpy(filter->Fingerprints, fingerprints, filter->ArrayLength * sizeof(uint8_t));
835854
return true;
836855
}
837856

0 commit comments

Comments
 (0)