def test__p_mtime_w_serial(self): from persistent.timestamp import TimeStamp WHEN_TUPLE = (2011, 2, 15, 13, 33, 27.5) ts = TimeStamp(*WHEN_TUPLE) inst, jar, OID = self._makeOneWithJar() inst._p_serial = ts.raw() self.assertEqual(inst._p_mtime, ts.timeTime())
def _get_mtime(self): # The C implementation automatically unghostifies the object # when _p_mtime is accessed. self._p_activate() self._p_accessed() serial = _OGA(self, '_Persistent__serial') if serial is not None: ts = TimeStamp(serial) return ts.timeTime()
def get_cache_modification_time_for_stream(self): max_tid = 0 for key in self.local_client: parts = key.split(':') if len(parts) != 4: continue tid = int(parts[2]) max_tid = max(tid, max_tid) if max_tid: tid_str = p64(max_tid) ts = TimeStamp(tid_str) return ts.timeTime()
def __pre_pack(self, t, referencesf): logger.info("pack: beginning pre-pack") # In 2019, Unix timestamps look like # 1564006806.0 # While 64-bit integer TIDs for the same timestamp look like # 275085010696509852 # # Multiple TIDs can map to a single Unix timestamp. # For example, the 9 integers between 275085010624927044 and # 275085010624927035 all map to 1564006804.9999998. # # Therefore, Unix timestamps are ambiguous, especially if we're committing # multiple transactions rapidly (within the resolution of the underlying TID # clock). # This ambiguity mostly matters for unit tests, where we do commit rapidly. # # To help them out, we accept 64-bit integer TIDs to specify an exact # transaction to pack to. # We also allow None or a negative number to mean "current committed transaction". if t is None: t = -1 if t > 275085010696509852: # Must be a TID. # Turn it back into a time.time() for later logging ts = TimeStamp(int64_to_8bytes(t)) logger.debug( "Treating requested pack time %s as TID meaning %s", t, ts ) best_pack_tid_int = t t = ts.timeTime() elif t < 0 or t >= time.time(): # Packing for the current time or in the future means to pack # to the lastest commit in the database. This matters if not all # machine clocks are synchronized. best_pack_tid_int = MAX_TID - 1 else: # Find the latest commit before or at the pack time. # Note that several TIDs will fit in the resolution of a time.time(), # so this is slightly ambiguous. requested_pack_ts = TimeStamp(*time.gmtime(t)[:5] + (t % 60,)) requested_pack_tid = requested_pack_ts.raw() requested_pack_tid_int = bytes8_to_int64(requested_pack_tid) best_pack_tid_int = requested_pack_tid_int tid_int = self.packundo.choose_pack_transaction(best_pack_tid_int) if tid_int is None: logger.debug("all transactions before %s have already " "been packed", time.ctime(t)) return s = time.ctime(TimeStamp(int64_to_8bytes(tid_int)).timeTime()) logger.info("Analyzing transactions committed %s or before (TID %d)", s, tid_int) # In pre_pack, the adapter fills tables with # information about what to pack. The adapter # must not actually pack anything yet. def get_references(state): """Return an iterable of the set of OIDs the given state refers to.""" if not state: return () return {bytes8_to_int64(oid) for oid in referencesf(state)} self.packundo.pre_pack(tid_int, get_references) logger.info("pack: pre-pack complete") return tid_int
def _get_mtime(self): if self.__serial is not None: ts = TimeStamp(self.__serial) return ts.timeTime()