@@ -694,7 +694,7 @@ collect_data_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyVal
694694{
695695 struct cbdata * cbdata = vcbdata ;
696696 int rm ;
697- Id id ;
697+ Id id , storage ;
698698 struct extdata * xd ;
699699 NeedId * needid ;
700700
@@ -704,15 +704,15 @@ collect_data_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyVal
704704 rm = cbdata -> keymap [key - data -> keys ];
705705 if (!rm )
706706 return SEARCH_NEXT_KEY ; /* we do not want this one */
707+ storage = cbdata -> target -> keys [rm ].storage ;
707708
708- if (cbdata -> target -> keys [rm ].storage == KEY_STORAGE_VERTICAL_OFFSET )
709+ xd = cbdata -> extdata + 0 ; /* incore buffer */
710+ if (storage == KEY_STORAGE_VERTICAL_OFFSET )
709711 {
710- xd = cbdata -> extdata + rm ; /* vertical buffer */
712+ xd += rm ; /* vertical buffer */
711713 if (cbdata -> vstart == -1 )
712714 cbdata -> vstart = xd -> len ;
713715 }
714- else
715- xd = cbdata -> extdata + 0 ; /* incore buffer */
716716 switch (key -> type )
717717 {
718718 case REPOKEY_TYPE_DELETED :
@@ -787,7 +787,7 @@ collect_data_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyVal
787787 if (cbdata -> owndirpool )
788788 id = putinowndirpool (cbdata , data , id );
789789 id = cbdata -> dirused [id ];
790- if (cbdata -> filelistmode )
790+ if (rm == cbdata -> filelistmode )
791791 {
792792 /* postpone adding to xd, just update len to get the correct offsets into the incore data*/
793793 xd -> len += data_addideof_len (id ) + strlen (kv -> str ) + 1 ;
@@ -813,7 +813,7 @@ collect_data_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyVal
813813 cbdata -> target -> error = pool_error (cbdata -> pool , -1 , "unknown type for %d: %d\n" , key -> name , key -> type );
814814 break ;
815815 }
816- if (cbdata -> target -> keys [ rm ]. storage == KEY_STORAGE_VERTICAL_OFFSET && kv -> eof )
816+ if (storage == KEY_STORAGE_VERTICAL_OFFSET && kv -> eof )
817817 {
818818 /* we can re-use old data in the blob here! */
819819 data_addid (cbdata -> extdata + 0 , cbdata -> vstart ); /* add offset into incore data */
@@ -833,7 +833,7 @@ collect_filelist_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, Ke
833833 struct extdata * xd ;
834834
835835 rm = cbdata -> keymap [key - data -> keys ];
836- if (! rm )
836+ if (rm != cbdata -> filelistmode )
837837 return SEARCH_NEXT_KEY ; /* we do not want this one */
838838 id = kv -> id ;
839839 if (cbdata -> owndirpool )
@@ -1456,7 +1456,7 @@ for (i = 1; i < target.nkeys; i++)
14561456 needid [0 ].map = reloff ; /* remember size in case we need to grow */
14571457
14581458 cbdata .needid = needid ;
1459- cbdata .schema = solv_calloc (target .nkeys + 1 , sizeof (Id ));
1459+ cbdata .schema = solv_calloc (target .nkeys + 2 , sizeof (Id ));
14601460
14611461 /* create main schema */
14621462 cbdata .sp = cbdata .schema + 1 ;
@@ -1565,17 +1565,23 @@ for (i = 1; i < target.nkeys; i++)
15651565
15661566/********************************************************************/
15671567
1568- /* check if we can do the special filelist memory optimization */
1569- /* we do the check before the keys are mapped */
1568+ /* check if we can do the special filelist memory optimization
1569+ * we do the check before the keys are mapped.
1570+ * The optimization is done if there is just one vertical key and
1571+ * it is of type REPOKEY_TYPE_DIRSTRARRAY */
15701572 if (anysolvableused && anyrepodataused )
15711573 {
15721574 for (i = 1 ; i < target .nkeys ; i ++ )
1573- if (target .keys [i ].storage == KEY_STORAGE_VERTICAL_OFFSET )
1574- cbdata .filelistmode |= cbdata .filelistmode == 0 && target .keys [i ].type == REPOKEY_TYPE_DIRSTRARRAY ? 1 : 2 ;
1575- else if (target .keys [i ].type == REPOKEY_TYPE_DIRSTRARRAY )
1576- cbdata .filelistmode = 2 ;
1577- if (cbdata .filelistmode != 1 )
1578- cbdata .filelistmode = 0 ;
1575+ {
1576+ if (target .keys [i ].storage != KEY_STORAGE_VERTICAL_OFFSET )
1577+ continue ;
1578+ if (target .keys [i ].type != REPOKEY_TYPE_DIRSTRARRAY || cbdata .filelistmode != 0 )
1579+ {
1580+ cbdata .filelistmode = 0 ;
1581+ break ;
1582+ }
1583+ cbdata .filelistmode = i ;
1584+ }
15791585 }
15801586
15811587/********************************************************************/
@@ -1601,7 +1607,6 @@ for (i = 1; i < target.nkeys; i++)
16011607 {
16021608 grow_needid (& cbdata , spool -> nstrings - 1 );
16031609 needid = cbdata .needid ; /* we relocated */
1604- reloff = needid [0 ].map ; /* we have a new offset */
16051610 }
16061611 }
16071612 else
@@ -1623,6 +1628,7 @@ for (i = 1; i < target.nkeys; i++)
16231628 * need value is it is bigger than our value so that
16241629 * ordering works.
16251630 */
1631+ reloff = needid [0 ].map ;
16261632 for (i = pool -> nrels - 1 , needidp = needid + (reloff + i ); i > 0 ; i -- , needidp -- )
16271633 if (needidp -> need )
16281634 break ;
@@ -1850,7 +1856,6 @@ for (i = 1; i < target.nkeys; i++)
18501856 cbdata .lastdirid = 0 ;
18511857 repodata_search_keyskip (data , SOLVID_META , 0 , searchflags , keyskip , collect_data_cb , & cbdata );
18521858 }
1853-
18541859 if (xd -> len - cbdata .lastlen > cbdata .maxdata )
18551860 cbdata .maxdata = xd -> len - cbdata .lastlen ;
18561861 cbdata .lastlen = xd -> len ;
@@ -2005,21 +2010,24 @@ for (i = 1; i < target.nkeys; i++)
20052010 for (i = 1 ; i < target .nschemata ; i ++ )
20062011 write_idarray (& target , pool , 0 , repodata_id2schema (& target , i ));
20072012
2008- /********************************************************************/
2009-
2013+ /*
2014+ * write incore data
2015+ */
20102016 write_id (& target , cbdata .maxdata );
20112017 write_id (& target , cbdata .extdata [0 ].len );
20122018 if (cbdata .extdata [0 ].len )
20132019 write_blob (& target , cbdata .extdata [0 ].buf , cbdata .extdata [0 ].len );
20142020 solv_free (cbdata .extdata [0 ].buf );
20152021
2016- /* do we have vertical data? */
2022+ /*
2023+ * write vertical data if we have any
2024+ */
20172025 for (i = 1 ; i < target .nkeys ; i ++ )
20182026 if (cbdata .extdata [i ].len )
20192027 break ;
20202028 if (i < target .nkeys )
20212029 {
2022- /* yes , write it in pages */
2030+ /* have vertical data , write it in pages */
20232031 unsigned char vpage [REPOPAGE_BLOBSIZE ];
20242032 int lpage = 0 ;
20252033
@@ -2032,13 +2040,18 @@ for (i = 1; i < target.nkeys; i++)
20322040 }
20332041 else
20342042 {
2035- /* ok, just this single extdata, which is of type REPOKEY_TYPE_DIRSTRARRAY */
2043+ /* ok, just one single extdata which is of type REPOKEY_TYPE_DIRSTRARRAY */
20362044 xd = cbdata .extdata + i ;
20372045 xd -> len = 0 ;
2038- /* remove all keys from the keymap but this one */
2039- for (j = 0 ; j < nkeymap ; j ++ )
2040- if (keymap [j ] != i )
2041- keymap [j ] = 0 ;
2046+ keyskip = create_keyskip (repo , SOLVID_META , repodataused , & oldkeyskip );
2047+ FOR_REPODATAS (repo , j , data )
2048+ {
2049+ if (!repodataused [j ])
2050+ continue ;
2051+ cbdata .keymap = keymap + keymapstart [j ];
2052+ cbdata .lastdirid = 0 ;
2053+ repodata_search_keyskip (data , SOLVID_META , 0 , searchflags , keyskip , collect_filelist_cb , & cbdata );
2054+ }
20422055 for (i = solvablestart , s = pool -> solvables + i ; i < solvableend ; i ++ , s ++ )
20432056 {
20442057 if (s -> repo != repo )
0 commit comments