get.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <stdio.h>
  2. #include <grass/rowio.h>
  3. static void *my_select ( ROWIO *,int);
  4. static void pageout ( ROWIO *,int);
  5. /*!
  6. * \brief read a row
  7. *
  8. * Rowio_get() returns a
  9. * buffer which holds the data for row <b>n</b> from the file associated with
  10. * ROWIO structure <b>r.</b> If the row requested is not in memory, the
  11. * <b>getrow()</b> routine specified in <i>rowio_setup</i> is called to
  12. * read row <b>n</b> into memory and a pointer to the memory buffer containing
  13. * the row is returned. If the data currently in the buffer had been changed by
  14. * <i>rowio_put</i>, the <b>putrow()</b> routine specified in
  15. * <i>rowio_setup</i> is called first to write the changed row to disk. If row
  16. * <b>n</b> is already in memory, no disk read is done. The pointer to the data
  17. * is simply returned.
  18. * Return codes:
  19. * NULL <b>n</b> is negative, or
  20. * <b>getrow()</b> returned 0 (indicating an error condition).
  21. * !NULL pointer to buffer containing row <b>n.</b>
  22. *
  23. * \param r
  24. * \param n
  25. * \return char *
  26. */
  27. void *rowio_get (ROWIO *R,int row)
  28. {
  29. int i;
  30. int age;
  31. int cur;
  32. if (row < 0)
  33. return NULL;
  34. if (row == R->cur)
  35. return R->buf;
  36. for (i = 0; i < R->nrows; i++)
  37. if (row == R->rcb[i].row)
  38. return my_select (R, i);
  39. age = 0;
  40. cur = 0;
  41. for (i = 0; i < R->nrows; i++)
  42. if (R->rcb[i].row < 0) /* free slot ! */
  43. {
  44. cur = i;
  45. break;
  46. }
  47. else if (age < R->rcb[i].age)
  48. {
  49. cur = i;
  50. age = R->rcb[i].age;
  51. }
  52. pageout (R, cur);
  53. i = (*R->getrow) (R->fd, R->rcb[cur].buf, R->rcb[cur].row = row, R->len);
  54. R->rcb[cur].dirty = 0;
  55. if (!i)
  56. {
  57. R->rcb[cur].row = -1;
  58. if (cur == R->cur)
  59. R->cur = -1;
  60. return NULL;
  61. }
  62. return my_select (R, cur);
  63. }
  64. void rowio_flush( ROWIO *R)
  65. {
  66. int i;
  67. for (i = 0; i < R->nrows; i++)
  68. pageout (R, i);
  69. }
  70. static void pageout ( ROWIO *R,int cur)
  71. {
  72. if (R->rcb[cur].row < 0)
  73. return;
  74. if (! R->rcb[cur].dirty)
  75. return;
  76. (*R->putrow) (R->fd, R->rcb[cur].buf, R->rcb[cur].row, R->len);
  77. R->rcb[cur].dirty = 0;
  78. }
  79. static void *my_select ( ROWIO *R,int n)
  80. {
  81. int i;
  82. R->rcb[n].age = 0;
  83. for (i = 0; i < R->nrows; i++)
  84. R->rcb[i].age++;
  85. R->cur = R->rcb[n].row;
  86. R->buf = R->rcb[n].buf;
  87. return R->buf;
  88. }