CRUD multiusuario: ¿válido, problema o error?

13

Introducción :

¿Alguna vez usó Dropbox con otras personas y ambos modificaron el mismo archivo? ¿Alguna vez tuvo una aplicación multiusuario con una base de datos relacional, y dos personas estaban modificando (o peor, una estaba eliminando y la otra modificando) el mismo objeto? Bueno, simulemos eso con este desafío (más o menos).

En aras de este desafío, solo tenemos dos usuarios y uno o dos archivos relevantes. Ambos usuarios tienen en general privilegios para CRUD (Crear, Leer, Actualizar y Eliminar) todos los archivos.

Desafío:

Entrada:

Tendremos algunas entradas (el formato de entrada es flexible y se permite cualquier formato razonable):

1) Modo de bloqueo (activar / desactivar) : un poco la diferencia entre el bloqueo de concurrencia optimista y pesimista .
Ambos usuarios pueden CRUD (Crear, Leer, Actualizar y Eliminar) todo, pero a veces pueden ocurrir errores o problemas. Dependiendo del modo de bloqueo, un problema cuando se apaga puede ser un error cuando se enciende. Esto se explica a continuación en la sección Salida .

2 y 3) Dos acciones del usuario . Estas acciones siempre consisten en dos cosas: qué hace el usuario (Crear, Leer, Actualizar o Eliminar) y para qué archivo.

Salida:

Tendremos tres salidas posibles:

  1. Válido : Ambas acciones de ambos usuarios pueden realizarse simultáneamente sin que ocurra ningún problema.
  2. Error : Ambas acciones de ambos usuarios no pueden realizarse simultáneamente y causa un error para uno de los usuarios (qué usuario es irrelevante para este desafío). Esto puede ocurrir cuando:
    • un usuario lee o actualiza un archivo, que el otro usuario elimina;
    • ambos usuarios actualizan el mismo archivo con el modo de bloqueo activado;
    • un usuario crea un archivo, que el otro usuario lee / actualiza / elimina (esto significa que el archivo ya existe, por lo que no se puede crear);
    • ambos usuarios crean el mismo archivo.
  3. Problema : Ambas acciones de ambos usuarios pueden realizarse simultáneamente, pero pueden causar problemas inesperados. Esto puede ocurrir cuando:
    • ambos usuarios actualizan un archivo cuando el modo de bloqueo está desactivado;
    • un usuario actualiza un archivo, que el otro usuario lee;
    • ambos usuarios eliminan el mismo archivo (prácticamente esto causará un error para el segundo usuario, pero dado que aún se eliminará como el usuario lo desea, será un problema en lugar de un error en aras de este desafío)

Reglas del desafío:

  • ¡Todas las entradas y salidas son flexibles, y todos deberían indicar cuál usaron en su respuesta!
    Entradas de ejemplo: 0/ 1para el modo de bloqueo & 31(tercera acción: Actualizar; archivo: 1) & 21(segunda acción: Leer; archivo: 1); true/ falsepara el modo de bloqueo & ['C','A'](acción: Crear; archivo: A) & ['D','B'](acción: Eliminar; archivo: B); etc.
    Resultados de ejemplo: null/ true/ false(nulo = válido; verdadero = error; falso = problema); -1/ 0/ 1(-1 = error; 0 = problema; 1 = válido); Sin embargo, las tres salidas posibles deben ser únicas y distintas para los tres tipos de salida.
  • Lo que se llama a los archivos es irrelevante, lo que también se puede ver con los ejemplos de entrada anteriores. Así que siéntase libre de usar cualquier tipo de nombre de archivo en sus respuestas que consista en una sola letra (ASCII) o dígito. Sin embargo, tienen que ser consistentes en todos sus casos de prueba, por lo que no puede usar A/ Ben un caso de prueba y 1/ 2en otro.
  • Las cuatro acciones para CRUD también deben ser valores únicos y consistentes. Por lo tanto, no puede usar 'D'/ 'C'en un caso de prueba, y luego 4/ 1en otro caso de prueba.
  • Puede suponer que el archivo elegido por un usuario siempre existe cuando desea leerlo, actualizarlo o eliminarlo.

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana.
    No permita que los lenguajes de code-golf lo desanimen a publicar respuestas con lenguajes que no sean codegolf. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Las reglas estándar se aplican a su respuesta con las reglas de E / S predeterminadas , por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados y programas completos de tipo retorno. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código (es decir, TIO ).
  • Además, se recomienda agregar una explicación para su respuesta.

Todos los casos de prueba posibles (donde las acciones pueden estar en el orden de entrada ):

: debe admitir todas las variaciones (hasta cuatro) de los casos de prueba a continuación. Entonces, si un caso de prueba indica action1: Create file A; action2: Update file B, ese caso de prueba también debería tener los mismos resultados para action1: Create file B; action2: Update file A; action1: Update file B; action2: Create file A; y action1: Update file A; action2: Create file B.

Valid use-cases:

locking mode: either;  action1: Create file A;  action2: Create file B
locking mode: either;  action1: Create file A;  action2: Read file B
locking mode: either;  action1: Create file A;  action2: Update file B
locking mode: either;  action1: Create file A;  action2: Delete file B
locking mode: either;  action1: Read file A;    action2: Read file A
locking mode: either;  action1: Read file A;    action2: Read file B
locking mode: either;  action1: Read file A;    action2: Update file B
locking mode: either;  action1: Read file A;    action2: Delete file B
locking mode: either;  action1: Update file A;  action2: Update file B
locking mode: either;  action1: Update file A;  action2: Delete file B
locking mode: either;  action1: Delete file A;  action2: Delete file B

Error use-cases:

locking mode: either;  action1: Create file A;  action2: Create file A
locking mode: either;  action1: Create file A;  action2: Read file A
locking mode: either;  action1: Create file A;  action2: Update file A
locking mode: either;  action1: Create file A;  action2: Delete file A
locking mode: either;  action1: Read file A;    action2: Delete file A
locking mode: on;      action1: Update file A;  action2: Update file A
locking mode: either;  action1: Update file A;  action2: Delete file A

Problem use-cases:

locking mode: either;  action1: Read file A;    action2: Update file A
locking mode: off;     action1: Update file A;  action2: Update file A
locking mode: either;  action1: Delete file A;  action2: Delete file A
Kevin Cruijssen
fuente
2
Siento que habrá una solución de 1 byte si puedo encontrar los métodos correctos de entrada / salida (quizás algún tipo de enmascaramiento de bits)
Datos
2
@ExpiredData Alteraron algunas partes de los posibles resultados, que deben ser consistentes, pero no necesariamente únicos. Y también que las entradas tienen que ser consistentes.
Kevin Cruijssen
1
@Arnauld Ah, excluí todos los B/Bcasos en mi recuento , ya que los consideré similares a A/A. De ahí viene la diferencia. Pero supongo que pensar es incorrecto si tienes un valor específico para los archivos ...
Kevin Cruijssen

Respuestas:

8

JavaScript (ES6), 36 bytes

Sin una tabla de búsqueda

(m,a,f,A,F)=>f-F?2:a^A?a*A&8:a&4?m:a

Pruébalo en línea!

I / O

  • Modo de bloqueo ( ): = Encendido, = Apagadom08
  • Acciones ( y ): = Crear, = Leer, = Actualizar, = BorraraA0248
  • Archivos ( y ): cualquier enterofF
  • Salida: = Error, = Válido, = Problema028

¿Cómo?

Si los archivos son diferentes, todas las operaciones son seguras y solo devolvemos (válido).2

Si los archivos son idénticos, debemos devolver:

  • 2 (válido) si tenemos dos operaciones de lectura
  • 8 (problema) si tenemos dos operaciones de eliminación , o una actualización y una lectura
  • m (problema o error) si tenemos dos operaciones de actualización
  • 0 (error) para todo lo demás

Usando una matriz CRUD (que es simétrica por definición), podemos ver que los valores anteriores se pueden calcular con:4×4

a ^ AaA? ? a * A & 8 : a & 4update? ? m:a

CRUD0248C00000R20280U408m0D80008


JavaScript (ES6),  46 45  40 bytes

Con una tabla de búsqueda

(m,a,f,A,F)=>f-F?0:[m,1,1,0][a*2+A*9&23]

Pruébalo en línea!

I / O

  • Modo de bloqueo: indefinido = Encendido, = Apagado1
  • Acciones: = Actualizar, = Leer, = Crear, = Eliminar0123
  • Archivos: cualquier número entero
  • Salida: indefinido = Error, = Válido, = Problema01
Arnauld
fuente
4

Retina 0.8.2 , 53 bytes

^(.)(?!\1).+|..RR.
V
..DD.
P
..UUL
E
.+[CD].+
E
..+
P

Pruébalo en línea! El enlace incluye un conjunto de pruebas. Toma la entrada como una cadena de 5 caracteres, dos caracteres que representan los nombres de los archivos, luego dos caracteres de CRUD, luego Lo U(bloqueado / desbloqueado), y genera uno de VPE(válido / problema / error). Explicación:

^(.)(?!\1).+|..RR.
V

Los nombres de archivo diferentes siempre son válidos, al igual que dos lecturas. Molesto, esta es la única prueba que me obliga a usar un encabezado. (Cuestaría un byte adicional hacer innecesario el encabezado).

..DD.
P

Dos eliminaciones son siempre un problema.

..UUL
E

Dos actualizaciones bloqueadas son un error.

.+[CD].+
E

Cualquier otra creación o eliminación es un error.

..+
P

Todo lo demás es un problema.

Neil
fuente
3

Octava , 96 bytes

@(a,b,c)[a(1)!=b(1)|a(2)+b(2)==20,mod((m=a+b+c)(2),10010)<1|mod(m(2),1020000)<1|mod(m(2),200)<1]

Pruébalo en línea!

Definitivamente puede ser más corto, pero ahora no tengo tiempo para hacerlo

File 1 = 0
File 2 = 1
Read = 10
Delete = 100
Create = 1000 
Update = 10000
Lock on = 100000
Lock off = 1000000

Valid Values: 
[1 0] 

Problem Values: 
[0 1]


Invalid Values: 
[0 0]

Ingrese como a = [archivo, acción], b = [archivo2, acción2], c = bloqueo

Datos caducados
fuente