From 6e29c4d355b118a2941a4f9a06997d59bd110230 Mon Sep 17 00:00:00 2001 From: 4am Date: Tue, 10 Sep 2019 01:46:21 -0400 Subject: [PATCH] refactor okvs_append so it's O(1) instead of O(N), which makes ParseGamesList O(N) instead of O(N^2), which makes program startup noticeably faster --- src/constants.a | 2 +- src/okvs.a | 65 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/constants.a b/src/constants.a index 81d6b05b2..7423e10e3 100644 --- a/src/constants.a +++ b/src/constants.a @@ -9,7 +9,7 @@ ; D000..E4E9 - persistent data structures (gGlobalPrefsStore, gGamesListStore) ; ...end of data and start of code are approximate, in between is unused... ; ...if they ever overlap, things will go boom... -; EA19..FFF9 - main program code +; E9F0..FFF9 - main program code ; FFFA..FFFF - NMI, reset, IRQ vectors ; ; LC RAM BANK 2 diff --git a/src/okvs.a b/src/okvs.a index 28b55fcaf..2154d9696 100644 --- a/src/okvs.a +++ b/src/okvs.a @@ -16,7 +16,7 @@ ; Call init() once. Call it again to reset the store to 0 keys. ; ; Keys are maintained in a singly linked list, so most functions are O(n). -; len() is O(1) though. +; len() and append() are O(1) though. ; ; Key count is stored as a byte, so a store can hold a maximum of 255 keys. ; @@ -47,7 +47,8 @@ ; ; Store ; +0 length (byte) -; +1 Record +; +1 free space pointer after last record (word) +; +3 Record ; ...Record... ; ...Record... ; @@ -75,6 +76,19 @@ okvs_init ldy #0 tya sta (PTR),y ; set number of keys + + iny ; set initial free space pointer + ldx PTR+1 + lda PTR + clc + adc #$03 + bcc + + inx ++ + sta (PTR),y + iny + txa + sta (PTR),y rts ;------------------------------------------------------------------------------ @@ -116,16 +130,18 @@ okvs_append clc adc #1 sta (PTR),y ; increment number of keys - tax - jsr incptr ; PTR -> first record -- dex - beq + - jsr derefptr ; PTR -> next record - clc - bcc - ; always branches -+ ; PTR -> new record - +LDAY PTR - +STAY SAVE ; save PTR + iny + lda (PTR),y + pha + iny + lda (PTR),y + sta PTR+1 + sta SAVE+1 + pla + sta PTR + sta SAVE + ; PTR -> new record + ; SAVE -> new record jsr incptr jsr incptr ; PTR -> space for new key +LDPARAM 3 @@ -184,6 +200,13 @@ okvs_append iny lda SRC+1 sta (PTR),y + jsr SetPTRFromStackParams ; update next-free-space pointer in head of okvs + ldy #1 + lda SRC + sta (PTR),y + iny + lda SRC+1 + sta (PTR),y rts ;------------------------------------------------------------------------------ @@ -208,8 +231,12 @@ okvs_get lda (PTR),y beq @fail ; no keys, fail immediately sta @maxkeys ; A = number of keys + ldx #3 +- jsr incptr + dex + bne - + ; PTR -> first record ldx #0 - jsr incptr ; PTR -> first record +LDPARAM 3 +STAY SRC ; SRC -> key we want to find ldy #0 @@ -270,7 +297,11 @@ okvs_get okvs_nth +PARAMS_ON_STACK 3 jsr SetPTRFromStackParams - jsr incptr ; PTR -> first record + ldx #3 +- jsr incptr + dex + bne - + ; PTR -> first record ldy #3 lda (PARAM),y tax ; X = numeric index of key to get @@ -355,7 +386,11 @@ okvs_iter_values sta @max +LDPARAM 3 +STAY @callback - jsr incptr ; PTR -> first record + ldx #3 +- jsr incptr + dex + bne - + ; PTR -> first record ldx #0 @loop lda #2