Translate

Mostrar mensagens com a etiqueta SEARCH. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta SEARCH. Mostrar todas as mensagens

quinta-feira, 14 de julho de 2022

☕💥 Arrays em COBOL: O Poder Oculto do OCCURS, SSRANGE e a Guerra Contra a Invasão de Memória

 

Bellacosa Mainframe e as tabelas internas no COBOL occurs e arrays

☕💥 Arrays em COBOL: O Poder Oculto do OCCURS, SSRANGE e a Guerra Contra a Invasão de Memória

Ou como evitar transformar seu Address Space em um filme de terror para Sysprogs



Introdução

Existe um momento na vida de todo desenvolvedor COBOL júnior em que ele descobre duas verdades universais:

A primeira é que OCCURS parece simples até deixar de ser simples.

A segunda é que existe uma entidade maligna chamada:

SSRANGE

capaz de transformar uma manhã tranquila em uma reunião emergencial envolvendo desenvolvimento, suporte, infraestrutura, DBA, operador e um sysprog segurando uma caneca de café já fria.

E tudo isso por causa de um pequeno detalhe:

MOVE WS-NOME(9999)

quando a tabela possui apenas:

OCCURS 100 TIMES.

Bem-vindo ao fascinante mundo das tabelas COBOL.


Capítulo 1 – O que é OCCURS?

OCCURS é o mecanismo utilizado pelo COBOL para criar estruturas repetitivas.

Em linguagens modernas chamaríamos isso de:

  • Array

  • Vetor

  • Lista fixa

  • Matriz

Exemplo:

01 CLIENTES.

   05 CLIENTE OCCURS 10 TIMES.

      10 NOME PIC X(30).
      10 IDADE PIC 99.

Memória:

CLIENTE(1)
CLIENTE(2)
CLIENTE(3)
...
CLIENTE(10)

COBOL simplesmente reserva um bloco contínuo.


A origem histórica

Década de 60.

Memória era absurdamente cara.

IBM 1401

4 KB

IBM System/360

256 KB

370

1 MB

Não existia:

  • Java Collections

  • Python List

  • C++ Vector

Era necessário reservar memória antecipadamente.

Daí nasceu:

OCCURS

Curiosidade histórica

Os engenheiros da IBM chamavam essas estruturas de:

Table Handling

Muito antes da expressão Array Processing se popularizar.


Capítulo 2 — Como a memória é organizada

Exemplo:

01 TAB.

   05 ITEM OCCURS 5 TIMES.

      10 CODIGO PIC 9(5).

Cada item ocupa:

5 bytes

Total

25 bytes

Layout:

0000 ITEM(1)
0005 ITEM(2)
0010 ITEM(3)
0015 ITEM(4)
0020 ITEM(5)

Acesso:

MOVE ITEM(3) TO WS-X

COBOL faz:

Base + ((3-1)*5)

Capítulo 3 – O Terror do Out of Bounds

Tabela:

05 CLIENTE OCCURS 100 TIMES.

Código:

MOVE NOME(101)

Problema.

A posição não existe.


Antigamente

Compilador:

NOSSRANGE

Padrão.

Nenhuma verificação.

Resultado:

Leitura aleatória.

Sobrescrever memória.

Corrupção.


O verdadeiro vilão

Imagine:

01 TABELA.

05 DADOS OCCURS 100 TIMES.

05 FLAG-FINAL PIC X.

Erro:

MOVE "S" TO DADOS(101)

Na prática:

FLAG-FINAL = S

ou pior.

Modifica outra estrutura.


Isso é invasão de memória?

Sim.

Tecnicamente:

Buffer overflow

Memory overwrite

Storage corruption


Capítulo 4 — Address Space

No zOS cada Job possui.

Address Space.

Exemplo

JOB1234



Private Area


LSQA


SWA


Subpools


Heap


Stack

Seu programa COBOL vive ali.


Se escrever fora da tabela:

pode corromper:

Working Storage

Heap

LE Runtime

Control Blocks


Em casos extremos:

S0C4

S878

U4038


Capítulo 5 — SSRANGE

A melhor invenção desde o café expresso.

Compilação:

SSRANGE

ou

CBL SSRANGE

Exemplo

MOVE WS-NOME(101)

Resultado:

Abend imediato.

Mensagem:

IGZxxxx

Subscript out of range


Excelente para:

Homologação

Teste

QA


Produção?

Normalmente:

NOSSRANGE

Performance melhor.


Dica Bellacosa

Desenvolvimento

SSRANGE

Produção

NOSSRANGE


Capítulo 6 — Índices

Ruim:

77 WS-I PIC 999.

Melhor:

05 CLIENTE OCCURS 100 TIMES
   INDEXED BY IDX.

SET

SET IDX TO 1

Próximo

SET IDX UP BY 1

Anterior

SET IDX DOWN BY 1

Por que índice é melhor?

Subscript:

CLIENTE(I)

Cálculo toda vez.


Index

Endereço pronto.

Ponteiro interno.

Mais rápido.


Capítulo 7 – Navegação

Crescente

SET IDX TO 1


PERFORM UNTIL IDX > MAX

PROCESSA

SET IDX UP BY 1

END-PERFORM

Decrescente

SET IDX TO MAX


PERFORM UNTIL IDX = 0


PROCESSA


SET IDX DOWN BY 1


END-PERFORM

Muito usado em:

Compressão

Ordenação

Rollback


Capítulo 8 — SEARCH

Busca sequencial.

SEARCH CLIENTE


AT END


DISPLAY "NAO ACHOU"


WHEN ID = WS-ID


DISPLAY NOME

END-SEARCH

Complexidade

O(n)


100 mil registros.

50 mil leituras médias.


SEARCH ALL

Arma secreta.

Busca binária.


Tabela obrigatoriamente ordenada.

SEARCH ALL CLIENTE


WHEN ID(IDX)=WS-ID


DISPLAY "ACHOU"

END-SEARCH

Complexidade

O(log n)


1000000 itens.

Comparações:

~20


Magia matemática.


Capítulo 9 — OCCURS DEPENDING ON

Tabela variável.

05 QTDE PIC 9(4).


05 CLIENTE OCCURS 1 TO 1000 TIMES

DEPENDING ON QTDE.

Muito usado em:

MQ

Copybooks

APIs

Arquivos


Capítulo 10 — Bidimensional

Exemplo.

Agência x Dia

05 MOVIMENTO.

10 AG OCCURS 100.

15 DIA OCCURS 31.

20 TOTAL PIC 9(10).

Uso:

TOTAL(10,15)

Agência 10.

Dia 15.


Tridimensional

ANO

MES

DIA
VENDAS(2026,6,23)

N dimensões

Teoricamente ilimitado.

Exemplo.

Banco.

País

Estado

Agência

Conta

Produto

Dia


Capítulo 11 — Ordenação

Tabela ordenada.

ASCENDING KEY

Muito útil para:

SEARCH ALL

Caches

Lookup


Capítulo 12 – Quando usar tabela

Excelente:

Parâmetros

Cache

Código UF

Tabela IR

CEP

Conversões


Ruim:

Milhões registros.


Melhor:

DB2

VSAM

IMS


Capítulo 13 – Performance

SEARCH

O(n)

SEARCH ALL

O(log n)

Index

Muito rápido

Subscript

Mais lento

SSRANGE

Seguro

NOSSRANGE

Rápido


Easter Egg COBOL

Existe uma lenda entre veteranos de mainframe.

Diz-se que em algum datacenter esquecido dos anos 80 existe um programa COBOL compilado com:

NOSSRANGE
OPT(2)
FASTSRT
ARITH(EXTEND)

executando desde 1987.

Ninguém sabe exatamente o que ele faz.

Ninguém possui o código-fonte.

Ninguém ousa recompilar.

Mas toda madrugada, às 02h17, ele produz um relatório financeiro perfeito, movimenta bilhões de dólares e desaparece novamente nas profundezas do JES2.

Os sysprogs apenas observam o spool, tomam um gole de café e repetem o antigo mantra do reino z/OS:

"Se está funcionando há 39 anos, não toque."


Conclusão

OCCURS é muito mais do que um simples array.

É uma das construções mais antigas, elegantes e eficientes já criadas para processamento em lote de grande volume.

Dominar:

  • OCCURS

  • INDEXED BY

  • SET

  • SEARCH

  • SEARCH ALL

  • SSRANGE

  • OCCURS DEPENDING ON

  • Tabelas multidimensionais

  • Navegação UP e DOWN

  • Layout de memória

  • Address Space do z/OS

é um dos marcos que separam o Padawan COBOL do Cavaleiro do Batch Jedi Council.

Porque no universo do Mainframe existe uma verdade absoluta:

"DB2 pode falhar, CICS pode reciclar, VSAM pode corromper, mas um OCCURS acessado fora dos limites sempre encontrará uma maneira criativa de arruinar o dia de alguém."

terça-feira, 25 de fevereiro de 2020

☕💥 Os 10 Padrões Secretos de Arrays em COBOL Mainframe

 

Bellacosa Mainframe e 10 padroes secretos de arrays

☕💥 Os 10 Padrões Secretos de Arrays em COBOL Mainframe

Ou como descobrir que você já usava algoritmos de entrevistas do LeetCode muito antes deles virarem moda



Introdução

Existe uma curiosidade engraçada no mundo da programação.

Um desenvolvedor Java estuda LeetCode.

Um desenvolvedor Python assiste vídeos sobre algoritmos.

Um engenheiro C++ compra livros de Competitive Programming.

Enquanto isso...

Um programador COBOL de banco com vinte anos de experiência está processando 300 milhões de registros no Batch Noturno utilizando exatamente os mesmos algoritmos...

Mas chama tudo de:

"andar na tabela"

"fazer acumulado"

"pesquisa binária"

"comparar dois índices"

"janela de análise"

E provavelmente faz isso tomando café às 3 da manhã olhando um SDSF.

A verdade é que muitos dos algoritmos mais famosos ensinados atualmente em universidades e plataformas de entrevistas já existem no universo COBOL há décadas.

OCCURS.

INDEXED BY.

SEARCH.

SEARCH ALL.

SET UP.

SET DOWN.

ASCENDING KEY.

Tabelas auxiliares.

Acumuladores.

Áreas de trabalho.

Tudo isso forma um verdadeiro arsenal de algoritmos.

E hoje vamos conhecer os 10 padrões clássicos de Arrays, explicados para um Padawan COBOL.


Padrão 1 — Two Pointers

Os Dois Jedi da Tabela

É provavelmente o algoritmo mais antigo do mundo corporativo.

A ideia é simples.

Utilizamos dois ponteiros.

Um na esquerda.

Outro na direita.

Ou ambos andando em velocidades diferentes.


Exemplo

Verificar se uma tabela é simétrica.

01 TAB.

   05 ITEM OCCURS 100 TIMES
      INDEXED BY IDX1 IDX2.

77 MAX PIC 999 VALUE 100.



SET IDX1 TO 1
SET IDX2 TO MAX



PERFORM UNTIL IDX1 >= IDX2


   IF ITEM(IDX1) NOT = ITEM(IDX2)

      DISPLAY 'NAO SIMETRICO'

   END-IF


   SET IDX1 UP BY 1
   SET IDX2 DOWN BY 1


END-PERFORM

Onde aparece?

Remover duplicidade

Palíndromo

Conciliação bancária

Arquivos ordenados

Merge VSAM

Join Batch


Complexidade

O(n)


Padrão 2 — Sliding Window

A Janela Deslizante

Esse algoritmo parece sofisticado.

Mas todo programador financeiro já utilizou.


Exemplo

Últimos 30 dias.

Tabela

10
20
15
40
50

Janela

3


Primeira

10 20 15

Soma

45


Move.

20 15 40

75


Move.

15 40 50

105


COBOL


ADD ENTRADA(I)
TO SOMA


SUBTRACT ENTRADA(I-3)

FROM SOMA

Muito usado em:

Detecção fraude

PIX

Cartão crédito

Médias móveis

SMF


Complexidade

O(n)


Padrão 3 — Prefix Sum

O Acumulador Supremo

Padawan.

Você provavelmente já usou.

Só não sabia o nome.


Exemplo.

Tabela.

5 3 2 4 1

Prefix.

5

8

10

14

15

Consultar.

Posição.

2 até 5.

15 - 5

10


COBOL

ADD VALOR(I)

TO ACUM(I-1)

GIVING ACUM(I)

Utilização.

Analytics

DW

RMF

SMF

Cobrança


Padrão 4 — Kadane

O Santo Graal das Séries

Maior sequência positiva.


Exemplo.

-2
1
-3
4
-1
2
1

Resultado.

6


COBOL

IF SOMA < ZERO

MOVE ZERO TO SOMA

END-IF

Aplicações.

Lucro máximo

Oscilações

Bolsa

PIX

Cartões


Complexidade.

O(n)


Padrão 5 — Merge Intervals

Fundindo Períodos

Muito usado.

Principalmente bancos.


Exemplo.

Cliente bloqueado.

01-05

03-10

12-20

Resultado.

01-10

12-20


COBOL

Comparar.

Datas.

Mesclar.


Usado.

Seguros

RH

Férias

Janelas batch


Padrão 6 — Cyclic Sort

A Ordem Cósmica

Pouco conhecido.

Mas genial.


Exemplo.

3 1 2

Cada número.

Vai para posição.

Correta.


Resultado.

1 2 3

Muito útil.

Detectar.

Ausentes.

Duplicados.


Padrão 7 — Hashing

O Cache Jedi


Python

Dict


Java

HashMap


COBOL

Tabela OCCURS


Exemplo.

Estados.

SP


RJ


MG

Pesquisar.

Instantaneamente.


Alternativa.

SEARCH ALL


Exemplo.

Tabela IR.

Códigos.

CEP.

Produtos.


Padrão 8 — Binary Search

SEARCH ALL

A arma secreta do COBOL.


Tabela ordenada.

SEARCH ALL CLIENTE

Complexidade.

O(log n)


1000000 registros.

Comparações.

20


Magia matemática.


Muito superior.

SEARCH.


SEARCH.

500 mil leituras.


SEARCH ALL.


Padrão 9 — Monotonic Stack

O Mestre Esquecido


Pouco usado.

Mas poderoso.


Encontrar.

Próximo maior.

Próximo menor.


Exemplo.

Temperaturas.

30

31

28

35

Pergunta.

Quando esquenta?


Em COBOL.

Pode ser implementado.

Com tabela OCCURS.


Muito usado.

Forecast.

Analytics.

IA.


Padrão 10 — Two Heaps

O Conselho Jedi

Min Heap.

Max Heap.


Encontrar.

Top 10.

Maior.

Menor.

Mediana.


Em COBOL.

Mais raro.

Mas possível.


Exemplo.

Ranking clientes.


SEARCH versus SEARCH ALL

Padawan.

Essa é importante.


SEARCH

Linear.

O(n)

SEARCH ALL

O(log n)

1000000 registros.

SEARCH.

500000 leituras.

SEARCH ALL.


INDEX versus Subscript

Subscript.

CLIENTE(I)

Índice.

INDEXED BY IDX

Mais rápido.


Menos cálculos.


Melhor cache.


SSRANGE

O Guardião das Tabelas

Sempre.

DEV.

TESTE.

QA.


Nunca acessar.

CLIENTE(1001)

Se existem.


SSRANGE salva vidas.


Quando usar DB2

Tabela enorme.

Não use OCCURS.


Quando usar OCCURS

Lookup.

UF.

IR.

CEP.

Parâmetros.

Cache.


Arquitetura Moderna

Hoje.

Programadores resolvem LeetCode.


Veteranos Mainframe.

Já faziam isso.

Em 1982.


Usando.

COBOL

VSAM

JCL

DFSORT

ICETOOL

DB2


Curiosidade Histórica

Década de 70.

IBM chamava isso.

Table Processing


Década de 80.

Performance Tuning.


Década de 90.

Binary Search.

Virou padrão.

Grandes bancos.


Década de 2000.

Java descobriu.

Collections.


Década de 2020.

LeetCode descobriu.


Década de 2030.

IA vai descobrir.

Que um programador COBOL aposentado em Campinas ou Itatiba já utilizava Prefix Sum desde 1989.


Easter Egg Bellacosa

Existe uma antiga profecia dos Sysprogs.

Ela diz:

"Chegará um dia em que um desenvolvedor júnior perguntará ao arquiteto qual algoritmo usar."

O arquiteto responderá:

Use Sliding Window.

O desenvolvedor pesquisará durante três horas.

Assistirá quatro vídeos.

Lerá cinco artigos.

Abrirá o ChatGPT.

Fará benchmarking.

Criará um POC.

E finalmente implementará.

Enquanto isso, um programador COBOL veterano sentado ao lado apenas dirá:

Ah...

Você queria uma média móvel.

Faço isso desde 1993.

Está no PROGFINC.

Linha 287.

Não mexe.

Funciona.

E agora pega um café.

Porque no Reino do Mainframe, muitas vezes os algoritmos mais modernos apenas receberam nomes mais bonitos para técnicas que os Cavaleiros COBOL já dominavam há décadas.