@@ -1161,7 +1161,14 @@ async def fetch(self, *tileables, **kwargs) -> list:
11611161 return result
11621162
11631163 async def fetch_infos (self , * tileables , fields , ** kwargs ) -> list :
1164- available_fields = {"object_id" , "level" , "memory_size" , "store_size" , "band" }
1164+ available_fields = {
1165+ "object_id" ,
1166+ "object_refs" ,
1167+ "level" ,
1168+ "memory_size" ,
1169+ "store_size" ,
1170+ "bands" ,
1171+ }
11651172 if fields is None :
11661173 fields = available_fields
11671174 else :
@@ -1175,34 +1182,22 @@ async def fetch_infos(self, *tileables, fields, **kwargs) -> list:
11751182 if kwargs : # pragma: no cover
11761183 unexpected_keys = ", " .join (list (kwargs .keys ()))
11771184 raise TypeError (f"`fetch` got unexpected arguments: { unexpected_keys } " )
1178-
1185+ # following fields needs to access storage API to get the meta.
1186+ _need_query_storage_fields = {"level" , "memory_size" , "store_size" }
1187+ _need_query_storage = bool (_need_query_storage_fields & fields )
11791188 with enter_mode (build = True ):
1180- chunks = []
1181- get_chunk_metas = []
1182- fetch_infos_list = []
1183- for tileable in tileables :
1184- fetch_tileable , _ = self ._get_to_fetch_tileable (tileable )
1185- fetch_infos = []
1186- for chunk in fetch_tileable .chunks :
1187- chunks .append (chunk )
1188- get_chunk_metas .append (
1189- self ._meta_api .get_chunk_meta .delay (chunk .key , fields = ["bands" ])
1190- )
1191- fetch_infos .append (
1192- ChunkFetchInfo (tileable = tileable , chunk = chunk , indexes = None )
1193- )
1194- fetch_infos_list .append (fetch_infos )
1195- chunk_metas = await self ._meta_api .get_chunk_meta .batch (* get_chunk_metas )
1196- chunk_to_band = {
1197- chunk : meta ["bands" ][0 ] for chunk , meta in zip (chunks , chunk_metas )
1198- }
1199-
1189+ chunk_to_bands , fetch_infos_list , result = await self ._query_meta_service (
1190+ tileables , fields , _need_query_storage
1191+ )
1192+ if not _need_query_storage :
1193+ assert result is not None
1194+ return result
12001195 storage_api_to_gets = defaultdict (list )
12011196 storage_api_to_fetch_infos = defaultdict (list )
12021197 for fetch_info in itertools .chain (* fetch_infos_list ):
12031198 chunk = fetch_info .chunk
1204- band = chunk_to_band [chunk ]
1205- storage_api = await self ._get_storage_api (band )
1199+ bands = chunk_to_bands [chunk ]
1200+ storage_api = await self ._get_storage_api (bands [ 0 ] )
12061201 storage_api_to_gets [storage_api ].append (
12071202 storage_api .get_infos .delay (chunk .key )
12081203 )
@@ -1219,7 +1214,7 @@ async def fetch_infos(self, *tileables, fields, **kwargs) -> list:
12191214 for fetch_infos in fetch_infos_list :
12201215 fetched = defaultdict (list )
12211216 for fetch_info in fetch_infos :
1222- band = chunk_to_band [fetch_info .chunk ]
1217+ bands = chunk_to_bands [fetch_info .chunk ]
12231218 # Currently there's only one item in the returned List from storage_api.get_infos()
12241219 data = fetch_info .data [0 ]
12251220 if "object_id" in fields :
@@ -1232,12 +1227,47 @@ async def fetch_infos(self, *tileables, fields, **kwargs) -> list:
12321227 fetched ["store_size" ].append (data .store_size )
12331228 # data.band misses ip info, e.g. 'numa-0'
12341229 # while band doesn't, e.g. (address0, 'numa-0')
1235- if "band " in fields :
1236- fetched ["band " ].append (band )
1230+ if "bands " in fields :
1231+ fetched ["bands " ].append (bands )
12371232 result .append (fetched )
12381233
12391234 return result
12401235
1236+ async def _query_meta_service (self , tileables , fields , query_storage ):
1237+ chunks = []
1238+ get_chunk_metas = []
1239+ fetch_infos_list = []
1240+ for tileable in tileables :
1241+ fetch_tileable , _ = self ._get_to_fetch_tileable (tileable )
1242+ fetch_infos = []
1243+ for chunk in fetch_tileable .chunks :
1244+ chunks .append (chunk )
1245+ get_chunk_metas .append (
1246+ self ._meta_api .get_chunk_meta .delay (
1247+ chunk .key ,
1248+ fields = ["bands" ] if query_storage else fields ,
1249+ )
1250+ )
1251+ fetch_infos .append (
1252+ ChunkFetchInfo (tileable = tileable , chunk = chunk , indexes = None )
1253+ )
1254+ fetch_infos_list .append (fetch_infos )
1255+ chunk_metas = await self ._meta_api .get_chunk_meta .batch (* get_chunk_metas )
1256+ if not query_storage :
1257+ result = []
1258+ chunk_to_meta = dict (zip (chunks , chunk_metas ))
1259+ for fetch_infos in fetch_infos_list :
1260+ fetched = defaultdict (list )
1261+ for fetch_info in fetch_infos :
1262+ for field in fields :
1263+ fetched [field ].append (chunk_to_meta [fetch_info .chunk ][field ])
1264+ result .append (fetched )
1265+ return {}, fetch_infos_list , result
1266+ chunk_to_bands = {
1267+ chunk : meta ["bands" ] for chunk , meta in zip (chunks , chunk_metas )
1268+ }
1269+ return chunk_to_bands , fetch_infos_list , None
1270+
12411271 async def decref (self , * tileable_keys ):
12421272 logger .debug ("Decref tileables on client: %s" , tileable_keys )
12431273 return await self ._lifecycle_api .decref_tileables (list (tileable_keys ))
0 commit comments