Skip to content

Commit a1af52f

Browse files
committed
Reduce fragmentation by completely deleting old thoughts.
Signed-off-by: Katharine Berry <[email protected]>
1 parent 33e8028 commit a1af52f

File tree

4 files changed

+54
-7
lines changed

4 files changed

+54
-7
lines changed

app/src/c/converse/conversation.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,20 @@ struct ConversationEntry {
3434
struct Conversation {
3535
ConversationEntry* entries;
3636
int deleted_entries;
37+
int nulled_entries;
3738
int entry_count;
3839
int entry_allocated;
3940
char thread_id[37];
4041
};
4142

4243
static ConversationEntry* prv_create_entry(Conversation* conversation);
4344
void prv_destroy_entry(ConversationEntry *entry);
45+
const char* prv_type_to_string(EntryType type);
4446

4547
Conversation* conversation_create() {
4648
Conversation *conversation = bmalloc(sizeof(Conversation));
4749
conversation->deleted_entries = 0;
50+
conversation->nulled_entries = 0;
4851
conversation->entry_count = 0;
4952
conversation->entry_allocated = 30;
5053
conversation->entries = bmalloc(sizeof(ConversationEntry) * conversation->entry_allocated);
@@ -62,6 +65,9 @@ void conversation_destroy(Conversation* conversation) {
6265

6366
void prv_destroy_entry(ConversationEntry *entry) {
6467
switch (entry->type) {
68+
case EntryTypeDeleted:
69+
// Nothing to do here.
70+
break;
6571
case EntryTypePrompt:
6672
free(entry->content.prompt->prompt);
6773
free(entry->content.prompt);
@@ -132,6 +138,7 @@ void prv_destroy_entry(ConversationEntry *entry) {
132138
free(entry->content.widget);
133139
break;
134140
}
141+
entry->type = EntryTypeDeleted;
135142
}
136143

137144
static ConversationEntry* prv_create_entry(Conversation* conversation) {
@@ -141,6 +148,7 @@ static ConversationEntry* prv_create_entry(Conversation* conversation) {
141148
++conversation->entry_allocated;
142149
conversation->entries = new_entries;
143150
}
151+
memset(&conversation->entries[conversation->entry_count], 0, sizeof(ConversationEntry));
144152
return &conversation->entries[conversation->entry_count++];
145153
}
146154

@@ -261,10 +269,29 @@ void conversation_add_widget(Conversation* conversation, ConversationWidget* wid
261269
}
262270

263271
void conversation_delete_first_entry(Conversation* conversation) {
264-
prv_destroy_entry(&conversation->entries[conversation->deleted_entries]);
272+
ConversationEntry* entry = &conversation->entries[conversation->deleted_entries];
273+
while (entry->type == EntryTypeDeleted && conversation->deleted_entries < conversation->entry_count) {
274+
conversation->deleted_entries++;
275+
conversation->nulled_entries--;
276+
entry = &conversation->entries[conversation->deleted_entries];
277+
}
278+
prv_destroy_entry(entry);
265279
conversation->deleted_entries++;
266280
}
267281

282+
283+
void conversation_delete_last_thought(Conversation* conversation) {
284+
BOBBY_LOG(APP_LOG_LEVEL_DEBUG, "Deleting last thought");
285+
for (int i = conversation->entry_count - 2; i >= conversation->deleted_entries; --i) {
286+
ConversationEntry* entry = &conversation->entries[i];
287+
if (entry->type == EntryTypeThought) {
288+
BOBBY_LOG(APP_LOG_LEVEL_DEBUG, "Deleting thought %d", i);
289+
prv_destroy_entry(entry);
290+
return;
291+
}
292+
}
293+
}
294+
268295
ConversationEntry* conversation_entry_at_index(Conversation* conversation, int index) {
269296
if (index >= conversation->entry_count) {
270297
BOBBY_LOG(APP_LOG_LEVEL_WARNING, "Caller asked for entry %d, but only %d exist.", index, conversation->entry_count);
@@ -293,6 +320,8 @@ ConversationEntry* conversation_get_last_of_type(Conversation* conversation, Ent
293320

294321
const char* prv_type_to_string(EntryType type) {
295322
switch(type) {
323+
case EntryTypeDeleted:
324+
return "EntryTypeDeleted";
296325
case EntryTypePrompt:
297326
return "EntryTypePrompt";
298327
case EntryTypeResponse:
@@ -371,7 +400,7 @@ const char* conversation_get_thread_id(Conversation* conversation) {
371400
}
372401

373402
int conversation_length(Conversation* conversation) {
374-
return conversation->entry_count - conversation->deleted_entries;
403+
return conversation->entry_count - conversation->deleted_entries - conversation->nulled_entries;
375404
}
376405

377406
bool conversation_is_idle(Conversation* conversation) {
@@ -393,6 +422,7 @@ bool conversation_is_idle(Conversation* conversation) {
393422

394423
static bool prv_entry_type_is_assistant(ConversationEntry* entry) {
395424
switch (entry->type) {
425+
case EntryTypeDeleted:
396426
case EntryTypePrompt:
397427
case EntryTypeError:
398428
case EntryTypeThought:

app/src/c/converse/conversation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ typedef struct {
151151
} ConversationWidget;
152152

153153
typedef enum {
154+
EntryTypeDeleted,
154155
EntryTypePrompt,
155156
EntryTypeResponse,
156157
EntryTypeThought,
@@ -180,6 +181,7 @@ ConversationEntry* conversation_peek(Conversation* conversation);
180181
ConversationEntry* conversation_get_last_of_type(Conversation* conversation, EntryType type);
181182
EntryType conversation_entry_get_type(ConversationEntry* entry);
182183
void conversation_delete_first_entry(Conversation* conversation);
184+
void conversation_delete_last_thought(Conversation* conversation);
183185

184186
ConversationPrompt* conversation_entry_get_prompt(ConversationEntry* entry);
185187
ConversationResponse* conversation_entry_get_response(ConversationEntry* response);

app/src/c/converse/segments/segment_layer.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#define NAME_HEIGHT 20
3636

3737
typedef enum {
38+
SegmentTypeNone,
3839
SegmentTypeMessage,
3940
SegmentTypeInfo,
4041
SegmentTypeWeatherSingleDayWidget,
@@ -82,6 +83,8 @@ SegmentLayer* segment_layer_create(GRect rect, ConversationEntry* entry, bool as
8283
data->assistant_label_layer = NULL;
8384
}
8485
switch (data->type) {
86+
case SegmentTypeNone:
87+
break;
8588
case SegmentTypeMessage:
8689
data->message_layer = message_layer_create(child_frame, entry);
8790
break;
@@ -121,6 +124,8 @@ void segment_layer_destroy(SegmentLayer* layer) {
121124
BOBBY_LOG(APP_LOG_LEVEL_INFO, "destroying SegmentLayer %p.", layer);
122125
SegmentLayerData* data = layer_get_data(layer);
123126
switch (data->type) {
127+
case SegmentTypeNone:
128+
break;
124129
case SegmentTypeMessage:
125130
message_layer_destroy(data->message_layer);
126131
break;
@@ -160,6 +165,8 @@ ConversationEntry* segment_layer_get_entry(SegmentLayer* layer) {
160165
void segment_layer_update(SegmentLayer* layer) {
161166
SegmentLayerData* data = layer_get_data(layer);
162167
switch (data->type) {
168+
case SegmentTypeNone:
169+
break;
163170
case SegmentTypeMessage:
164171
message_layer_update(data->message_layer);
165172
break;
@@ -196,6 +203,8 @@ void segment_layer_update(SegmentLayer* layer) {
196203

197204
static SegmentType prv_get_segment_type(ConversationEntry* entry) {
198205
switch (conversation_entry_get_type(entry)) {
206+
case EntryTypeDeleted:
207+
return SegmentTypeNone;
199208
case EntryTypePrompt:
200209
case EntryTypeResponse:
201210
return SegmentTypeMessage;
@@ -221,5 +230,5 @@ static SegmentType prv_get_segment_type(ConversationEntry* entry) {
221230
break;
222231
}
223232
BOBBY_LOG(APP_LOG_LEVEL_WARNING, "Unknown entry type %d.", conversation_entry_get_type(entry));
224-
return SegmentTypeMessage;
233+
return SegmentTypeNone;
225234
}

app/src/c/converse/session_window.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ static void prv_destroy(SessionWindow *sw) {
103103
BOBBY_LOG(APP_LOG_LEVEL_INFO, "destroying SessionWindow %p.", sw);
104104
prv_cancel_timeout(sw);
105105
dictation_session_destroy(sw->dictation);
106+
for (int i = sw->segments_deleted; i < sw->segment_count; ++i) {
107+
segment_layer_destroy(sw->segment_layers[i]);
108+
}
106109
conversation_manager_destroy(sw->manager);
107110
status_bar_layer_destroy(sw->status_layer);
108111
scroll_layer_destroy(sw->scroll_layer);
@@ -113,9 +116,6 @@ static void prv_destroy(SessionWindow *sw) {
113116
thinking_layer_destroy(sw->thinking_layer);
114117
sw->thinking_layer = NULL;
115118
}
116-
for (int i = sw->segments_deleted; i < sw->segment_count; ++i) {
117-
segment_layer_destroy(sw->segment_layers[i]);
118-
}
119119
free(sw->segment_layers);
120120
window_destroy(sw->window);
121121
if (sw->starting_prompt) {
@@ -307,6 +307,7 @@ static void prv_conversation_manager_handler(bool entry_added, void* context) {
307307
}
308308
return;
309309
}
310+
Conversation *conversation = conversation_manager_get_conversation(sw->manager);
310311
// If we have a new entry, we might just want to replace the old segment layer - we don't
311312
// keep old Thought segments around.
312313
if (sw->segment_count > sw->segments_deleted) {
@@ -320,9 +321,9 @@ static void prv_conversation_manager_handler(bool entry_added, void* context) {
320321
layer_remove_from_parent(last_layer);
321322
segment_layer_destroy(last_layer);
322323
sw->segment_layers[--sw->segment_count] = NULL;
324+
conversation_delete_last_thought(conversation);
323325
}
324326
}
325-
Conversation *conversation = conversation_manager_get_conversation(sw->manager);
326327
ConversationEntry* entry = conversation_peek(conversation);
327328
if (entry == NULL) {
328329
// ??????
@@ -370,6 +371,7 @@ static void prv_conversation_manager_handler(bool entry_added, void* context) {
370371
break;
371372
case EntryTypePrompt:
372373
case EntryTypeThought:
374+
case EntryTypeDeleted:
373375
// nothing to do here.
374376
break;
375377
}
@@ -390,6 +392,10 @@ static void prv_conversation_entry_deleted_handler(int index, void* context) {
390392
SegmentLayer *to_delete = sw->segment_layers[sw->segments_deleted];
391393
int16_t removed_height = layer_get_frame(to_delete).size.h;
392394
for (int i = sw->segments_deleted + 1; i < sw->segment_count; ++i) {
395+
if (sw->segment_layers[i] == NULL) {
396+
BOBBY_LOG(APP_LOG_LEVEL_WARNING, "Segment layer %d is NULL (not possible!?)", i);
397+
continue;
398+
}
393399
SegmentLayer *layer = sw->segment_layers[i];
394400
GRect frame = layer_get_frame(layer);
395401
frame.origin.y -= removed_height;

0 commit comments

Comments
 (0)