Datamigrering kan inte ske isolerat, den måste utvecklas parallellt med COBOL-applikationerna som läser och skriver dessa datamängder. Den begränsningen definierar hela utmaningen med VSAM-modernisering. VSAM (Virtual Storage Access Method) är inte bara ett filformat. Det är datakontraktet mellan program, den implicita specifikationen, definierad ingenstans förutom i FD-poster och SELECT-klausuler, som styr hur varje program i ett företagssystem producerar och konsumerar dess mest kritiska affärsdata. En enda ändring av postlayouten som inte återspeglas i varje program som läser den posten producerar datakorruption som kanske inte dyker upp förrän en regulatorisk rapport körs på data som inte längre betyder vad det konsumerande programmet förväntade sig att den skulle betyda.
De organisationer som lyckas med VSAM-datamodernisering är inte de som börjar med målschemat. Det är de som börjar med en fullständig, evidensbaserad förståelse av vad VSAM-filerna innehåller, hur de är strukturerade, vilka program som använder dem, i vilka mönster och vilka implicita kontrakt som finns mellan producenter och konsumenter. Den förståelsen, analysen av VSAM-filstrukturen, är förutsättningen för varje efterföljande beslut: vilka VSAM-datauppsättningar som mappas till relationstabeller, vilka som kräver olika målarkitekturer, vilka postlayouter som behöver precisionsbevarande datatypkonverteringar och vilka delade datauppsättningar som måste migreras som koordinerade enheter snarare än oberoende.
Delade datamängder behöver samordnad migrering
SMART TS XL extraherar automatiskt varje detalj i postlayouten som målschemadesignen kräver.
TA REDA PÅ MER…De fyra VSAM-organisationerna och vad var och en kräver
VSAM-datauppsättningar finns i fyra distinkta organisationer. Var och en har en annan strukturell egenskap, ett annat typiskt åtkomstmönster och en annan naturlig mappning jämfört med moderna målarkitekturer. Att behandla alla VSAM-datauppsättningar identiskt, och masskonvertera var och en till en relationstabell, producerar mål som fungerar för vissa datauppsättningar och presterar dåligt eller misslyckas funktionellt för andra.
KSDS, Key-Sequenced Data Set, är den vanligaste VSAM-organisationen. Poster är fysiskt ordnade efter en primärnyckel (primnyckeln), vilket möjliggör både direkt åtkomst med nyckel och sekventiell åtkomst i nyckelordning. KSDS-filer har valfritt alternativa index, sekundära nyckelsökvägar som tillåter hämtning via andra fält än primnyckeln. Det naturliga målet för en KSDS är en relationstabell där primnyckeln blir primärnyckel och alternativa index blir SQL-index.
ESDS, Entry-Sequenced Data Set, lagrar poster i den ordning de skrevs. Det finns ingen nyckel, poster adresseras med sin fysiska byte-offset (RBA: Relative Byte Address). ESDS-filer används vanligtvis för loggliknande data: revisionsloggar, transaktionsjournaler, händelseströmmar. Det naturliga målet för en ESDS är en relationstabell med endast tillägg, en händelseström (Kafka-ämne) eller en tidsseriedatabas, beroende på hur de konsumerande programmen kommer åt data.
RRDS, Relative Record Data Set, lagrar poster med fast längd adresserade med ett relativt postnummer. Varje plats i filen motsvarar ett postnummer; platser kan vara tomma (raderade). RRDS-filer används för direktåtkomstscenarier där postnumret är meningsfullt för applikationen, ofta som enkla uppslagstabeller eller hashbaserad lagring. Det naturliga målet är en relationstabell med en numerisk sekvensidentifierare, eller en uppslagsstruktur i minnet om datamängden är liten och används ofta.
LDS, Linear Data Set, är en byte-adresserbar lagring utan någon poststruktur synlig för VSAM. Den används av applikationer (vanligtvis DB2, Java-arbetsbelastningar eller anpassade program) som hanterar sitt eget interna format inom VSAM-byteintervallet. LDS-filer kan inte analyseras via vanliga COBOL FD-poster, deras struktur finns bara i applikationslagret som skriver dem.
Analysresultatet för varje datamängd måste identifiera vilken organisation den använder, eftersom organisationen avgör allt nedströms: målarkitektur, åtkomstmönster och den specifika analys som krävs för att förstå dess struktur.
Problemet med analys av postlayout
Postlayouten är den analytiskt mest komplexa dimensionen av VSAM-strukturanalys. Till skillnad från ett relationsschema där varje kolumn har en definierad typ, namn och begränsning som upprätthålls av databasmotorn, har VSAM-poster ingen självbeskrivande struktur. Layouten finns helt och hållet i COBOL FD-posten, och FD-poster är sällan enkla.
FD-poster och COPY-medlemmar
Poststrukturen för en VSAM-datauppsättning definieras i FILE DESCRIPTION (FD)-posten i COBOL DATA DIVISION. I väl underhållna kodbaser refererar FD-posten till en COPY-medlem, en delad copybook som definierar postlayouten och inkluderas av varje program som använder datauppsättningen:
cobol
FILE SECTION.
FD CUSTOMER-FILE
LABEL RECORDS ARE STANDARD
RECORD CONTAINS 250 CHARACTERS.
01 CUSTOMER-RECORD.
COPY CUSTMSTR.
COPY-medlemmen CUSTMSTR definierar den faktiska fältlayouten. Om 47 program inkluderar CUSTMSTR, så delar 47 program ett beroende av den postlayout som definieras. Ett fältbyte i CUSTMSTR påverkar alla 47. Detta är kopplingsproblemet för kopieböcker tillämpat på data: VSAM-postlayouten är ett delat beroende som inte kan ändras utan att koordinera varje program som använder det.
För migreringsanalys måste varje FD-post spåras till sin kopiabok, och varje kopiabok måste mappas till varje program som inkluderar den. Beroendediagrammet för delad layout är grunden för att förstå migreringens omfattning.
OMDEFINERAR: Flera layouter, en post
Ocuco-landskapet REDEFINES Det är i klausulen som VSAM-postanalys blir verkligt komplex. REDEFINES tillåter olika fälttolkningar att läggas över samma fysiska lagring. En VSAM-post som innehåller en transaktionstypkod kan använda REDEFINES för att tolka de återstående bytena olika beroende på den koden:
cobol
01 TRANSACTION-RECORD.
05 TXN-TYPE PIC X(2).
05 TXN-COMMON-DATA PIC X(48).
05 TXN-DETAIL REDEFINES TXN-COMMON-DATA.
10 TXN-PAYMENT.
15 PAY-AMOUNT PIC S9(11)V99 COMP-3.
15 PAY-CURRENCY PIC X(3).
15 PAY-METHOD PIC X(2).
15 FILLER PIC X(28).
05 TXN-WITHDRAWAL REDEFINES TXN-COMMON-DATA.
10 WDR-AMOUNT PIC S9(11)V99 COMP-3.
10 WDR-ACCOUNT PIC 9(12).
10 WDR-BRANCH PIC 9(5).
10 FILLER PIC X(18).
Den här posten har inte en layout utan tre, beroende på TXN-TYPEI det relationella målschemat kräver detta vanligtvis antingen en polymorf tabelldesign (en bred tabell med nullbara kolumner för varje variant), en normaliserad design (föräldrarad plus typspecifika underrader) eller en JSON-kolumn som innehåller variantdata. Inget av dessa beslut kan fattas utan att analysera vad TXN-TYPE värden finns i data och vilka REDEFINES-varianter som faktiskt används.
En fullständig analys av postlayout måste:
- Identifiera varje REDEFINES-hierarki i varje FD-post
- Bestäm vilken REDEFINES-variant som är aktiv under vilka förhållanden (kräver programlogikanalys, inte bara FD-analys)
- Dokumentera fälttyper, längder och packad decimalprecision för varje variant
- Rekommendera lämplig normaliseringsstrategi för målschemat
COMP-3 och numerisk precision
COBOLs PIC S9(11)V99 COMP-3 (packad decimal) har specifika precisions- och skalegenskaper som inte har någon direkt motsvarighet i SQL-standarddatatyper. V indikerar en implicit decimalpunkt, lagras värdet som ett heltal med en implicit skala på 2 decimaler. COMP-3 packar två decimalsiffror per byte, där den sista halvbyten innehåller tecknet.
När det här fältet migreras till en relationsdatabas är rätt SQL-mål DECIMAL(13, 2), Inte FLOAT, vilket skulle introducera avrundningsfel, och inte INTEGER, vilket skulle förlora decimalerna. För finansiella system där COMP-3-fält innehåller monetära belopp är precisionskravet inte förhandlingsbart. En migrering som konverterar PIC S9(11)V99 COMP-3 till en flyttal i målschemat introducerar avrundningsfel som ackumuleras över batchkörningar och kan påverka den lagstadgade rapporteringen.
Varje COMP-3-fält i varje FD-post måste dokumenteras med exakt precision, skala och teckenkonvention innan målschemadesignen påbörjas.
Analysera VSAM-åtkomstmönster i COBOL-källa
FD-posten beskriver vad som finns i posten. COBOL PROCEDURE DIVISION beskriver hur programmet använder den. Båda krävs för en fullständig strukturell analys. Åtkomstmönsteranalysen undersöker varje filåtkomstverb i varje program som berör datamängden.
SELECT-klausulen: Första signalen
SELECT-klausulen i ENVIRONMENT DIVISION anger hur COBOL-programmet kommer att komma åt VSAM-filen:
cobol
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT CUSTOMER-FILE
ASSIGN TO CUSTFILE
ORGANIZATION IS INDEXED
ACCESS MODE IS DYNAMIC
RECORD KEY IS CUST-PRIME-KEY
ALTERNATE RECORD KEY IS CUST-ALT-KEY
WITH DUPLICATES
FILE STATUS IS WS-CUST-STATUS.
Denna SELECT-klausul avslöjar:
ORGANIZATION IS INDEXED→ KSDSACCESS MODE IS DYNAMIC→ programmet använder både sekventiell och slumpmässig åtkomstALTERNATE RECORD KEY IS CUST-ALT-KEY WITH DUPLICATES→ ett alternativt index finns och det här programmet använder det
Dynamiskt åtkomstläge är särskilt viktigt: ett program som öppnar ett KSDS i DYNAMISKT läge kan använda READ med en nyckel för direktåtkomst och READ NEXT för sekventiell skanning från en positionerad punkt. Båda åtkomstmönstren måste replikeras i målet, vilket kan kräva stöd för både direkt uppslagning (primärnyckelfråga) och områdesskanning (ordnad genomsökning) i relationsschemat.
Åtkomstverb och deras migrationskonsekvenser
Varje filåtkomstverb avslöjar en annan dimension av hur programmet interagerar med VSAM-datasetet:
LÄS (direkt): READ CUSTOMER-FILE KEY IS WS-CUST-KEY, direkt nyckelsökning. Kartor till SELECT ... WHERE primary_key = ?De flesta KSDS-program använder detta mönster; det översätts direkt till en relationell indexerad sökning.
LÄS (sekventiell): READ CUSTOMER-FILE NEXT RECORD, sekventiell skanning från aktuell position. Kartor till SELECT ... ORDER BY primary_key med markörpositionering. Det implicita ordningsberoendet, program som förlitar sig på VSAM:s naturliga nyckelordning för sekventiell bearbetning, måste explicit bevaras i målet.
START: START CUSTOMER-FILE KEY >= WS-SEARCH-KEY följd av READ NEXT, områdessökning från en ofullständig nyckelposition. Kartlägger till en områdesfråga: SELECT ... WHERE primary_key >= ? ORDER BY primary_keyProgram som använder START etablerar en nedre gräns för sekventiell skanning; detta är ett kritiskt åtkomstmönster för KSDS-filer som inte har någon enkel motsvarighet om inte måltabellen har samma nyckelordning.
SKRIVA: Infogar en ny post efter nyckel. Mappar till INSERT INTOOm VSAM-filen har alternativa index måste skrivningen bibehålla konsistens med dessa index. I VSAM är detta automatiskt; i en relationsdatabas krävs antingen en databasutlösare eller kod på applikationsnivå för att underhålla motsvarande sekundära indextabeller.
SKRIVA OM: Uppdaterar en post på plats. Posten måste vara spärrad för närvarande (efter en LÄSNING med spärrningsavsikt). Mappar till UPDATE ... WHERE primary_key = ?REWRITE är ett läs-modifiera-skriv-mönster; migreringen måste bevara transaktionell integritet under läsning och skrivning.
DELETE: Tar bort en post med nyckel. I KSDS-filer är DELETE en fysisk borttagning. Program som förväntar sig att den borttagna platsen inte ska vara tillgänglig för framtida sekventiella skanningar är beroende av detta fysiska borttagningsbeteende. En mjuk borttagning (logisk borttagningsflagga) i målet producerar inte motsvarande beteende om inte alla förbrukande program uppdateras för att filtrera logiskt borttagna poster.
Alternativ indexanvändning: Det dolda beroendet
Alternativa index på KSDS-filer är ett av de oftast förbisedda beroenden vid VSAM-migrering. Ett alternativt index tillåter ett program att komma åt ett KSDS via ett annat fält än primnyckeln. Det alternativa indexet är i sig en separat VSAM-datauppsättning (en PATH) som måste underhållas synkroniserad med basklustret.
Ett program som har åtkomst till CUSTOMER-FILE genom sin alternativa nyckel CUST-ALT-KEY har ett beroende som är osynligt om endast basklustrets FD-post analyseras. Migreringen måste:
- Identifiera vilka program som använder vilka alternativa nycklar (synligt i SELECT-klausulen)
ALTERNATE RECORD KEYdeklarationer) - Mappa varje alternativ nyckel till motsvarande SQL-index i måltabellen
- Säkerställ att INSERT- och DELETE-operationerna på måltabellen automatiskt bibehåller motsvarigheten till det alternativa indexet, vanligtvis genom unika eller icke-unika SQL-index som databasmotorn underhåller transparent.
Analysen måste räkna upp alla alternativa index för varje KSDS-datauppsättning och mappa vart och ett till dess förbrukande program.
Problemet med delade datamängder: Implicita datakontrakt
VSAM-filer delas ofta mellan flera program och flera JCL-jobbsteg. Denna delning skapar implicita datakontrakt, överenskommelser mellan program om postlayout, nyckelintervall och åtkomstmönster som inte existerar någonstans förutom i själva koden.
Det delade datamängdernas beroende har två dimensioner:
Relationer mellan producent och konsument. Program A skriver poster som program B läser. Postlayouten, nyckelvärdena och ordningen som program A producerar måste matcha exakt vad program B förväntar sig att konsumera. Om A och B migreras oberoende av varandra till olika målscheman utan att koordinera det delade datakontraktet blir resultatet tyst datakorruption: B:s läsningar lyckas mot måldatabasen men returnerar data i ett format som B:s logik inte hanterar korrekt.
Samtidig åtkomst över jobbsteg. En JCL-jobbström kan ha flera steg, där varje steg kör ett annat program mot samma VSAM-datauppsättning i sekvens. Steg 1 skriver, steg 2 läser och transformerar, steg 3 skriver resultaten. Migreringen måste bevara detta sekventiella beroende, den ordning i vilken program kommer åt och ändrar den delade datauppsättningen är en del av systemets beteendespecifikation.
En fullständig analys av delade dataset måste:
- Räkna upp varje VSAM-datauppsättning och varje program som har åtkomst till den.
- Klassificera varje programs åtkomst som producent (WRITE/REWRITE/DELETE), konsument (READ) eller båda.
- Dokumentera JCL-jobbkontexten där varje program körs, vilket steg, i vilket jobb, i vilken schemaläggarberoendekedja
- Identifiera producent-konsument-par där producentens utdataformat måste exakt matcha konsumentens förväntade indataformat.
Denna analys kan inte göras genom att undersöka ett enskilt program isolerat. Den kräver strukturell analys över flera program och JCL.
Resultaten före migreringen: Vad analysen måste producera
En strukturell VSAM-analys som är tillräcklig för planering av datamodernisering producerar sex resultat:
Leverans 1: VSAM-datauppsättningsinventering
Varje VSAM-datauppsättning i miljön, med: datauppsättningens organisation (KSDS/ESDS/RRDS/LDS), genomsnittlig och maximal postlängd, uppskattat antal poster (från JCL SPACE-parametrar eller katalogposter), nyckelstruktur (primär nyckeloffset, längd; alternativa nyckelstrukturer) och om datauppsättningen har alternativa index.
Leverans 2: Katalog för postlayout
För varje dataset, varje FD-post och de kopieböcker den refererar till, med: alla fältdefinitioner inklusive REDEFINES-hierarkier, varje COMP-3-fält med dess exakta precision och skala, varje binärt (COMP/COMP-5) fält med dess bytelängd, varje element med variabel längd (INTRÄDER BEROENDE PÅ med dess styrande fält) och varje villkorlig variant eller layoutvariant som impliceras av REDEFINES.
Leverans 3: Klassificering av åtkomstmönster per program
För varje program som åtkommer varje datamängd: SELECT-klausulens egenskaper (organisation, åtkomstläge, alternativ nyckelanvändning), den kompletta uppsättningen åtkomstverb som används (LÄS/STARTA/SKRIV/OMSKRIV/TA BORT), om programmet använder sekventiell åtkomst och beror på nyckelordning, vilka alternativa index programmet använder och om programmet har läs-ändra-skriv-mönster (implicita transaktionskrav).
Leverans 4: Delad datamängdskarta
En riktad graf där noder är VSAM-datauppsättningar och program, och kanter representerar åtkomstrelationer med sin typ (läs/skriv). Grafen visar varje producent, varje konsument, producent-konsument-par och JCL-jobbsekvenskontexten för varje åtkomst.
Resultat 5: Rekommendationer för målscheman
För varje VSAM-datauppsättning, den rekommenderade målarkitekturen baserat på dess organisation och åtkomstmönster:
| VSAM-typ | Primär åtkomstmönster | Rekommenderat mål |
|---|---|---|
| KSDS, endast direkt nyckelåtkomst | Punktsökningar efter primärnyckel | Relationell tabell, indexerad |
| KSDS, med STARTA/LÄS NÄSTA | Avståndsskanningar i nyckelordning | Relationell tabell med klustrat index |
| KSDS med alternativa index | Åtkomst med flera sökvägar | Relationell tabell med flera index |
| ESDS, endast tillägg | Sekventiell tillägg, ingen nyckel | Endast tilläggstabell, händelseström eller logg |
| ESDS, med RBA-åtkomst | Byte-offset-positionering | Objektlagring med metadataindex |
| RRDS | Åtkomst till registernummer | Relationell tabell med sekvenskolumn |
| Stora KSDS (bulk, analyser) | Fullständiga sekventiella skanningar | Kolumnlagring eller datasjö |
| LDS | Applikationshanterat internt format | Kräver analys av applikationslagret |
Leverans 6: Precisionskänsligt fältregister
Varje COMP-3-, COMP-, COMP-5- och flyttalsfält i varje datamängd, med dess COBOL-definition, korrekt SQL-datatypmappning och en flagga för alla fält där mappningen kräver precisionsvalidering före och efter migrering.
Vad som skiljer VSAM-analys från relationell schemaanalys
Team som har erfarenhet av att migrera mellan relationsdatabaser underskattar ibland VSAM-analys eftersom de tillämpar den mentala modellen för schemamigrering: extrahera DDL, omdesigna schemat, migrera data. VSAM har ingen DDL i databasbemärkelse. Schemat är distribuerat över källkoden, i FD-poster, i kopieböcker, i SELECT-klausuler och i PROCEDURE DIVISION-logiken som avgör vilken REDEFINES-variant som är aktiv för en given post.
Tre egenskaper gör VSAM-analys strukturellt annorlunda:
Schemat finns i koden. Postlayouten för en VSAM-datauppsättning definieras i COBOL-källkoden, inte i en databaskatalog. Att hitta den kräver att källkoden analyseras. Att ändra den kräver att alla program som delar kopieboken koordineras. Att förstå alla dess varianter kräver att man analyserar programlogik, inte bara FD-posten.
Åtkomstmönster är implicita i programbeteendet. En relationsdatabas exponerar frågemönster genom EXPLAIN-planer och frågeloggar. VSAM-åtkomstmönster är endast synliga i PROCEDURE DIVISION för de program som öppnar filen. Att förstå om ett program är beroende av nyckelordning, alternativ indexåtkomst eller intervallskanning kräver kodanalys.
Delade datamängder skapar dolda kontrakt. I en relationsdatabas är ett schema en artefakt på databasnivå som alla konsumenter delar och ser. I VSAM är postlayouten inbäddad i varje programs kopieringsbok. Två program kan ha divergerade kopior av vad som nominellt är samma postlayout, och att upptäcka denna divergens kräver att man jämför kopieringsboksdefinitioner mellan program, inte att man inspekterar en enda schemadefinition.
Hur SMART TS XL Utför VSAM-strukturanalys
SMART TS XLÄr statisk kodanalys analyserar varje element i VSAM-strukturen som finns i COBOL-källkoden: FD-poster, COPY-medlemsexpansioner, SELECT-klausuldeklarationer (organisation, åtkomstläge, primära och alternativa nyckelspecifikationer) och varje filåtkomstverb i PROCEDURE DIVISION. För varje VSAM-datauppsättning producerar analysen åtkomstmönsterklassificeringen, postlayouten med full REDEFINES-upplösning och COMP-3-fältregistret med precisionsmetadata.
Mappningen av applikationsberoenden bygger den delade datamängden: varje program som åtkommer varje VSAM-datamängd, klassificerat efter åtkomsttyp, med identifierade producent-konsument-relationer och löst delningsgraf för kopieringsboken. När 47 program delar en kopieringsbok som definierar en VSAM-postlayout, gör beroendemappningen alla 47 synliga innan något migreringsbeslut fattas, inte efter att en layoutändring har orsakat oväntade skador på 47 program.
JCL -expansionsfunktionen tillhandahåller det operativa sammanhanget: vilka JCL-jobbsteg refererar till vilka VSAM-datauppsättningar i sina DD-satser, i vilken sekvens, i vilka jobbströmmar. De producent-konsument-relationer som finns på JCL-jobbnivå, där steg 1 skriver till en VSAM-datauppsättning som steg 3 läser, är synliga i JCL-beroendeanalysen, vilket möjliggör migreringssekvensering som bevarar de operativa ordningsberoenden som batchschemat framtvingar.
Effektanalysfunktionen besvarar frågan som föregår varje beslut om VSAM-migrering: om layouten för denna datamängd ändras, vilka program påverkas? Effektomfattningen, varje program som delar relevant kopia, varje JCL-steg som refererar till datamängden, räknas upp innan migreringsarbetet påbörjas, vilket ger grunden för samordnad migreringsplanering snarare än att upptäcka berörda program ett trasigt program i taget.
Företagssökningsfunktionen gör hela VSAM - inventeringen sökbar genom hela moderniseringsprogrammet: hitta alla program som har åtkomst till en specifik VSAM-datauppsättning, varje kopiebok som definierar en specifik postlayout, varje program som använder START/READ NEXT-mönster (som indikerar ordningsberoenden), varje fält definierat som COMP-3 (som kräver precisionsmedveten målmappning), på några sekunder, över miljontals rader COBOL.
Som beskrivs i samband med migrera IMS- och VSAM-datastrukturer tillsammans med COBOL-program, datamigrering och kodanalys måste ske parallellt. SMART TS XLVSAM:s strukturella analys tillhandahåller den inventering som gör den parallellismen hanterbar, de delade postlayouterna, åtkomstmönstren och producent-konsument-relationerna som avgör om datamigrering kan ske oberoende eller måste koordineras med programändringar.
Strukturen du förstår är strukturen du kan migrera
VSAM-filstrukturanalysen är inte en omkostnadskostnad i ett moderniseringsprogram. Den utgör beslutsfattandets grund. Målschemat kan inte utformas utan att känna till varianterna av postlayouten. Migreringen kan inte sekvenseras utan att känna till producent-konsument-relationerna. Precisionen i COMP-3-fält kan inte bevaras utan att veta vilka fält som kräver decimalmedvetna måltyper.
Varje moderniseringsprogram som hoppar över den här analysen upptäcker vad det missade under migreringskörningen, när en REDEFINES-variant som inte analyserades producerar felaktiga poster i målet, när en delad datamängd migreras utan att koordinera alla dess konsumenter, när en intervallskanning som förlitade sig på VSAM:s nyckelordningsreturer resulterar i odefinierad ordning från en måltabell som inte utformades med ett klustrat index. Dessa upptäckter under körningen kostar multiplar av vad analysen skulle ha kostat under planeringen.
Förstå strukturen först. Migrera data sedan. Sekvensen är inte en formalitet. Det är skillnaden mellan en migrering som ger korrekta resultat och en som producerar data som ser rätt ut tills den första regulatoriska revisionen körs.