Upload
laura-higgins
View
212
Download
0
Embed Size (px)
Citation preview
Abstract Data Type (ADT) – visit 3/4
1. 'is_mem_av()' Semantics• Definitions: none, strong and weak semantics
• ULz data type and sketch of data structure, for z in {n, s, w}
• ULs and ULw pseudo codes and implementations
• UBz data type and sketch of data structure, for z in {n, s, w}
1. Fixed vs Mutable Array Size• Declaration
• Usage
• STACK_Impl_BAs
System-oriented Programming, B. Hirsbrunner, diuf.unifr.ch/pai/sp, Lecture 11 – 5 May 2015Lecture: ADT (visit 3/4): 45' + Tutorials: Regular Expressions (45'); Exercises: 90’
1. 'is_mem_av()' Semantics: none, strong, weak
2
The aim of the function is_mem_av() is to test if enough physical memory is available to add a new element
Typical usage
if (!is_full(obj) && is_mem_av(obj)) then put(obj,&e)
Proposed Semantics
1. none (n): is_mem_av returns always true
2. strong (s): put never fails if is_mem_av returns true
3. weak (w): put may fail if is_mem_av returns true, but
never crash the system
Implementation hints
2.An empty buffer is always available, managed by put and get3.Similar to (2), but only with a boolean variable
(A variant could be that is_mem_av does a malloc/free,but then the system may crash !)
1. 'is_mem_av()' Semantics: data type + sketch of data structure
3
typedef struct stack_descr_t { // none semantics p_node_t *top; // points to the top node, i.e. last in element long size; // number of elements in the STACK} stack_descr_t;
/---|*| <---|*| <---|*| pred | top
ULz implementations: none, strong and weak semantics
typedef struct stack_descr_t { // strong semantics ... same as none semantics boolean_t mem_av; // false if no more node can be added to the STACK p_node_t *buf; // buffer for a new node} stack_descr_t; /---|*| <---|*| <---|*| /---| | pred | | top buf
typedef struct stack_descr_t { // weak semantics ... same as none semantics boolean_t mem_av; // false if no more node can be added to the STACK} stack_descr_t; data structure sketch: same as for none semantics
1. 'is_mem_av()' Semantics: ULs and ULw impl.
4
void stack_put(stackt _s, elt_t *e) // ULs pseudo code{ //1--- verify precondition: exit if mem_av is FALSE
//2--- copy *e and update descriptor ... //3--- possibly reserve a free place ... set mem_av to FALSE if not succeeded}
ULs pseudo code
ULw pseudo code void stack_put(stackt _s, elt_t *e) // Ulw pseudo code{ //1--- verify precondition: exit if mem_av is FALSE
//3--- possibly find a free place ... set mem_av to FALSE if not succeeded //2--- copy *e and update descriptor ...}
see next two slides for complete implementations
1. 'is_mem_av()' Semantics: ULs implementation
5
void stack_put(stackt _s, elt_t *e)//---------------------------------{ stack_descr_t *s = _s;
//--- verify precondition if (!s->mem_av) exit(EXIT_FAILURE); // out of memory
//--- copy *e and update descriptor s->buf->e = *e; s->buf->pred = s->top; s->top = s->buf; ++s->size; //--- possibly reserve a free place s->buf = malloc(sizeof *s->buf); // memory allocation: STACK buffer // (is deallocated by stack_destroy or stack_get) if (s->buf == NULL) //--- ERROR TREATMENT { s->mem_av = FALSE; // used by 'put' and 'is_mem_av' //--- error treatment will be made by a coming 'put' call }}
1. 'is_mem_av()' Semantics: ULw implementation
6
void stack_put(stackt _s, elt_t *e)//---------------------------------{ stack_descr_t *s = _s;
//--- verify precondition if (!s->mem_av) exit(EXIT_FAILURE); // out of memory
//--- possibly find a free place p_node_t *buf = malloc(sizeof *buf); // memory allocation: next node // (is deallocated by stack_destroy or stack_get)
if (buf == NULL) { s->mem_av = FALSE; return; } // used by 'put' and 'is_mem_av'
//--- copy *e and update descriptor buf->e = *e; buf->pred = s->top; s->top = buf; ++s->size; }
1. 'is_mem_av()' Semantics: data type + sketch of data structure
7
typedef struct stack_descr_t { // none semantics elt_t *base; // points to the base elt of the STACK array instance long top; // pseudo pointer referring to the next free entry long size; // 0 <= size <= capacity long capacity; // current capacity of the STACK instance, >= 0 long init_cap; // initial capacity, >= 0 long incr; // increment, > 1} stack_descr_t; ----------------------------- | * | * | * | * | | | | ----------------------------- | top base
UAz implementations: none, strong and weak semantics
typedef struct stack_descr_t { // strong semantics ... same as none semantics boolean_t mem_av; // false if no more node can be added to the STACK} stack_descr_t; <------ capacity ------><---> <---- size ----> buffer ----------------------------- | * | * | * | * | | | | ----------------------------- | top base
weak semantics: same DT as for strong, and same DS as for none semantics
2. Fixed vs Mutable Array Size: declaration
8
STACK_Light / MTE / type_m.h, lines 14, 24, 29-36:
#define MTE_MAX_STR_LEN (1024 - sizeof(long) - 1) // maximum string length
typedef char data_t[MTE_MAX_STR_LEN + 1];
#define __fixed_data_length__ 0 //---YYY#define __mutable_data_length__ 1 //---YYY
typedef struct elt_t { // 1K = 2**10 bytes for static string length long key;// data_t data; // fixed string length //---YYY char *data; // mutable string length //---YYY} elt_t;
The lines postfixed by //---YYY are the ones which differ from type_f.h
2. Fixed vs Mutable String Length: usage
9
#if __fixed_data_length__ //--- defined in "../MTE/type_f.h" and "../MTE/type_m.h" elt_t elt = {1, "Hello"};#elif __mutable_data_length__ elt_t elt = {1, malloc(MTE_MAX_STR_LEN + 1)}; strcpy(elt.data, "Hello");#endif
if (scanf("%li%s", &elt.key, elt.data) != 2) goto error_scanf; //--- ERROR TREATMENT stack_put(s, &elt);
printf("%li %s\n", elt.key, elt.data);
In both cases, the usage is exactly the same, e.g. in the program STACK_Test_core.c, lines 129-133:
but in the mutable case one must explicitly allocate the memory via a malloc, e.g. in the same program, lines 68-73:
and has to free the allocated memory, e.g. in the same program, lines 278-280: #if __mutable_data_length__
free(elt.data);#endif
2. Fixed vs Mutable String Length: STACK_Impl_BAs
10
In the mutable case, the implementations of the STACK's subroutines are considerably more complicated.
Compare for {ADT, ADT_m} / STACK_Impl_BAs:
• the data structures and their sketches• create• put
Remember: the usage is the same !!!
And do the same for ULs