Tengo una aplicación que carga registros de un archivo de registro binario y los muestra en un TListView virtual. Hay potencialmente millones de registros en un archivo, y la pantalla puede ser filtrada por el usuario, por lo que no carga todos los registros en la memoria a la vez, y los índices de elementos ListView no son una relación de 1 a 1 con las compensaciones de registros de archivos (la lista de elementos 1 puede ser el registro de archivos 100, por ejemplo). Uso el evento OnDataHint de ListView para cargar registros solo para los elementos en los que ListView está realmente interesado. A medida que el usuario se desplaza, el rango especificado por OnDataHint cambia, lo que me permite liberar registros que no están en el nuevo rango y asignar nuevos registros según sea necesario.TVirtualStringTree - restauración de nodos visuales y consumo de memoria
Esto funciona bien, la velocidad es tolerable y la huella de memoria es muy baja.
Actualmente estoy evaluando TVirtualStringTree como reemplazo del TListView, principalmente porque deseo agregar la capacidad de expandir/colapsar registros que abarcan varias líneas (puedo mezclarlo con el TListView aumentando/disminuyendo dinámicamente el conteo de elementos, pero esto no es tan sencillo como usar un árbol real).
En su mayor parte, he sido capaz de portar la lógica TListView y hacer que todo funcione como lo necesito. Observo que el paradigma virtual de TVirtualStringTree es muy diferente. No tiene el mismo tipo de funcionalidad OnDataHint que TListView (puedo usar el evento OnScroll para simularlo, lo que permite que mi lógica de buffer de memoria continúe funcionando), y puedo usar el evento OnInitializeNode para asociar nodos con registros que están asignados .
Sin embargo, una vez que se inicializa un nodo de árbol, se ve que permanece inicializado durante la vida útil del árbol. Eso no es bueno para mi A medida que el usuario se desplaza y elimino registros de la memoria, necesito reiniciar esos nodos visuales sin eliminarlos del árbol por completo, o perder sus estados de expansión/colapso. Cuando el usuario los vuelva a visualizar, puedo volver a asignar los registros y reiniciar los nodos. Básicamente, quiero hacer que TVirtualStringTree actúe tanto como TListView como sea posible, en lo que respecta a su virtualización.
He visto que TVirtualStringTree tiene un método ResetNode(), pero encuentro varios errores cada vez que trato de usarlo. Debo usarlo mal. También pensé simplemente almacenar un puntero de datos dentro de cada nodo en mis búferes de registro, y asignar y liberar memoria, actualizar esos punteros en consecuencia. El efecto final tampoco funciona tan bien.
Peor aún, mi archivo de registro de prueba más grande tiene ~ 5 millones de registros en el mismo. Si inicializo el TVirtualStringTree con tantos nodos a la vez (cuando la pantalla de registro no está filtrada), la sobrecarga interna del árbol para sus nodos ocupa una friolera de 260 MB de memoria (sin ningún registro asignado aún). Mientras que con TListView, cargando el mismo archivo de registro y toda la lógica de la memoria detrás de él, puedo salirse con la suya usando solo unos pocos MB.
¿Alguna idea?
Actualmente uso un TListView en el modo vsReport, no un TListBox. TListView no admite elementos de altura variable en vsReport. –
Estoy marcando esta como la respuesta por ahora, pero solo porque me dice que no cambie a VST. –