Skip to content

Commit e1060f4

Browse files
committed
Create packet_slab to ecapsulate simulated annealing system, create memory-optimized undo stack
1 parent d718a70 commit e1060f4

9 files changed

+268
-3
lines changed

src/packet_slab.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "packet_slab.h"
2+
#include "memory_mapper.h"
3+
#include <stdlib.h>
4+
5+
struct PacketSlab_struct {
6+
size_t data_size;
7+
LZMAPacket* packets;
8+
};
9+
10+
size_t packet_slab_memory_usage(size_t data_size)
11+
{
12+
return sizeof(LZMAPacket) * data_size + sizeof(PacketSlab);
13+
}
14+
15+
PacketSlab* packet_slab_new(size_t data_size)
16+
{
17+
PacketSlab* slab = malloc(sizeof(PacketSlab));
18+
if (slab == NULL) {
19+
return NULL;
20+
}
21+
slab->data_size = data_size;
22+
23+
uint8_t* packets;
24+
if (map_anonymous(sizeof(LZMAPacket) * data_size, &packets)) {
25+
free(slab);
26+
return NULL;
27+
}
28+
slab->packets = (LZMAPacket*)packets;
29+
30+
for (size_t i = 0; i < data_size; i++) {
31+
slab->packets[i] = literal_packet();
32+
}
33+
34+
return slab;
35+
}
36+
37+
void packet_slab_free(PacketSlab* slab)
38+
{
39+
unmap((uint8_t*) slab->packets, sizeof(LZMAPacket) * slab->data_size);
40+
free(slab);
41+
}
42+
43+
size_t packet_slab_size(const PacketSlab* slab)
44+
{
45+
return slab->data_size;
46+
}
47+
48+
LZMAPacket* packet_slab_packets(PacketSlab* slab)
49+
{
50+
return slab->packets;
51+
}

src/packet_slab.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
#include "lzma_packet.h"
3+
#include <stddef.h>
4+
5+
typedef struct PacketSlab_struct PacketSlab;
6+
7+
size_t packet_slab_memory_usage(size_t data_size);
8+
9+
PacketSlab* packet_slab_new(size_t data_size);
10+
void packet_slab_free(PacketSlab* slab);
11+
12+
size_t packet_slab_size(const PacketSlab* slab);
13+
LZMAPacket* packet_slab_packets(PacketSlab* slab);

src/packet_slab_undo_stack.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include "packet_slab_undo_stack.h"
2+
#include <stdlib.h>
3+
#include <assert.h>
4+
5+
struct PacketSlabUndoHeap_struct {
6+
size_t size;
7+
size_t count;
8+
PacketSlabUndo* heap;
9+
PacketSlabUndoHeap* prev;
10+
};
11+
12+
static PacketSlabUndoHeap* packet_slab_undo_heap_new(size_t size, PacketSlabUndoHeap* prev)
13+
{
14+
PacketSlabUndoHeap* undo_heap = malloc(sizeof(PacketSlabUndoHeap));
15+
if (undo_heap == NULL) {
16+
return NULL;
17+
}
18+
undo_heap->size = size;
19+
undo_heap->count = 0;
20+
undo_heap->prev = prev;
21+
undo_heap->heap = malloc(sizeof(PacketSlabUndo) * size);
22+
if (undo_heap->heap == NULL) {
23+
free(undo_heap);
24+
return NULL;
25+
}
26+
return undo_heap;
27+
}
28+
29+
static void packet_slab_undo_heap_free(PacketSlabUndoHeap* undo_heap)
30+
{
31+
free(undo_heap->heap);
32+
free(undo_heap);
33+
}
34+
35+
static void packet_slab_undo_heap_apply(PacketSlabUndoHeap* undo_heap, PacketSlab* slab)
36+
{
37+
LZMAPacket* packets = packet_slab_packets(slab);
38+
while (undo_heap->count > 0) {
39+
PacketSlabUndo undo = undo_heap->heap[--undo_heap->count];
40+
packets[undo.position] = undo.old_packet;
41+
}
42+
}
43+
44+
void packet_slab_undo_stack_new(PacketSlabUndoStack* undo_stack)
45+
{
46+
undo_stack->count = 0;
47+
undo_stack->last = NULL;
48+
}
49+
50+
void packet_slab_undo_stack_free(PacketSlabUndoStack* undo_stack)
51+
{
52+
while (undo_stack->last != NULL) {
53+
PacketSlabUndoHeap* undo_heap = undo_stack->last;
54+
undo_stack->last = undo_heap->prev;
55+
packet_slab_undo_heap_free(undo_heap);
56+
}
57+
}
58+
59+
void packet_slab_undo_stack_insert(PacketSlabUndoStack* undo_stack, PacketSlabUndo undo)
60+
{
61+
if (undo_stack->count < UNDO_STACK_SIZE) {
62+
undo_stack->stack[undo_stack->count++] = undo;
63+
return;
64+
}
65+
66+
if (undo_stack->last == NULL || undo_stack->last->size == undo_stack->last->count) {
67+
size_t next_size = UNDO_STACK_SIZE*2;
68+
if (undo_stack->last != NULL) {
69+
next_size = undo_stack->last->size*2;
70+
}
71+
PacketSlabUndoHeap* prev = undo_stack->last;
72+
undo_stack->last = packet_slab_undo_heap_new(next_size, prev);
73+
}
74+
75+
assert(undo_stack->last != NULL);
76+
77+
undo_stack->last->heap[undo_stack->last->count++] = undo;
78+
}
79+
80+
void packet_slab_undo_stack_apply(PacketSlabUndoStack* undo_stack, PacketSlab* slab)
81+
{
82+
while (undo_stack->last != NULL) {
83+
PacketSlabUndoHeap* undo_heap = undo_stack->last;
84+
undo_stack->last = undo_heap->prev;
85+
86+
packet_slab_undo_heap_apply(undo_heap, slab);
87+
packet_slab_undo_heap_free(undo_heap);
88+
}
89+
90+
LZMAPacket* packets = packet_slab_packets(slab);
91+
while (undo_stack->count > 0) {
92+
PacketSlabUndo undo = undo_stack->stack[--undo_stack->count];
93+
packets[undo.position] = undo.old_packet;
94+
}
95+
}

src/packet_slab_undo_stack.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
#include "lzma_state.h"
3+
#include "packet_slab.h"
4+
#include <stddef.h>
5+
6+
//todo: this explination sucks
7+
//this structure stores a list of undo states. this is generated by the slab neighbour generator and can be used to return to the last slab if it is not suitable
8+
9+
typedef struct {
10+
size_t position;
11+
LZMAPacket old_packet;
12+
} PacketSlabUndo;
13+
14+
typedef struct PacketSlabUndoHeap_struct PacketSlabUndoHeap;
15+
16+
#define UNDO_STACK_SIZE 32
17+
typedef struct {
18+
size_t count;
19+
PacketSlabUndo stack[UNDO_STACK_SIZE];
20+
PacketSlabUndoHeap* last;
21+
} PacketSlabUndoStack;
22+
23+
void packet_slab_undo_stack_new(PacketSlabUndoStack* undo_stack);
24+
void packet_slab_undo_stack_free(PacketSlabUndoStack* undo_stack);
25+
void packet_slab_undo_stack_insert(PacketSlabUndoStack* undo_stack, PacketSlabUndo undo);
26+
void packet_slab_undo_stack_apply(PacketSlabUndoStack* undo_stack, PacketSlab* slab);

src/substring_enumerator.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ size_t substring_enumerator_memory_usage(size_t data_size)
2323
return sizeof(size_t) * data_size + sizeof(SubstringEnumerator);
2424
}
2525

26-
void memoize_bigram_positions(SubstringEnumerator* em)
26+
static void memoize_bigram_positions(SubstringEnumerator* em)
2727
{
2828
const uint8_t* data = em->data;
2929
size_t data_size = em->data_size;

tests/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
#include "max_heap_test.h"
22
#include "substring_enumerator_test.h"
3+
#include "packet_slab_undo_stack_test.h"
34

45
int main(int argc, char** argv)
56
{
67
(void) argc; (void) argv;
78

89
substring_enumerator_test();
910
max_heap_test();
11+
packet_slab_undo_stack_test();
1012

1113
return 0;
1214
}

tests/packet_slab_undo_stack_test.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "packet_slab_undo_stack_test.h"
2+
#include "test_util.h"
3+
#include "../src/lzma_packet.h"
4+
#include "../src/packet_slab.h"
5+
#include "../src/packet_slab_undo_stack.h"
6+
7+
#define SLAB_SIZE 1024
8+
9+
static void packet_slab_undo_stack_test_apply()
10+
{
11+
PRETTY_PRINT_SUB_TEST_NAME();
12+
13+
fprintf(stderr, "allocating PacketSlab of size %ld\n", (size_t)SLAB_SIZE);
14+
PacketSlab* slab = packet_slab_new(SLAB_SIZE);
15+
16+
TEST_ASSERT(slab != NULL, "Could not allocate slab!");
17+
18+
PacketSlabUndoStack undo_stack;
19+
packet_slab_undo_stack_new(&undo_stack);
20+
21+
fprintf(stderr, "changing all packets to shortreps...\n");
22+
LZMAPacket* packets = packet_slab_packets(slab);
23+
for (size_t i = 0; i < SLAB_SIZE; i++) {
24+
PacketSlabUndo undo = { .position = i, .old_packet = packets[i] };
25+
packets[i] = short_rep_packet();
26+
packet_slab_undo_stack_insert(&undo_stack, undo);
27+
}
28+
fprintf(stderr, "undoing shortreps...\n");
29+
packet_slab_undo_stack_apply(&undo_stack, slab);
30+
for (size_t i = 0; i < SLAB_SIZE; i++) {
31+
TEST_ASSERT_EQ(packets[i].type, LITERAL, "Packet edit was not undone! expected: %d, got %d");
32+
}
33+
34+
fprintf(stderr, "freeing memory...\n");
35+
packet_slab_undo_stack_free(&undo_stack);
36+
packet_slab_free(slab);
37+
}
38+
39+
static void packet_slab_undo_stack_test_free()
40+
{
41+
PRETTY_PRINT_SUB_TEST_NAME();
42+
43+
fprintf(stderr, "allocating PacketSlab of size %ld\n", (size_t)SLAB_SIZE);
44+
PacketSlab* slab = packet_slab_new(SLAB_SIZE);
45+
46+
TEST_ASSERT(slab != NULL, "Could not allocate slab!");
47+
48+
PacketSlabUndoStack undo_stack;
49+
packet_slab_undo_stack_new(&undo_stack);
50+
51+
fprintf(stderr, "changing all packets to shortreps...\n");
52+
LZMAPacket* packets = packet_slab_packets(slab);
53+
for (size_t i = 0; i < SLAB_SIZE; i++) {
54+
PacketSlabUndo undo = { .position = i, .old_packet = packets[i] };
55+
packets[i] = short_rep_packet();
56+
packet_slab_undo_stack_insert(&undo_stack, undo);
57+
}
58+
fprintf(stderr, "not undoing shortreps...\n");
59+
for (size_t i = 0; i < SLAB_SIZE; i++) {
60+
TEST_ASSERT_EQ(packets[i].type, SHORT_REP, "Packet edit was not applied! expected: %d, got %d");
61+
}
62+
63+
fprintf(stderr, "freeing memory...\n");
64+
packet_slab_undo_stack_free(&undo_stack);
65+
packet_slab_free(slab);
66+
}
67+
68+
void packet_slab_undo_stack_test()
69+
{
70+
PRETTY_PRINT_TEST_NAME();
71+
72+
packet_slab_undo_stack_test_apply();
73+
packet_slab_undo_stack_test_free();
74+
}

tests/packet_slab_undo_stack_test.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
void packet_slab_undo_stack_test();

tests/test_util.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <stdio.h>
22
#include <stdlib.h>
3+
#include <assert.h>
34

45
#define PRETTY_PRINT_TEST_NAME() \
56
{ \
@@ -17,7 +18,7 @@
1718
fprintf(stderr, "ERROR: "); \
1819
fprintf(stderr, msg); \
1920
fprintf(stderr, "\n"); \
20-
exit(-1); \
21+
assert(0); \
2122
} \
2223
}
2324

@@ -29,6 +30,6 @@
2930
fprintf(stderr, "ERROR: "); \
3031
fprintf(stderr, msg, __EXPECT_STOR, __GOT_STOR); \
3132
fprintf(stderr, "\n"); \
32-
exit(-1); \
33+
assert(0); \
3334
} \
3435
}

0 commit comments

Comments
 (0)