@@ -77,7 +77,7 @@ import Data.Constraint (Dict (..))
7777import Data.Kind (Type )
7878import Data.Map.Strict (Map )
7979import qualified Data.Map.Strict as Map
80- import Data.Maybe (catMaybes , fromJust )
80+ import Data.Maybe (catMaybes , fromJust , fromMaybe )
8181import Data.Set (Set )
8282import qualified Data.Set as Set
8383import Data.Typeable (Proxy (.. ), Typeable , cast , eqT ,
@@ -1322,6 +1322,15 @@ data Stats = Stats {
13221322 -- sizes from the final model state (which of course has only tables still
13231323 -- open in the final state).
13241324 , closedTableSizes :: ! (Map Model. TableHandleID Int )
1325+ -- | The ultimate parent for each table. This is the 'TableId' of a table
1326+ -- created using 'new' or 'open'.
1327+ , parentTable :: Map Model. TableHandleID Model. TableHandleID
1328+ -- | Track the interleavings of operations via different but related tables.
1329+ -- This is a map from the ultimate parent table to a summary log of which
1330+ -- tables (derived from that parent table via duplicate) have had
1331+ -- \"interesting\" actions performed on them. We record only the
1332+ -- interleavings of different tables not multiple actions on the same table.
1333+ , dupTableActionLog :: Map Model. TableHandleID [Model. TableHandleID ]
13251334 }
13261335 deriving stock Show
13271336
@@ -1337,6 +1346,8 @@ initStats = Stats {
13371346 , failActions = []
13381347 , numActionsPerTable = Map. empty
13391348 , closedTableSizes = Map. empty
1349+ , parentTable = Map. empty
1350+ , dupTableActionLog = Map. empty
13401351 }
13411352
13421353updateStats ::
@@ -1364,6 +1375,8 @@ updateStats action lookUp modelBefore _modelAfter result =
13641375 . updFailActions
13651376 . updNumActionsPerTable
13661377 . updClosedTableSizes
1378+ . updDupTableActionLog
1379+ . updParentTable
13671380 where
13681381 -- === Tags
13691382
@@ -1500,6 +1513,69 @@ updateStats action lookUp modelBefore _modelAfter result =
15001513 }
15011514 _ -> stats
15021515
1516+ updParentTable stats = case (action, result) of
1517+ (New {}, MEither (Right (MTableHandle tbl))) ->
1518+ stats {
1519+ parentTable = Map. insert (Model. tableHandleID tbl)
1520+ (Model. tableHandleID tbl)
1521+ (parentTable stats)
1522+ }
1523+ (Open {}, MEither (Right (MTableHandle tbl))) ->
1524+ stats {
1525+ parentTable = Map. insert (Model. tableHandleID tbl)
1526+ (Model. tableHandleID tbl)
1527+ (parentTable stats)
1528+ }
1529+ (Duplicate ptblVar, MEither (Right (MTableHandle tbl))) ->
1530+ let -- immediate and ultimate parent table ids
1531+ iptblId , uptblId :: Model. TableHandleID
1532+ iptblId = getTableHandleId (lookUp ptblVar)
1533+ uptblId = parentTable stats Map. ! iptblId
1534+ in stats {
1535+ parentTable = Map. insert (Model. tableHandleID tbl)
1536+ uptblId
1537+ (parentTable stats)
1538+ }
1539+ _ -> stats
1540+
1541+ updDupTableActionLog stats | MEither (Right _) <- result =
1542+ case action of
1543+ Lookups ks tableVar
1544+ | not (null ks) -> updateLastActionLog tableVar
1545+ RangeLookup r tableVar
1546+ | not (emptyRange r) -> updateLastActionLog tableVar
1547+ NewCursor _ tableVar -> updateLastActionLog tableVar
1548+ Updates upds tableVar
1549+ | not (null upds) -> updateLastActionLog tableVar
1550+ Inserts ins tableVar
1551+ | not (null ins) -> updateLastActionLog tableVar
1552+ Deletes ks tableVar
1553+ | not (null ks) -> updateLastActionLog tableVar
1554+ Close tableVar -> updateLastActionLog tableVar
1555+ _ -> stats
1556+ where
1557+ -- add the current table to the front of the list of tables, if it's
1558+ -- not the latest one already
1559+ updateLastActionLog :: GVar Op (WrapTableHandle h IO k v blob ) -> Stats
1560+ updateLastActionLog tableVar =
1561+ case Map. lookup pthid (dupTableActionLog stats) of
1562+ Just (thid' : _)
1563+ | thid == thid' -> stats -- the most recent action was via this table
1564+ malog ->
1565+ let alog = thid : fromMaybe [] malog
1566+ in stats {
1567+ dupTableActionLog = Map. insert pthid alog
1568+ (dupTableActionLog stats)
1569+ }
1570+ where
1571+ thid = getTableHandleId (lookUp tableVar)
1572+ pthid = parentTable stats Map. ! thid
1573+
1574+ emptyRange (R. FromToExcluding l u) = l >= u
1575+ emptyRange (R. FromToIncluding l u) = l > u
1576+
1577+ updDupTableActionLog stats = stats
1578+
15031579 getTableHandleId :: ModelValue (ModelState h ) (WrapTableHandle h IO k v blob )
15041580 -> Model. TableHandleID
15051581 getTableHandleId (MTableHandle th) = Model. tableHandleID th
@@ -1620,6 +1696,8 @@ data FinalTag =
16201696 | NumTableActions String
16211697 -- | Total /logical/ size of a table
16221698 | TableSize String
1699+ -- | Number of interleaved actions on duplicate tables
1700+ | DupTableActionLog String
16231701 deriving stock Show
16241702
16251703-- | This is run only after completing every action
@@ -1633,6 +1711,7 @@ tagFinalState' (getModel -> ModelState finalState finalStats) = concat [
16331711 , tagNumTables
16341712 , tagNumTableActions
16351713 , tagTableSizes
1714+ , tagDupTableActionLog
16361715 ]
16371716 where
16381717 tagNumLookupsResults = [
@@ -1686,6 +1765,13 @@ tagFinalState' (getModel -> ModelState finalState finalStats) = concat [
16861765 , size <- Map. elems (openSizes `Map.union` closedSizes)
16871766 ]
16881767
1768+ tagDupTableActionLog =
1769+ [ (" Interleaved actions on table duplicates" ,
1770+ [DupTableActionLog (showPowersOf 2 n)])
1771+ | (_, alog) <- Map. toList (dupTableActionLog finalStats)
1772+ , let n = length alog
1773+ ]
1774+
16891775{- ------------------------------------------------------------------------------
16901776 Utils
16911777-------------------------------------------------------------------------------}
0 commit comments