Алгоритм вычисления страницы

jenya7
Дата: 17.09.2018 09:49:17
Сильно запутался. Нужна помощь.
Есть память со следующей архитектурой
автор
MEMORY = 1815 BLOCKS
1 BLOCK = 64 PAGES
1 PAGE = 4096 BYTE

То есть память разделена на блоки, блоки разделены на страницы, каждая страница 4К.
Мне передают в качестве аргументов офсет и размер данных и на основе этих двух параметров я должен вытащить данные.
Для облегчения задачи мне передают фиксированный размер 65530 байт, соответственно офсет увеличивается на 65530.
+
#define PAGESIZE 4096
#define BLOCKSIZE 262144 //64 * 4096;

uint32_t startpage, endpage, pages;
uint32_t page, block, page_chunk;
uint32_t block_idx, page_idx, uart_byte_idx, page_addr;
uint32_t row_address;
uint32_t last_chunk;
uint32_t total_sent_size;
void GetLoggerDataFast(uint32_t offset, uint32_t datasize)
{
    total_sent_size = 0;
    
    last_chunk = datasize % PAGESIZE;
    
    pages = (datasize / PAGESIZE);
    
    if (pages == 0)
        pages = 1;
    else
    {
        if(last_chunk)
            pages++;
    }

    startpage = (offset % BLOCKSIZE) / PAGESIZE;
    endpage = ((offset + datasize) % BLOCKSIZE) / PAGESIZE;
    
    page = startpage;
    
    for (page_idx = 0; page_idx < pages; page_idx++)
    { 
        
    if (page_idx == 0)  
    {
        if (datasize > PAGESIZE)
        {
            page_chunk = PAGESIZE - (offset % PAGESIZE);
            page_addr = (offset % PAGESIZE);
        }
        else
        {
            page_chunk = datasize;
            page_addr = 0;
        }
    }
    else if (page_idx  == ( pages-1)) 
    {
        page_chunk = datasize - ((pages-1) * PAGESIZE);
             //page_chunk = datasize - total_sent_size;
        page_addr = 0;
    }
    else
    {
        page_chunk = PAGESIZE;
        page_addr = 0;
    }
        
        printf ("page num = %d \n", page);
        printf ("page addr = %d \n", page_addr);
        printf ("page chunk = %d \n", page_chunk);
        printf ("-------------------\n");
        
        total_sent_size += page_chunk;
         
        page++;
        if (page > 63)
        {
            page = 0;
        }
    } 
    
     printf ("total size = %d \n", total_sent_size);
     printf ("\n\n");
}


проверяю
int main()
{
    GetLoggerDataFast(0, 65530);
    GetLoggerDataFast(65530, 65530);
    GetLoggerDataFast(131060, 65530);
    GetLoggerDataFast(196590, 65530);
    GetLoggerDataFast(262120, 65530);
    GetLoggerDataFast(327650, 65530);
    
  return 0;
}


получаю лог
+

page num = 0
page addr = 0
page chunk = 4096
-------------------
page num = 1
page addr = 0
page chunk = 4096
-------------------
page num = 2
page addr = 0
page chunk = 4096
-------------------
page num = 3
page addr = 0
page chunk = 4096
-------------------
page num = 4
page addr = 0
page chunk = 4096
-------------------
page num = 5
page addr = 0
page chunk = 4096
-------------------
page num = 6
page addr = 0
page chunk = 4096
-------------------
page num = 7
page addr = 0
page chunk = 4096
-------------------
page num = 8
page addr = 0
page chunk = 4096
-------------------
page num = 9
page addr = 0
page chunk = 4096
-------------------
page num = 10
page addr = 0
page chunk = 4096
-------------------
page num = 11
page addr = 0
page chunk = 4096
-------------------
page num = 12
page addr = 0
page chunk = 4096
-------------------
page num = 13
page addr = 0
page chunk = 4096
-------------------
page num = 14
page addr = 0
page chunk = 4096
-------------------
page num = 15
page addr = 0
page chunk = 4090
-------------------
total size = 65530


page num = 15
page addr = 4090
page chunk = 6
-------------------
page num = 16
page addr = 0
page chunk = 4096
-------------------
page num = 17
page addr = 0
page chunk = 4096
-------------------
page num = 18
page addr = 0
page chunk = 4096
-------------------
page num = 19
page addr = 0
page chunk = 4096
-------------------
page num = 20
page addr = 0
page chunk = 4096
-------------------
page num = 21
page addr = 0
page chunk = 4096
-------------------
page num = 22
page addr = 0
page chunk = 4096
-------------------
page num = 23
page addr = 0
page chunk = 4096
-------------------
page num = 24
page addr = 0
page chunk = 4096
-------------------
page num = 25
page addr = 0
page chunk = 4096
-------------------
page num = 26
page addr = 0
page chunk = 4096
-------------------
page num = 27
page addr = 0
page chunk = 4096
-------------------
page num = 28
page addr = 0
page chunk = 4096
-------------------
page num = 29
page addr = 0
page chunk = 4096
-------------------
page num = 30
page addr = 0
page chunk = 4090
-------------------
total size = 61440


page num = 31
page addr = 4084
page chunk = 12
-------------------
page num = 32
page addr = 0
page chunk = 4096
-------------------
page num = 33
page addr = 0
page chunk = 4096
-------------------
page num = 34
page addr = 0
page chunk = 4096
-------------------
page num = 35
page addr = 0
page chunk = 4096
-------------------
page num = 36
page addr = 0
page chunk = 4096
-------------------
page num = 37
page addr = 0
page chunk = 4096
-------------------
page num = 38
page addr = 0
page chunk = 4096
-------------------
page num = 39
page addr = 0
page chunk = 4096
-------------------
page num = 40
page addr = 0
page chunk = 4096
-------------------
page num = 41
page addr = 0
page chunk = 4096
-------------------
page num = 42
page addr = 0
page chunk = 4096
-------------------
page num = 43
page addr = 0
page chunk = 4096
-------------------
page num = 44
page addr = 0
page chunk = 4096
-------------------
page num = 45
page addr = 0
page chunk = 4096
-------------------
page num = 46
page addr = 0
page chunk = 4090
-------------------
total size = 61446


Первая итерация все правильно - 16 страниц - последняя на 6 байт меньше - все правильно.
Вторая итерация все правильно - начали с 15-ой страницы, добрали 6 байт а потом все сломалось - последняя страница 30 а не 31.
MBo
Дата: 17.09.2018 12:24:18
Видимо, эта музыка будет вечной - я гляжу, эпопея много лет длится.

В прошлой ветке http://www.sql.ru/forum/1297859/ я почему-то говорил:

автор
Вычисление первой и последней страницы должно быть правильно, вот на это и надо ориентироваться, а такое нахождение количества страниц некорректно.


Это по-прежнему справедливо.
jenya7
Дата: 17.09.2018 12:30:22
MBo
Видимо, эта музыка будет вечной - я гляжу, эпопея много лет длится.

В прошлой ветке http://www.sql.ru/forum/1297859/ я почему-то говорил:

автор
Вычисление первой и последней страницы должно быть правильно, вот на это и надо ориентироваться, а такое нахождение количества страниц некорректно.


Это по-прежнему справедливо.

я решил начать с чистого листа так как запутался. так как коректно вычислить? в этом и вопрос.
Dima T
Дата: 17.09.2018 12:36:37
Так правильно
    endpage = ((offset + datasize - 1) % BLOCKSIZE) / PAGESIZE;

И у тебя полностью проигнорирован учет блоков. Ты работаешь только с первым блоком, поэтому выходя за его пределы начинаются глюки.
jenya7
Дата: 17.09.2018 12:48:46
Dima T
Так правильно
    endpage = ((offset + datasize - 1) % BLOCKSIZE) / PAGESIZE;

И у тебя полностью проигнорирован учет блоков. Ты работаешь только с первым блоком, поэтому выходя за его пределы начинаются глюки.

в привиденном выше примере у меня так и есть
endpage = ((offset + datasize) % BLOCKSIZE) / PAGESIZE;
блоки вычисляются правильно. я не привел их в коде.
Dima T
Дата: 17.09.2018 13:07:31
jenya7
Dima T
Так правильно
    endpage = ((offset + datasize - 1) % BLOCKSIZE) / PAGESIZE;

И у тебя полностью проигнорирован учет блоков. Ты работаешь только с первым блоком, поэтому выходя за его пределы начинаются глюки.

в привиденном выше примере у меня так и есть
endpage = ((offset + datasize) % BLOCKSIZE) / PAGESIZE;
блоки вычисляются правильно. я не привел их в коде.

-1 надо, т.к. offset + datasize это первый байт следующего сообщения.
Не важно. endpage у тебя не используется в коде.
jenya7
Дата: 17.09.2018 13:09:08
Dima T
jenya7
пропущено...

в привиденном выше примере у меня так и есть
endpage = ((offset + datasize) % BLOCKSIZE) / PAGESIZE;
блоки вычисляются правильно. я не привел их в коде.

-1 надо, т.к. offset + datasize это первый байт следующего сообщения.
Не важно. endpage у тебя не используется в коде.

ааа. спасибо. похоже тут и есть моя проблема.
Dima T
Дата: 17.09.2018 13:17:26
jenya7
Dima T
пропущено...

-1 надо, т.к. offset + datasize это первый байт следующего сообщения.
Не важно. endpage у тебя не используется в коде.

ааа. спасибо. похоже тут и есть моя проблема.

Нет, проблема в другом. Я же написал что endpage ты не используешь.
Dima T
Дата: 17.09.2018 13:22:12
Тут ошибка
    if (page_idx == 0)  
    {
        if (datasize > PAGESIZE)
        {
            page_chunk = PAGESIZE - (offset % PAGESIZE);
            page_addr = (offset % PAGESIZE);
        }
        else
        {
            page_chunk = datasize;
            page_addr = 0;
        }
    }

надо так
    if (page_idx == 0)  
    {
        page_addr = (offset % PAGESIZE);
        page_chunk = PAGESIZE - page_addr;
        if (page_chunk > datasize)
        {
            page_chunk = datasize;
        }
Dima T
Дата: 17.09.2018 13:26:44
Еще ты некорректно считаешь
 pages = (datasize / PAGESIZE);

Твои 65530 байт могут быть как на 16 так и на 17 страницах, т.к. они не всегда попадают в начало страницы.