aboutsummaryrefslogtreecommitdiff
path: root/src/datastore/gnunet-service-datastore.c
diff options
context:
space:
mode:
authorDavid Barksdale <amatus@amat.us>2017-04-16 12:39:43 -0500
committerDavid Barksdale <amatus@amat.us>2017-04-16 12:42:34 -0500
commit4907330f51ffd48af1f7bac6f43c7c7f78c37818 (patch)
treea2cd65dbb24ea5caeda1fff2521f935dd7ea6256 /src/datastore/gnunet-service-datastore.c
parentcacd64d8635201459e59bf2cd8a2ea8fd0699b84 (diff)
downloadgnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.tar.gz
gnunet-4907330f51ffd48af1f7bac6f43c7c7f78c37818.zip
[datastore] Combine put and update plugin APIs
This resolves issue #4965.
Diffstat (limited to 'src/datastore/gnunet-service-datastore.c')
-rw-r--r--src/datastore/gnunet-service-datastore.c194
1 files changed, 22 insertions, 172 deletions
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c
index 277530843..d965ad8e0 100644
--- a/src/datastore/gnunet-service-datastore.c
+++ b/src/datastore/gnunet-service-datastore.c
@@ -733,41 +733,23 @@ check_data (const struct DataMessage *dm)
733 733
734 734
735/** 735/**
736 * Context for a PUT request used to see if the content is
737 * already present.
738 */
739struct PutContext
740{
741 /**
742 * Client to notify on completion.
743 */
744 struct GNUNET_SERVICE_Client *client;
745
746#if ! HAVE_UNALIGNED_64_ACCESS
747 void *reserved;
748#endif
749
750 /* followed by the 'struct DataMessage' */
751};
752
753
754/**
755 * Put continuation. 736 * Put continuation.
756 * 737 *
757 * @param cls closure 738 * @param cls closure
758 * @param key key for the item stored 739 * @param key key for the item stored
759 * @param size size of the item stored 740 * @param size size of the item stored
760 * @param status #GNUNET_OK or #GNUNET_SYSERROR 741 * @param status #GNUNET_OK if inserted, #GNUNET_NO if updated,
742 * or #GNUNET_SYSERROR if error
761 * @param msg error message on error 743 * @param msg error message on error
762 */ 744 */
763static void 745static void
764put_continuation (void *cls, 746put_continuation (void *cls,
765 const struct GNUNET_HashCode *key, 747 const struct GNUNET_HashCode *key,
766 uint32_t size, 748 uint32_t size,
767 int status, 749 int status,
768 const char *msg) 750 const char *msg)
769{ 751{
770 struct PutContext *pc = cls; 752 struct GNUNET_SERVICE_Client *client = cls;
771 753
772 if (GNUNET_OK == status) 754 if (GNUNET_OK == status)
773 { 755 {
@@ -782,10 +764,9 @@ put_continuation (void *cls,
782 size, 764 size,
783 GNUNET_h2s (key)); 765 GNUNET_h2s (key));
784 } 766 }
785 transmit_status (pc->client, 767 transmit_status (client,
786 status, 768 GNUNET_SYSERR == status ? GNUNET_SYSERR : GNUNET_OK,
787 msg); 769 msg);
788 GNUNET_free (pc);
789 if (quota - reserved - cache_size < payload) 770 if (quota - reserved - cache_size < payload)
790 { 771 {
791 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 772 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -799,125 +780,6 @@ put_continuation (void *cls,
799 780
800 781
801/** 782/**
802 * Actually put the data message.
803 *
804 * @param pc put context
805 */
806static void
807execute_put (struct PutContext *pc)
808{
809 const struct DataMessage *dm;
810
811 dm = (const struct DataMessage *) &pc[1];
812 plugin->api->put (plugin->api->cls,
813 &dm->key,
814 ntohl (dm->size),
815 &dm[1],
816 ntohl (dm->type),
817 ntohl (dm->priority),
818 ntohl (dm->anonymity),
819 ntohl (dm->replication),
820 GNUNET_TIME_absolute_ntoh (dm->expiration),
821 &put_continuation,
822 pc);
823}
824
825
826/**
827 *
828 * @param cls closure
829 * @param status #GNUNET_OK or #GNUNET_SYSERR
830 * @param msg error message on error
831 */
832static void
833check_present_continuation (void *cls,
834 int status,
835 const char *msg)
836{
837 struct GNUNET_SERVICE_Client *client = cls;
838
839 transmit_status (client,
840 GNUNET_NO,
841 NULL);
842}
843
844
845/**
846 * Function that will check if the given datastore entry
847 * matches the put and if none match executes the put.
848 *
849 * @param cls closure, pointer to the client (of type `struct PutContext`).
850 * @param key key for the content
851 * @param size number of bytes in data
852 * @param data content stored
853 * @param type type of the content
854 * @param priority priority of the content
855 * @param anonymity anonymity-level for the content
856 * @param replication replication-level for the content
857 * @param expiration expiration time for the content
858 * @param uid unique identifier for the datum;
859 * maybe 0 if no unique identifier is available
860 * @return #GNUNET_OK usually
861 * #GNUNET_NO to delete the item
862 */
863static int
864check_present (void *cls,
865 const struct GNUNET_HashCode *key,
866 uint32_t size,
867 const void *data,
868 enum GNUNET_BLOCK_Type type,
869 uint32_t priority,
870 uint32_t anonymity,
871 uint32_t replication,
872 struct GNUNET_TIME_Absolute expiration,
873 uint64_t uid)
874{
875 struct PutContext *pc = cls;
876 const struct DataMessage *dm;
877
878 dm = (const struct DataMessage *) &pc[1];
879 if (key == NULL)
880 {
881 execute_put (pc);
882 return GNUNET_OK;
883 }
884 if ( (GNUNET_BLOCK_TYPE_FS_DBLOCK == type) ||
885 (GNUNET_BLOCK_TYPE_FS_IBLOCK == type) ||
886 ( (size == ntohl (dm->size)) &&
887 (0 == memcmp (&dm[1],
888 data,
889 size)) ) )
890 {
891 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
892 "Result already present in datastore\n");
893 if ( (ntohl (dm->priority) > 0) ||
894 (ntohl (dm->replication) > 0) ||
895 (GNUNET_TIME_absolute_ntoh (dm->expiration).abs_value_us >
896 expiration.abs_value_us) )
897 plugin->api->update (plugin->api->cls,
898 uid,
899 ntohl (dm->priority),
900 ntohl (dm->replication),
901 GNUNET_TIME_absolute_ntoh (dm->expiration),
902 &check_present_continuation,
903 pc->client);
904 else
905 {
906 transmit_status (pc->client,
907 GNUNET_NO,
908 NULL);
909 }
910 GNUNET_free (pc);
911 }
912 else
913 {
914 execute_put (pc);
915 }
916 return GNUNET_OK;
917}
918
919
920/**
921 * Verify PUT-message. 783 * Verify PUT-message.
922 * 784 *
923 * @param cls identification of the client 785 * @param cls identification of the client
@@ -950,8 +812,6 @@ handle_put (void *cls,
950 struct GNUNET_SERVICE_Client *client = cls; 812 struct GNUNET_SERVICE_Client *client = cls;
951 int rid; 813 int rid;
952 struct ReservationList *pos; 814 struct ReservationList *pos;
953 struct PutContext *pc;
954 struct GNUNET_HashCode vhash;
955 uint32_t size; 815 uint32_t size;
956 816
957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 817 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -979,30 +839,20 @@ handle_put (void *cls,
979 GNUNET_NO); 839 GNUNET_NO);
980 } 840 }
981 } 841 }
982 pc = GNUNET_malloc (sizeof (struct PutContext) + size + 842 bool absent = GNUNET_NO == GNUNET_CONTAINER_bloomfilter_test (filter,
983 sizeof (struct DataMessage)); 843 &dm->key);
984 pc->client = client; 844 plugin->api->put (plugin->api->cls,
985 GNUNET_memcpy (&pc[1], 845 &dm->key,
986 dm, 846 absent,
987 size + sizeof (struct DataMessage)); 847 ntohl (dm->size),
988 if (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (filter, 848 &dm[1],
989 &dm->key)) 849 ntohl (dm->type),
990 { 850 ntohl (dm->priority),
991 GNUNET_CRYPTO_hash (&dm[1], 851 ntohl (dm->anonymity),
992 size, 852 ntohl (dm->replication),
993 &vhash); 853 GNUNET_TIME_absolute_ntoh (dm->expiration),
994 plugin->api->get_key (plugin->api->cls, 854 &put_continuation,
995 0, 855 client);
996 false,
997 &dm->key,
998 &vhash,
999 ntohl (dm->type),
1000 &check_present,
1001 pc);
1002 GNUNET_SERVICE_client_continue (client);
1003 return;
1004 }
1005 execute_put (pc);
1006 GNUNET_SERVICE_client_continue (client); 856 GNUNET_SERVICE_client_continue (client);
1007} 857}
1008 858