Страница 1 из 2

Queue to BLOB

Добавлено: 07 Декабрь 2017, 16:26
Constantine
Есть такая задачка.
Из множества текстовых файлов формируется Queue, которая никогда (очень редко) не меняется.
Нужно ее сформировать, а затем со всем содержимым поместить в BLOB, а затем, при необходимости, восстановить в памяти, чтобы не формировать ее каждый раз из файлов.
Кто-нибудь делал? Есть идеи?
Спасибо!

Queue to BLOB

Добавлено: 07 Декабрь 2017, 16:45
Yufil
Это называется "сериализация". XML, JSON, YAML ... в помощь.
Тем не менее, я делал https://mega.nz/#!pxY0VQwR!B2l1BEHvbfFT ... voxTx-XoSI

Хранились данные сессии, включающие очереди, группы и т д.

В тексте программы что-то типа

Код: Выделить всё

P   Class(DumpClass)
    End
....
!    Регистрация хранимых объектов (Очереди, группы, просто переменные 
     P.AddField('ZTstQ',TstQ)
     P.AddField('ResQ',ResQ)
     P.AddField('Qlist',QList)
     P.AddField('QGroup',QGroup)
.... 
!    Чтение блоба 
     P.LoadBlob(Ses:Info)

.... 
!     Запись блоба 
      P.SaveBlob(Ses:Info)
Вот наскрёб куски из реальных работающих программ
https://mega.nz/#!R4Rg1TAK!hyP2E8WsyeTh ... l8fPlta2lI

Queue to BLOB

Добавлено: 07 Декабрь 2017, 16:47
Constantine
Спасибо, Юра!
Ты, как всегда, лучший!

Queue to BLOB

Добавлено: 07 Декабрь 2017, 17:10
Дед Пахом
Проще всего перегнать очередь в строку без всякой сериализации, байт в байт, и так же обратно.

Queue to BLOB

Добавлено: 07 Декабрь 2017, 17:13
Constantine
А примерчик можно, пожалуйста...

Queue to BLOB

Добавлено: 07 Декабрь 2017, 17:24
Дед Пахом
берётся строка длиной "размер одной записи очереди Х количество записей" и в цикле по очереди каждая запись пишется в эту строку на нужном месте. Обратно: размер строки из файла из файла делим на размер записи, получаем число записей в очереди, и каждый кусок строки добавляем в очередь.

Queue to BLOB

Добавлено: 07 Декабрь 2017, 17:32
Constantine
Спасибо!

Queue to BLOB

Добавлено: 07 Декабрь 2017, 17:56
Дед Пахом

Код: Выделить всё

  PROGRAM

SomeGrp                       GROUP, TYPE
s1                              STRING(20)
l1                              LONG
                              END

SomeQue                       QUEUE(SomeGrp), TYPE
                              END

  MAP
    Que2String(SomeQue q), *STRING
    String2Que(STRING  s, *SomeQue q)
  END


myQ                           QUEUE(SomeQue)
                              END

qBuf                          &STRING
ndx                           LONG, AUTO

  CODE
  !-- test data
  myQ.l1 = 1
  myQ.s1 = 'First'
  ADD(myQ)
  myQ.l1 = 2
  myQ.s1 = 'Second'
  ADD(myQ)

  !-- byte serialization
  qBuf &= Que2String(myQ)

  !-- delete all records
  FREE(myQ)
  CLEAR(myQ)

  !-- deserialize
  String2Que(qBuf, myQ)

  !-- Test
  LOOP ndx = 1 TO RECORDS(myQ)
    GET(myQ, ndx)
    MESSAGE(myQ.l1 &': '& myQ.s1)
  END

  !-- cleanup
  DISPOSE(qBuf)
  
Que2String                    PROCEDURE(SomeQue q)
sref                            &STRING
grp                             LIKE(SomeGrp)
nrecs                           LONG, AUTO
qIndex                          LONG, AUTO
slice1                          LONG, AUTO
slice2                          LONG, AUTO
  CODE
  nrecs = RECORDS(q)
  sref &= NEW STRING(nrecs * LEN(grp))
  
  slice1 = 1
  slice2 = LEN(grp)
  
  LOOP qIndex = 1 TO nrecs
    GET(q, qIndex)
    grp = q
    sref[slice1 : slice2] = grp
    slice1 += LEN(grp)
    slice2 += LEN(grp)
  END
  
  RETURN sref
  
String2Que                    PROCEDURE(STRING  s, *SomeQue q)
grp                             LIKE(SomeGrp)
nrecs                           LONG, AUTO
qIndex                          LONG, AUTO
slice1                          LONG, AUTO
slice2                          LONG, AUTO
  CODE
  nrecs = LEN(s) / LEN(grp)
  slice1 = 1
  slice2 = LEN(grp)
  LOOP qIndex = 1 TO nrecs
    grp = s[slice1 : slice2]
    q = grp
    ADD(q)
    slice1 += LEN(grp)
    slice2 += LEN(grp)
  END
  

Queue to BLOB

Добавлено: 07 Декабрь 2017, 18:04
Constantine
Спасибо БОЛЬШОЕ! :-)

Queue to BLOB

Добавлено: 07 Декабрь 2017, 21:15
Yufil
Так у меня класс именно это и делает, только там в блоб можно загнать не одну, а несколько очередей. Сначала выводится служебная запись с идентификатором, размером записи и количеством записей, потом записи очереди, потом таким же образом и другие очереди...

Queue to BLOB

Добавлено: 08 Декабрь 2017, 8:46
Constantine
А вот интересно, с помощью PEEK/POKE такой номер можно проделать?
Т.е. сохранить/восстановить "дамп" очереди?
Мне кажется, что так будет побыстрее...

Queue to BLOB

Добавлено: 08 Декабрь 2017, 9:07
Yufil
Так она может быть раскидана по памяти, вряд ли удастся скопировать всю сразу. А вот буфер копируется через memcopy, с некоторой экономией времени...

Queue to BLOB

Добавлено: 08 Декабрь 2017, 9:49
Constantine
А если STATIC?

Queue to BLOB

Добавлено: 08 Декабрь 2017, 11:40
Дед Пахом
Constantine писал(а): 08 Декабрь 2017, 9:49А если STATIC?
А если всё-таки попробовать самому хоть что-то сделать? :facepalm:

Queue to BLOB

Добавлено: 08 Декабрь 2017, 12:28
Yufil
Дык, я выложил готовый и реально работающий класс. Который выкладывает в Blob даже не одну, а несколько очередей.
Используется в разного рода обучающих программах для сохранения сессии (список пройденных разделов, результаты тестирований, значения переменных, текущая ситуация на экране, конфигурация параметров и т д) и, знамо дело, восстановлении при последующем пуске (для Интернет-версий между обращениями к серверу)
Создал объект класса, указал очереди, которые в нём лежат. После чего SaveBlob копирует очереди в Blob, а LoadBlob достаёт их оттуда.
Бери и пользуйся...