NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

flatbuffer_index.py (3937B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\imagecaching\client\repository\flatbuffer_index.py
      2 import os
      3 import blue
      4 import flatbuffers
      5 import uthread2
      6 from locks import FifoLock, TempLock
      7 from imagecaching.client.model.definitions.image.entry import ImageEntry
      8 from imagecaching.client.model.definitions.image.identifier import ImageIdentifier
      9 from imagecaching.client.model.flatbuffer.image_cache_generated import ImageList, ImageListStart, ImageListAddImages, ImageListStartImagesVector, ImageListEnd
     10 from imagecaching.client.const import INDEX_FILENAME
     11 if False:
     12     from typing import Dict, Optional
     13 
     14 def _resolve_path_for_writing(res_path):
     15     return blue.paths.ResolvePathForWriting(res_path)
     16 
     17 
     18 class FolderIndex(object):
     19     RETRY_DELAY = 0.1
     20     RETRY_ATTEMPTS = 5
     21 
     22     def __init__(self, folder_res_path):
     23         self._folder_res_path = folder_res_path
     24         self._entries = {}
     25         self._retry_attempts = FolderIndex.RETRY_ATTEMPTS
     26 
     27     @property
     28     def folder_res_path(self):
     29         return self._folder_res_path
     30 
     31     @property
     32     def index_res_path(self):
     33         return u'%s/%s' % (self._folder_res_path, INDEX_FILENAME)
     34 
     35     def get(self, image_id):
     36         return self._entries.get(image_id)
     37 
     38     def identifiers(self):
     39         return sorted(self._entries, key=lambda identifier: identifier.image_id)
     40 
     41     def upsert(self, image_entry):
     42         self._entries[image_entry.identifier] = image_entry
     43 
     44     def remove(self, image_id):
     45         return self._entries.pop(image_id, None) is not None
     46 
     47     def from_bytes(self, buf):
     48         self._entries = {}
     49         if not buf:
     50             return
     51         root = ImageList.GetRootAs(buf, 0)
     52         for i in range(root.ImagesLength()):
     53             entry = ImageEntry.from_flatbuffer(root.Images(i))
     54             self._entries[entry.identifier] = entry
     55 
     56     def to_bytes(self):
     57         builder = flatbuffers.Builder(0)
     58         image_offsets = [ entry.to_flatbuffer(builder) for entry in self._entries.values() ]
     59         ImageListStartImagesVector(builder, len(image_offsets))
     60         for offset in reversed(image_offsets):
     61             builder.PrependUOffsetTRelative(offset)
     62 
     63         images_vector = builder.EndVector()
     64         ImageListStart(builder)
     65         ImageListAddImages(builder, images_vector)
     66         root = ImageListEnd(builder)
     67         builder.Finish(root)
     68         return builder.Output()
     69 
     70     def _access_lock(self):
     71         return TempLock(self.index_res_path, FifoLock)
     72 
     73     def _retry_wrapper(self, impl_method, *args, **kwargs):
     74         with self._access_lock():
     75             for attempt in range(self._retry_attempts):
     76                 try:
     77                     return impl_method(*args, **kwargs)
     78                 except (OSError, IOError):
     79                     if attempt < self._retry_attempts - 1:
     80                         uthread2.Sleep(FolderIndex.RETRY_DELAY)
     81                     else:
     82                         raise
     83 
     84     def load(self):
     85         self._retry_wrapper(self._load_impl)
     86 
     87     def _load_impl(self):
     88         path = _resolve_path_for_writing(self.index_res_path)
     89         if not os.path.exists(path):
     90             self._entries = {}
     91             return
     92         with open(path, 'rb') as index_file:
     93             buf = index_file.read()
     94         self.from_bytes(buf)
     95 
     96     def save(self):
     97         self._retry_wrapper(self._save_impl)
     98 
     99     def _save_impl(self):
    100         folder_path = _resolve_path_for_writing(self._folder_res_path)
    101         if not os.path.exists(folder_path):
    102             os.makedirs(folder_path)
    103         path = _resolve_path_for_writing(self.index_res_path)
    104         with open(path, 'wb') as index_file:
    105             index_file.write(self.to_bytes())
    106             index_file.flush()
    107             os.fsync(index_file.fileno())
    108 
    109     def update(self, mutator):
    110 
    111         def _txn():
    112             self._load_impl()
    113             mutator(self)
    114             self._save_impl()
    115 
    116         self._retry_wrapper(_txn)